From 4f07461569e934a9fef3782584c4c54fc61fc788 Mon Sep 17 00:00:00 2001 From: seancoulter <31253489+seancoulter@users.noreply.github.com> Date: Wed, 16 Oct 2019 11:35:04 -0700 Subject: [PATCH] [FloatingEdgeCheck] No longer flag floating edges in airports (#201) * initial * javadoc * unit test; md doc update * spotlessApply --- docs/checks/floatingEdgeCheck.md | 2 +- .../linear/edges/FloatingEdgeCheck.java | 35 ++++++++++++---- .../linear/edges/FloatingEdgeCheckTest.java | 14 +++++++ .../edges/FloatingEdgeCheckTestRule.java | 41 +++++++++++++++++++ 4 files changed, 84 insertions(+), 8 deletions(-) diff --git a/docs/checks/floatingEdgeCheck.md b/docs/checks/floatingEdgeCheck.md index 95545f5be..6c56158d4 100644 --- a/docs/checks/floatingEdgeCheck.md +++ b/docs/checks/floatingEdgeCheck.md @@ -2,7 +2,7 @@ #### Description -This check will look for any edges (Roads) that do not contain any incoming or outgoing edges. +This check will look for any edges (Roads) outside of airports that do not contain any incoming or outgoing edges. The appearance on the map would be that of a road simply floating in the middle of nowhere. No one for any navigation, no ability to enter the edge (road) from any point and no way to exit it. To resolve the issue a mapper would either remove the edge as invalid or connect it to the surrounding diff --git a/src/main/java/org/openstreetmap/atlas/checks/validation/linear/edges/FloatingEdgeCheck.java b/src/main/java/org/openstreetmap/atlas/checks/validation/linear/edges/FloatingEdgeCheck.java index 978fa727d..f8b7745f5 100644 --- a/src/main/java/org/openstreetmap/atlas/checks/validation/linear/edges/FloatingEdgeCheck.java +++ b/src/main/java/org/openstreetmap/atlas/checks/validation/linear/edges/FloatingEdgeCheck.java @@ -3,6 +3,7 @@ import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.stream.StreamSupport; import org.openstreetmap.atlas.checks.atlas.predicates.TypePredicates; import org.openstreetmap.atlas.checks.base.BaseCheck; @@ -10,19 +11,21 @@ import org.openstreetmap.atlas.geography.atlas.items.AtlasObject; import org.openstreetmap.atlas.geography.atlas.items.Edge; import org.openstreetmap.atlas.geography.atlas.items.ItemType; +import org.openstreetmap.atlas.tags.AerowayTag; import org.openstreetmap.atlas.tags.HighwayTag; import org.openstreetmap.atlas.tags.SyntheticBoundaryNodeTag; +import org.openstreetmap.atlas.tags.annotations.validation.Validators; import org.openstreetmap.atlas.utilities.configuration.Configuration; import org.openstreetmap.atlas.utilities.scalars.Distance; /** - * This check will look for any edges that do not contain any incoming or outgoing edges. The - * appearance on the map would be that of a road simply floating in the middle of nowhere. No way - * for any navigation, no ability to enter the {@link Edge} (road) from any point and no way to exit - * it. To resolve the issue a mapper would either remove the edge as invalid or connect it to a - * connected set of edges. + * This check will look for any edges outside of airport boundaries that do not contain any incoming + * or outgoing edges. The appearance on the map would be that of a road simply floating in the + * middle of nowhere. No way for any navigation, no ability to enter the {@link Edge} (road) from + * any point and no way to exit it. To resolve the issue a mapper would either remove the edge as + * invalid or connect it to a connected set of edges. * - * @author cuthbertm, gpogulsky + * @author cuthbertm, gpogulsky, seancoulter */ public class FloatingEdgeCheck extends BaseCheck { @@ -46,6 +49,23 @@ public class FloatingEdgeCheck extends BaseCheck private final Distance minimumDistance; private final HighwayTag highwayMinimum; + /** + * Checks if the {@link Edge} intersects with/is within an airport. + * + * @param edge + * the Edge being checked + * @return true if the edge intersects with an airport; false otherwise + */ + private static boolean intersectsAirport(final Edge edge) + { + return StreamSupport + .stream(edge.getAtlas() + .areasIntersecting(edge.bounds(), + area -> Validators.hasValuesFor(area, AerowayTag.class)) + .spliterator(), false) + .anyMatch(area -> area.asPolygon().overlaps(edge.asPolyLine())); + } + /** * Default constructor defined by the {@link BaseCheck} required to instantiate the Check within * the Atlas Checks framework @@ -93,7 +113,8 @@ public boolean validCheckForObject(final AtlasObject object) { // Consider navigable master edges return TypePredicates.IS_EDGE.test(object) && ((Edge) object).isMasterEdge() - && HighwayTag.isCarNavigableHighway(object) && isMinimumHighwayType(object); + && HighwayTag.isCarNavigableHighway(object) && isMinimumHighwayType(object) + && !intersectsAirport((Edge) object); } /** diff --git a/src/test/java/org/openstreetmap/atlas/checks/validation/linear/edges/FloatingEdgeCheckTest.java b/src/test/java/org/openstreetmap/atlas/checks/validation/linear/edges/FloatingEdgeCheckTest.java index 255d3e91f..adbd3449a 100644 --- a/src/test/java/org/openstreetmap/atlas/checks/validation/linear/edges/FloatingEdgeCheckTest.java +++ b/src/test/java/org/openstreetmap/atlas/checks/validation/linear/edges/FloatingEdgeCheckTest.java @@ -22,6 +22,13 @@ public class FloatingEdgeCheckTest ConfigurationResolver.inlineConfiguration( "{\"FloatingEdgeCheck\":{\"highway.minimum\": \"PRIMARY_LINK\",\"length\":{\"maximum.kilometers\":16.093,\"minimum.meters\": 1.0}}}")); + @Test + public void testAirportIntersectingEdge() + { + this.verifier.actual(this.setup.airportAtlas(), this.check); + this.verifier.verifyEmpty(); + } + @Test public void testBidirectionalFloatingEdge() { @@ -45,6 +52,13 @@ public void testFloatingEdge() this.verifier.globallyVerify(flags -> Assert.assertEquals(1, flags.size())); } + @Test + public void testFloatingEdgeContainedInAirportPolygon() + { + this.verifier.actual(this.setup.floatingEdgeInAirportPolygon(), this.check); + this.verifier.verifyEmpty(); + } + @Test public void testInlineConfigFloatingEdge() { diff --git a/src/test/java/org/openstreetmap/atlas/checks/validation/linear/edges/FloatingEdgeCheckTestRule.java b/src/test/java/org/openstreetmap/atlas/checks/validation/linear/edges/FloatingEdgeCheckTestRule.java index fad841dfd..7c7627b85 100644 --- a/src/test/java/org/openstreetmap/atlas/checks/validation/linear/edges/FloatingEdgeCheckTestRule.java +++ b/src/test/java/org/openstreetmap/atlas/checks/validation/linear/edges/FloatingEdgeCheckTestRule.java @@ -6,6 +6,7 @@ import org.openstreetmap.atlas.geography.atlas.Atlas; import org.openstreetmap.atlas.utilities.testing.CoreTestRule; import org.openstreetmap.atlas.utilities.testing.TestAtlas; +import org.openstreetmap.atlas.utilities.testing.TestAtlas.Area; import org.openstreetmap.atlas.utilities.testing.TestAtlas.Edge; import org.openstreetmap.atlas.utilities.testing.TestAtlas.Loc; import org.openstreetmap.atlas.utilities.testing.TestAtlas.Node; @@ -19,9 +20,27 @@ public class FloatingEdgeCheckTestRule extends CoreTestRule private static final String TEST_2 = "37.33531,-122.009566"; private static final String TEST_3 = "37.3314171,-122.0304871"; + private static final String TEST_4 = "47.6027,-122.3182"; + private static final String TEST_5 = "47.6027,-122.3130"; + private static final String TEST_6 = "47.6008,-122.3130"; + private static final String TEST_7 = "47.6009,-122.3179"; + + private static final String TEST_8 = "47.6025,-122.3181"; + private static final String TEST_9 = "47.6011,-122.3177"; + private static final String LOCATION_1 = "1.11,1.11"; private static final String LOCATION_2 = "1.12,1.12"; + @TestAtlas(nodes = { @Node(coordinates = @Loc(value = TEST_1)), + @Node(coordinates = @Loc(value = TEST_2)), @Node(coordinates = @Loc(value = TEST_3)), + @Node(coordinates = @Loc(value = LOCATION_1)), + @Node(coordinates = @Loc(value = LOCATION_2)) }, edges = { + @Edge(coordinates = { @Loc(value = TEST_1), @Loc(value = TEST_2) }, tags = { + "highway=SECONDARY" }) }, areas = { + @Area(coordinates = { @Loc(value = TEST_1), + @Loc(value = TEST_2) }, tags = { "aeroway=taxiway" }) }) + private Atlas airportAtlas; + @TestAtlas(nodes = { @Node(coordinates = @Loc(value = TEST_1)), @Node(coordinates = @Loc(value = TEST_2)), @Node(coordinates = @Loc(value = TEST_3)) }, edges = { @@ -45,6 +64,17 @@ public class FloatingEdgeCheckTestRule extends CoreTestRule @Loc(value = LOCATION_1) }, tags = { "highway=SECONDARY" }) }) private Atlas floatingBidirectionalEdgeAtlas; + @TestAtlas(nodes = { @Node(coordinates = @Loc(value = TEST_4)), + @Node(coordinates = @Loc(value = TEST_5)), @Node(coordinates = @Loc(value = TEST_6)), + @Node(coordinates = @Loc(value = TEST_7)), @Node(coordinates = @Loc(value = TEST_8)), + @Node(coordinates = @Loc(value = TEST_9)) }, edges = { + @Edge(coordinates = { @Loc(value = TEST_8), @Loc(value = TEST_9) }, tags = { + "highway=SECONDARY" }) }, areas = { + @Area(coordinates = { @Loc(value = TEST_4), + @Loc(value = TEST_5), @Loc(value = TEST_6), + @Loc(value = TEST_7) }, tags = { "aeroway=taxiway" }) }) + private Atlas floatingEdgeInAirportAtlas; + @TestAtlas(nodes = { @Node(coordinates = @Loc(value = LOCATION_1), tags = { "synthetic_boundary_node=YES" }), @Node(coordinates = @Loc(value = LOCATION_2)) }, edges = { @@ -64,6 +94,11 @@ public class FloatingEdgeCheckTestRule extends CoreTestRule @Loc(value = LOCATION_2) }, tags = { "highway=SECONDARY" }) }) private Atlas mixedAtlas; + public Atlas airportAtlas() + { + return this.airportAtlas; + } + public Atlas connectedEdgeAtlas() { return this.connectedEdgeAtlas; @@ -79,6 +114,11 @@ public Atlas floatingEdgeAtlas() return this.floatingEdgeAtlas; } + public Atlas floatingEdgeInAirportPolygon() + { + return this.floatingEdgeInAirportAtlas; + } + public Atlas mixedAtlas() { return this.mixedAtlas; @@ -88,4 +128,5 @@ public Atlas syntheticBorderAtlas() { return this.syntheticBorderAtlas; } + }