Fix pedestrian area multipolygons (#63)

pull/64/head
Michael Barry 2022-01-27 06:14:37 -05:00 zatwierdzone przez GitHub
rodzic 31a16226a1
commit 48ce4cbe23
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
5 zmienionych plików z 74 dodań i 8 usunięć

Wyświetl plik

@ -513,8 +513,9 @@ public class Transportation implements
public void process(Tables.OsmHighwayPolygon element, FeatureCollector features) {
String manMade = element.manMade();
if (isBridgeOrPier(manMade) ||
// ignore underground pedestrian areas
(element.isArea() && element.layer() >= 0)) {
// only allow closed ways where area=yes, and multipolygons
// and ignore underground pedestrian areas
(!element.source().canBeLine() && element.layer() >= 0)) {
String highwayClass = highwayClass(element.highway(), element.publicTransport(), null, element.manMade());
if (highwayClass != null) {
features.polygon(LAYER_NAME).setBufferPixels(BUFFER_SIZE)

Wyświetl plik

@ -131,6 +131,17 @@ public abstract class AbstractLayerTest {
);
}
SourceFeature closedWayFeature(Map<String, Object> props) {
return SimpleFeature.createFakeOsmFeature(
newLineString(0, 0, 1, 0, 1, 1, 0, 1, 0, 0),
new HashMap<>(props),
OSM_SOURCE,
null,
0,
null
);
}
SourceFeature polygonFeatureWithArea(double area, Map<String, Object> props) {
return SimpleFeature.create(
GeoUtils.worldToLatLonCoords(rectangle(0, Math.sqrt(area))),

Wyświetl plik

@ -990,7 +990,7 @@ public class TransportationTest extends AbstractLayerTest {
@Test
public void testPedestrianArea() {
assertFeatures(10, List.of(Map.of(
Map<String, Object> pedestrianArea = Map.of(
"_layer", "transportation",
"class", "path",
"subclass", "pedestrian",
@ -998,13 +998,36 @@ public class TransportationTest extends AbstractLayerTest {
"_minzoom", 13,
"_maxzoom", 14,
"_type", "polygon"
)), process(polygonFeature(Map.of(
);
Map<String, Object> circularPath = Map.of(
"_layer", "transportation",
"class", "path",
"subclass", "pedestrian",
"_minzoom", 14,
"_maxzoom", 14,
"_type", "line"
);
assertFeatures(14, List.of(pedestrianArea), process(closedWayFeature(Map.of(
"highway", "pedestrian",
"area", "yes",
"foot", "yes"
))));
assertFeatures(14, List.of(pedestrianArea), process(polygonFeature(Map.of(
"highway", "pedestrian",
"foot", "yes"
))));
assertFeatures(14, List.of(circularPath), process(closedWayFeature(Map.of(
"highway", "pedestrian",
"foot", "yes"
))));
assertFeatures(14, List.of(circularPath), process(closedWayFeature(Map.of(
"highway", "pedestrian",
"foot", "yes",
"area", "no"
))));
// ignore underground pedestrian areas
assertFeatures(10, List.of(),
assertFeatures(14, List.of(),
process(polygonFeature(Map.of(
"highway", "pedestrian",
"area", "yes",

Wyświetl plik

@ -8,7 +8,9 @@ import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.Lineal;
import org.locationtech.jts.geom.MultiLineString;
import org.locationtech.jts.geom.Polygonal;
import org.locationtech.jts.geom.Puntal;
@ -77,7 +79,26 @@ public class SimpleFeature extends SourceFeature {
/** Returns a new feature with OSM relation info. Useful for setting up inputs for OSM unit tests. */
public static SimpleFeature createFakeOsmFeature(Geometry latLonGeometry, Map<String, Object> tags, String source,
String sourceLayer, long id, List<OsmReader.RelationMember<OsmRelationInfo>> relations) {
return new SimpleFeature(latLonGeometry, null, tags, source, sourceLayer, id, relations);
String area = (String) tags.get("area");
return new SimpleFeature(latLonGeometry, null, tags, source, sourceLayer, id, relations) {
@Override
public boolean canBePolygon() {
return latLonGeometry instanceof Polygonal || (latLonGeometry instanceof LineString line
&& OsmReader.canBePolygon(line.isClosed(), area, latLonGeometry.getNumPoints()));
}
@Override
public boolean canBeLine() {
return latLonGeometry instanceof MultiLineString || (latLonGeometry instanceof LineString line
&& OsmReader.canBeLine(line.isClosed(), area, latLonGeometry.getNumPoints()));
}
@Override
protected Geometry computePolygon() {
var geom = worldGeometry();
return geom instanceof LineString line ? GeoUtils.JTS_FACTORY.createPolygon(line.getCoordinates()) : geom;
}
};
}
@Override

Wyświetl plik

@ -514,6 +514,16 @@ public class OsmReader implements Closeable, MemoryEstimator.HasEstimate {
}
}
/** Returns {@code true} if a way can be interpreted as a line. */
public static boolean canBeLine(boolean closed, String area, int points) {
return (!closed || !"yes".equals(area)) && points >= 2;
}
/** Returns {@code true} if a way can be interpreted as a polygon. */
public static boolean canBePolygon(boolean closed, String area, int points) {
return (closed && !"no".equals(area)) && points >= 4;
}
/**
* A {@link LineString} or {@link Polygon} created from an OSM way.
* <p>
@ -529,8 +539,8 @@ public class OsmReader implements Closeable, MemoryEstimator.HasEstimate {
public WaySourceFeature(ReaderWay way, boolean closed, String area, NodeLocationProvider nodeLocations,
List<RelationMember<OsmRelationInfo>> relationInfo) {
super(way, false,
(!closed || !"yes".equals(area)) && way.getNodes().size() >= 2, // line
(closed && !"no".equals(area)) && way.getNodes().size() >= 4, // polygon
OsmReader.canBeLine(closed, area, way.getNodes().size()),
OsmReader.canBePolygon(closed, area, way.getNodes().size()),
relationInfo
);
this.nodeIds = way.getNodes();