Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make fill tiles respect buffer size #1100

Merged
merged 2 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,24 @@ public static int countGeometries(VectorTileProto.Tile.Feature feature) {
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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
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;
Expand All @@ -39,14 +38,6 @@
*/
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;
Expand Down Expand Up @@ -282,13 +273,13 @@ private void writeTileFeatures(int zoom, long id, FeatureCollector.Feature featu
// 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
Expand All @@ -298,7 +289,7 @@ private int emitFilledTiles(long id, FeatureCollector.Feature feature, TiledGeom
VectorTile.Feature vectorTileFeature = new VectorTile.Feature(
feature.getLayer(),
id,
FILL,
VectorTile.encodeFill(feature.getBufferPixelsAtZoom(zoom)),
feature.getAttrsAtZoom(sliced.zoomLevel())
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,7 @@ void testPolygonWithHoleSpanningMultipleTiles(boolean anyGeom) throws Exception
), 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())
Expand Down Expand Up @@ -814,7 +814,7 @@ void testZ15Fill() throws Exception {
);

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)));
}

Expand All @@ -832,7 +832,7 @@ void testFullWorldPolygon() throws Exception {

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());
}
Expand Down Expand Up @@ -2449,7 +2449,7 @@ private PlanetilerResults runForCompactTest(boolean compactDbEnabled) throws Exc
),
(in, features) -> features.polygon("layer")
.setZoomRange(0, 2)
.setBufferPixels(0)
.setBufferPixels(1)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,18 @@ void firstCoordinateOfPolygon(double x, double y) {
}
}

@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(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,7 @@ void testFill() {
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)
Expand Down Expand Up @@ -1173,7 +1173,7 @@ void testNestedMultipolygonFill() {
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()));
}

Expand Down
Loading