kopia lustrzana https://github.com/onthegomap/planetiler
Handle more than one centerline for a lake (#139)
rodzic
bf081692ce
commit
313a695abb
|
@ -111,7 +111,13 @@ public class WaterName implements
|
|||
try {
|
||||
// multiple threads call this concurrently
|
||||
synchronized (this) {
|
||||
lakeCenterlines.put(osmId, feature.worldGeometry());
|
||||
// if we already have a centerline for this OSM_ID, then merge the existing one with this one
|
||||
var newGeometry = feature.worldGeometry();
|
||||
var oldGeometry = lakeCenterlines.get(osmId);
|
||||
if (oldGeometry != null) {
|
||||
newGeometry = GeoUtils.combine(oldGeometry, newGeometry);
|
||||
}
|
||||
lakeCenterlines.put(osmId, newGeometry);
|
||||
}
|
||||
} catch (GeometryException e) {
|
||||
e.log(stats, "omt_water_name_lakeline", "Bad lake centerline: " + feature);
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.locationtech.jts.geom.Geometry;
|
||||
|
||||
public class WaterNameTest extends AbstractLayerTest {
|
||||
|
||||
|
@ -89,6 +90,56 @@ public class WaterNameTest extends AbstractLayerTest {
|
|||
)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWaterNameMultipleLakelines() {
|
||||
assertFeatures(11, List.of(), process(SimpleFeature.create(
|
||||
newLineString(0, 0, 1, 1),
|
||||
new HashMap<>(Map.<String, Object>of(
|
||||
"OSM_ID", -10
|
||||
)),
|
||||
LAKE_CENTERLINE_SOURCE,
|
||||
null,
|
||||
0
|
||||
)));
|
||||
assertFeatures(11, List.of(), process(SimpleFeature.create(
|
||||
newLineString(2, 2, 3, 3),
|
||||
new HashMap<>(Map.<String, Object>of(
|
||||
"OSM_ID", -10
|
||||
)),
|
||||
LAKE_CENTERLINE_SOURCE,
|
||||
null,
|
||||
0
|
||||
)));
|
||||
assertFeatures(10, List.of(Map.of(
|
||||
"_layer", "water"
|
||||
), Map.of(
|
||||
"name", "waterway",
|
||||
"name:es", "waterway es",
|
||||
|
||||
"_layer", "water_name",
|
||||
"_geom",
|
||||
new TestUtils.NormGeometry(
|
||||
GeoUtils.latLonToWorldCoords(GeoUtils.JTS_FACTORY.createGeometryCollection(new Geometry[]{
|
||||
newLineString(0, 0, 1, 1),
|
||||
newLineString(2, 2, 3, 3)
|
||||
}))),
|
||||
"_minzoom", 9,
|
||||
"_maxzoom", 14,
|
||||
"_minpixelsize", "waterway".length() * 6d
|
||||
)), process(SimpleFeature.create(
|
||||
GeoUtils.worldToLatLonCoords(rectangle(0, Math.sqrt(1))),
|
||||
new HashMap<>(Map.<String, Object>of(
|
||||
"name", "waterway",
|
||||
"name:es", "waterway es",
|
||||
"natural", "water",
|
||||
"water", "pond"
|
||||
)),
|
||||
OSM_SOURCE,
|
||||
null,
|
||||
10
|
||||
)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMarinePoint() {
|
||||
assertFeatures(11, List.of(), process(SimpleFeature.create(
|
||||
|
|
|
@ -480,6 +480,23 @@ public class GeoUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/** Combines multiple geometries into one {@link GeometryCollection}. */
|
||||
public static Geometry combine(Geometry... geometries) {
|
||||
List<Geometry> innerGeometries = new ArrayList<>();
|
||||
// attempt to flatten out nested geometry collections
|
||||
for (var geom : geometries) {
|
||||
if (geom instanceof GeometryCollection collection) {
|
||||
for (int i = 0; i < collection.getNumGeometries(); i++) {
|
||||
innerGeometries.add(collection.getGeometryN(i));
|
||||
}
|
||||
} else {
|
||||
innerGeometries.add(geom);
|
||||
}
|
||||
}
|
||||
return innerGeometries.size() == 1 ? innerGeometries.get(0) :
|
||||
JTS_FACTORY.createGeometryCollection(innerGeometries.toArray(Geometry[]::new));
|
||||
}
|
||||
|
||||
/** Helper class to sort polygons by area of their outer shell. */
|
||||
private record PolyAndArea(Polygon poly, double area) implements Comparable<PolyAndArea> {
|
||||
|
||||
|
|
|
@ -384,7 +384,8 @@ public class TestUtils {
|
|||
result.put("_labelgrid_limit", feature.getPointLabelGridLimitAtZoom(zoom));
|
||||
result.put("_labelgrid_size", feature.getPointLabelGridPixelSizeAtZoom(zoom));
|
||||
result.put("_minpixelsize", feature.getMinPixelSizeAtZoom(zoom));
|
||||
result.put("_type", geom instanceof Puntal ? "point" : geom instanceof Lineal ? "line" : "polygon");
|
||||
result.put("_type", geom instanceof Puntal ? "point" : geom instanceof Lineal ? "line" :
|
||||
geom instanceof Polygonal ? "polygon" : geom.getClass().getSimpleName());
|
||||
result.put("_numpointsattr", feature.getNumPointsAttr());
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -300,4 +300,40 @@ public class GeoUtilsTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCombineEmpty() {
|
||||
assertEquals(EMPTY_GEOMETRY, GeoUtils.combine());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCombineOne() {
|
||||
assertEquals(newLineString(0, 0, 1, 1), GeoUtils.combine(newLineString(0, 0, 1, 1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCombineTwo() {
|
||||
assertEquals(GeoUtils.JTS_FACTORY.createGeometryCollection(new Geometry[]{
|
||||
newLineString(0, 0, 1, 1),
|
||||
newLineString(2, 2, 3, 3)
|
||||
}), GeoUtils.combine(
|
||||
newLineString(0, 0, 1, 1),
|
||||
newLineString(2, 2, 3, 3)
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCombineNested() {
|
||||
assertEquals(GeoUtils.JTS_FACTORY.createGeometryCollection(new Geometry[]{
|
||||
newLineString(0, 0, 1, 1),
|
||||
newLineString(2, 2, 3, 3),
|
||||
newLineString(4, 4, 5, 5)
|
||||
}), GeoUtils.combine(
|
||||
GeoUtils.combine(
|
||||
newLineString(0, 0, 1, 1),
|
||||
newLineString(2, 2, 3, 3)
|
||||
),
|
||||
newLineString(4, 4, 5, 5)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue