Skip to content

Commit

Permalink
min source feature size for centroid/point on surface/centroid if convex
Browse files Browse the repository at this point in the history
  • Loading branch information
msbarry committed Nov 13, 2023
1 parent c4036f3 commit c0d6f32
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ private Feature(String layer, Geometry geom, long id) {
this.geom = geom;
this.geometryType = GeometryType.typeOf(geom);
this.id = id;
if (geometryType == GeometryType.POINT) {
minPixelSizeAtMaxZoom = 0;
defaultMinPixelSize = 0;
}
}

/** Returns the original ID of the source feature that this feature came from (i.e. OSM node/way ID). */
Expand Down Expand Up @@ -728,5 +732,15 @@ public String toString() {
", attrs=" + attrs +
'}';
}

/** Returns the actual pixel size of the source feature at {@code zoom} (length if line, sqrt(area) if polygon). */
public double getSourceFeaturePixelSizeAtZoom(int zoom) {
try {
return source.size() * (256 << zoom);
} catch (GeometryException e) {
e.log(stats, "point_get_size_failure", "Error getting min size for point from geometry " + source.id());
return 0;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public abstract class SourceFeature implements WithTags, WithGeometryType {
private Geometry validPolygon = null;
private double area = Double.NaN;
private double length = Double.NaN;
private double size = Double.NaN;

/**
* Constructs a new input feature.
Expand Down Expand Up @@ -245,6 +246,14 @@ public double length() throws GeometryException {
(isPoint() || canBePolygon() || canBeLine()) ? worldGeometry().getLength() : 0) : length;
}

/**
* Returns and caches sqrt of {@link #area()} if polygon or {@link #length()} if a line string.
*/
public double size() throws GeometryException {
return Double.isNaN(size) ? (size = canBePolygon() ? Math.sqrt(Math.abs(area())) : canBeLine() ? length() : 0) :
size;
}

/** Returns the ID of the source that this feature came from. */
public String getSource() {
return source;
Expand Down Expand Up @@ -292,4 +301,5 @@ public final long id() {
public boolean hasRelationInfo() {
return relationInfos != null && !relationInfos.isEmpty();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ private void renderPoint(FeatureCollector.Feature feature, Coordinate... origCoo
coords[i] = origCoords[i].copy();
}
for (int zoom = feature.getMaxZoom(); zoom >= feature.getMinZoom(); zoom--) {
double minSize = feature.getMinPixelSizeAtZoom(zoom);
if (minSize > 0 && feature.getSourceFeaturePixelSizeAtZoom(zoom) < minSize) {
continue;
}
Map<String, Object> attrs = feature.getAttrsAtZoom(zoom);
double buffer = feature.getBufferPixelsAtZoom(zoom) / 256;
int tilesAtZoom = 1 << zoom;
Expand Down Expand Up @@ -207,7 +211,7 @@ private void renderLineOrPolygon(FeatureCollector.Feature feature, Geometry inpu
}
Map<String, Object> attrs = feature.getAttrsAtZoom(sliced.zoomLevel());
if (numPointsAttr != null) {
// if profile wants the original number of points that the simplified but untiled geometry started with
// if profile wants the original number off points that the simplified but untiled geometry started with
attrs = new HashMap<>(attrs);
attrs.put(numPointsAttr, geom.getNumPoints());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -614,5 +614,4 @@ void testManyAttr() {
)
), collector);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,15 @@ public List<Coordinate> z14CoordinateList(double... coords) {
return points;
}

public List<Coordinate> z14PixelRectangle(double min, double max) {
List<Coordinate> points = rectangleCoordList(min / 256d, max / 256d);
points.forEach(c -> {
c.x = GeoUtils.getWorldLon(0.5 + c.x * Z14_WIDTH);
c.y = GeoUtils.getWorldLat(0.5 + c.y * Z14_WIDTH);
});
return points;
}

public List<Coordinate> z14CoordinatePixelList(double... coords) {
return z14CoordinateList(DoubleStream.of(coords).map(c -> c / 256d).toArray());
}
Expand Down Expand Up @@ -2341,6 +2350,90 @@ void testBoundFilters() throws Exception {
assertEquals(bboxResult.tiles, polyResult.tiles);
}

@Test
void testSimplePolygon() throws Exception {
List<Coordinate> points = z14PixelRectangle(0, 40);

var results = runWithReaderFeatures(
Map.of("threads", "1"),
List.of(
newReaderFeature(newPolygon(points), Map.of())
),
(in, features) -> features.polygon("layer")
.setZoomRange(0, 14)
.setBufferPixels(0)
.setMinPixelSize(10) // should only show up z14 (40) z13 (20) and z12 (10)
);

assertEquals(Map.ofEntries(
newTileEntry(Z12_TILES / 2, Z12_TILES / 2, 12, List.of(
feature(newPolygon(rectangleCoordList(0, 10)), Map.of())
)),
newTileEntry(Z13_TILES / 2, Z13_TILES / 2, 13, List.of(
feature(newPolygon(rectangleCoordList(0, 20)), Map.of())
)),
newTileEntry(Z14_TILES / 2, Z14_TILES / 2, 14, List.of(
feature(newPolygon(rectangleCoordList(0, 40)), Map.of())
))
), results.tiles);
}

@Test
void testCentroidWithPolygonMinSize() throws Exception {
List<Coordinate> points = z14PixelRectangle(0, 40);

var results = runWithReaderFeatures(
Map.of("threads", "1"),
List.of(
newReaderFeature(newPolygon(points), Map.of())
),
(in, features) -> features.centroid("layer")
.setZoomRange(0, 14)
.setBufferPixels(0)
.setMinPixelSize(10) // should only show up z14 (40) z13 (20) and z12 (10)
);

assertEquals(Map.ofEntries(
newTileEntry(Z12_TILES / 2, Z12_TILES / 2, 12, List.of(
feature(newPoint(5, 5), Map.of())
)),
newTileEntry(Z13_TILES / 2, Z13_TILES / 2, 13, List.of(
feature(newPoint(10, 10), Map.of())
)),
newTileEntry(Z14_TILES / 2, Z14_TILES / 2, 14, List.of(
feature(newPoint(20, 20), Map.of())
))
), results.tiles);
}

@Test
void testCentroidWithLineMinSize() throws Exception {
List<Coordinate> points = z14CoordinatePixelList(0, 4, 40, 4);

var results = runWithReaderFeatures(
Map.of("threads", "1"),
List.of(
newReaderFeature(newLineString(points), Map.of())
),
(in, features) -> features.centroid("layer")
.setZoomRange(0, 14)
.setBufferPixels(0)
.setMinPixelSize(10) // should only show up z14 (40) z13 (20) and z12 (10)
);

assertEquals(Map.ofEntries(
newTileEntry(Z12_TILES / 2, Z12_TILES / 2, 12, List.of(
feature(newPoint(5, 1), Map.of())
)),
newTileEntry(Z13_TILES / 2, Z13_TILES / 2, 13, List.of(
feature(newPoint(10, 2), Map.of())
)),
newTileEntry(Z14_TILES / 2, Z14_TILES / 2, 14, List.of(
feature(newPoint(20, 4), Map.of())
))
), results.tiles);
}

@Test
void testBoundFiltersFill() throws Exception {
var polyResultz8 = runForBoundsTest(8, 8, "polygon", TestUtils.pathToResource("bottomrightearth.poly").toString());
Expand Down

0 comments on commit c0d6f32

Please sign in to comment.