kopia lustrzana https://github.com/onthegomap/planetiler
Make fill tiles respect buffer size (#1100)
rodzic
6d6cd37d1c
commit
e6f1c41006
|
|
@ -463,6 +463,24 @@ public class VectorTile {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encoded geometry for a polygon that fills an entire tile plus {@code buffer} pixels as a shortcut to
|
||||
* avoid needing to create an extra JTS geometry for encoding.
|
||||
*/
|
||||
public static VectorGeometry encodeFill(double buffer) {
|
||||
int min = (int) Math.round(EXTENT * buffer / 256d);
|
||||
int width = EXTENT + min + min;
|
||||
return new VectorGeometry(new int[]{
|
||||
CommandEncoder.commandAndLength(Command.MOVE_TO, 1),
|
||||
zigZagEncode(-min), zigZagEncode(-min),
|
||||
CommandEncoder.commandAndLength(Command.LINE_TO, 3),
|
||||
zigZagEncode(width), 0,
|
||||
0, zigZagEncode(width),
|
||||
zigZagEncode(-width), 0,
|
||||
CommandEncoder.commandAndLength(Command.CLOSE_PATH, 1)
|
||||
}, GeometryType.POLYGON, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds features in a layer to this tile.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import org.locationtech.jts.geom.MultiPolygon;
|
|||
import org.locationtech.jts.geom.Point;
|
||||
import org.locationtech.jts.geom.Polygon;
|
||||
import org.locationtech.jts.geom.Polygonal;
|
||||
import org.locationtech.jts.geom.impl.PackedCoordinateSequence;
|
||||
import org.locationtech.jts.geom.util.AffineTransformation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
@ -39,14 +38,6 @@ import org.slf4j.LoggerFactory;
|
|||
*/
|
||||
public class FeatureRenderer implements Consumer<FeatureCollector.Feature>, Closeable {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(FeatureRenderer.class);
|
||||
private static final VectorTile.VectorGeometry FILL = VectorTile.encodeGeometry(GeoUtils.JTS_FACTORY
|
||||
.createPolygon(GeoUtils.JTS_FACTORY.createLinearRing(new PackedCoordinateSequence.Double(new double[]{
|
||||
-5, -5,
|
||||
261, -5,
|
||||
261, 261,
|
||||
-5, 261,
|
||||
-5, -5
|
||||
}, 2, 0))));
|
||||
private final PlanetilerConfig config;
|
||||
private final Consumer<RenderedFeature> consumer;
|
||||
private final Stats stats;
|
||||
|
|
@ -282,13 +273,13 @@ public class FeatureRenderer implements Consumer<FeatureCollector.Feature>, Clos
|
|||
// polygons that span multiple tiles contain detail about the outer edges separate from the filled tiles, so emit
|
||||
// filled tiles now
|
||||
if (feature.isPolygon()) {
|
||||
emitted += emitFilledTiles(id, feature, sliced);
|
||||
emitted += emitFilledTiles(zoom, id, feature, sliced);
|
||||
}
|
||||
|
||||
stats.emittedFeatures(zoom, feature.getLayer(), emitted);
|
||||
}
|
||||
|
||||
private int emitFilledTiles(long id, FeatureCollector.Feature feature, TiledGeometry sliced) {
|
||||
private int emitFilledTiles(int zoom, long id, FeatureCollector.Feature feature, TiledGeometry sliced) {
|
||||
Optional<RenderedFeature.Group> groupInfo = Optional.empty();
|
||||
/*
|
||||
* Optimization: large input polygons that generate many filled interior tiles (i.e. the ocean), the encoder avoids
|
||||
|
|
@ -298,7 +289,7 @@ public class FeatureRenderer implements Consumer<FeatureCollector.Feature>, Clos
|
|||
VectorTile.Feature vectorTileFeature = new VectorTile.Feature(
|
||||
feature.getLayer(),
|
||||
id,
|
||||
FILL,
|
||||
VectorTile.encodeFill(feature.getBufferPixelsAtZoom(zoom)),
|
||||
feature.getAttrsAtZoom(sliced.zoomLevel())
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -770,7 +770,7 @@ class PlanetilerTests {
|
|||
), Map.of())
|
||||
)),
|
||||
newTileEntry(Z14_TILES / 2 + 2, Z14_TILES / 2 + 1, 14, List.of(
|
||||
feature(newPolygon(tileFill(5), List.of()), Map.of())
|
||||
feature(newPolygon(tileFill(4), List.of()), Map.of())
|
||||
)),
|
||||
newTileEntry(Z14_TILES / 2 + 3, Z14_TILES / 2 + 1, 14, List.of(
|
||||
feature(tileLeft(4), Map.of())
|
||||
|
|
@ -814,7 +814,7 @@ class PlanetilerTests {
|
|||
);
|
||||
|
||||
assertEquals(List.of(
|
||||
feature(newPolygon(tileFill(5)), Map.of())
|
||||
feature(newPolygon(tileFill(4)), Map.of())
|
||||
), results.tiles.get(TileCoord.ofXYZ(Z15_TILES / 2, Z15_TILES / 2, 15)));
|
||||
}
|
||||
|
||||
|
|
@ -832,7 +832,7 @@ class PlanetilerTests {
|
|||
|
||||
assertEquals(5461, results.tiles.size());
|
||||
// spot-check one filled tile
|
||||
assertEquals(List.of(rectangle(-5, 256 + 5).norm()), results.tiles.get(TileCoord.ofXYZ(
|
||||
assertEquals(List.of(rectangle(-4, 256 + 4).norm()), results.tiles.get(TileCoord.ofXYZ(
|
||||
Z4_TILES / 2, Z4_TILES / 2, 4
|
||||
)).stream().map(d -> d.geometry().geom().norm()).toList());
|
||||
}
|
||||
|
|
@ -2449,7 +2449,7 @@ class PlanetilerTests {
|
|||
),
|
||||
(in, features) -> features.polygon("layer")
|
||||
.setZoomRange(0, 2)
|
||||
.setBufferPixels(0)
|
||||
.setBufferPixels(1)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -692,6 +692,18 @@ class VectorTileTest {
|
|||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"0, 0, 256",
|
||||
"1, -1, 257",
|
||||
"10, -10, 266",
|
||||
})
|
||||
void testFill(double buffer, double min, double max) throws GeometryException {
|
||||
var geom = VectorTile.encodeFill(buffer);
|
||||
assertSameGeometry(rectangle(min, max), geom.decode());
|
||||
assertArrayEquals(VectorTile.encodeGeometry(rectangle(min, max)).commands(), geom.commands());
|
||||
}
|
||||
|
||||
private static void assertArrayEquals(int[] a, int[] b) {
|
||||
assertEquals(
|
||||
IntStream.of(a).boxed().toList(),
|
||||
|
|
|
|||
|
|
@ -814,7 +814,7 @@ class FeatureRendererTest {
|
|||
tileRight(1)
|
||||
),
|
||||
TileCoord.ofXYZ(Z14_TILES / 2, Z14_TILES / 2, 14), List.of(
|
||||
newPolygon(tileFill(5), List.of()) // <<<<---- the filled tile!
|
||||
newPolygon(tileFill(1), List.of()) // <<<<---- the filled tile!
|
||||
),
|
||||
TileCoord.ofXYZ(Z14_TILES / 2 + 1, Z14_TILES / 2, 14), List.of(
|
||||
tileLeft(1)
|
||||
|
|
@ -1173,7 +1173,7 @@ class FeatureRendererTest {
|
|||
var rendered = renderGeometry(feature);
|
||||
var innerTile = rendered.get(TileCoord.ofXYZ(Z14_TILES / 2, Z14_TILES / 2, 14));
|
||||
assertEquals(1, innerTile.size());
|
||||
assertEquals(new TestUtils.NormGeometry(rectangle(-5, 256 + 5)),
|
||||
assertEquals(new TestUtils.NormGeometry(rectangle(-1, 256 + 1)),
|
||||
new TestUtils.NormGeometry(innerTile.iterator().next()));
|
||||
}
|
||||
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue