From 40f7e9eed9684fd20a671cc71db8e514be43e474 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 8 Jun 2023 12:07:37 +0200 Subject: [PATCH] Add test for StairsEdge --- .../street/model/edge/StreetEdge.java | 3 - .../model/_data/StreetModelForTest.java | 5 + .../street/model/edge/StairsEdgeTest.java | 165 ++++++++++++++++++ .../street/model/edge/StreetEdgeCostTest.java | 79 --------- .../edge/StreetEdgeWheelchairCostTest.java | 48 ----- 5 files changed, 170 insertions(+), 130 deletions(-) create mode 100644 src/test/java/org/opentripplanner/street/model/edge/StairsEdgeTest.java diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java b/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java index 58402f8dcab..5f37bd9daad 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java @@ -8,12 +8,9 @@ import java.util.List; import java.util.Optional; import javax.annotation.Nonnull; -import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.LineString; import org.locationtech.jts.geom.impl.PackedCoordinateSequence; -import org.opentripplanner.framework.geometry.AngleUtils; import org.opentripplanner.framework.geometry.CompactLineStringUtils; -import org.opentripplanner.framework.geometry.DirectionUtils; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.geometry.SphericalDistanceLibrary; import org.opentripplanner.framework.geometry.SplitLineString; diff --git a/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java b/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java index 23bbd6a1d66..10b44e9c3b3 100644 --- a/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java +++ b/src/test/java/org/opentripplanner/street/model/_data/StreetModelForTest.java @@ -6,6 +6,7 @@ import org.opentripplanner.framework.geometry.SphericalDistanceLibrary; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model.edge.StreetEdge; +import org.opentripplanner.street.model.vertex.BarrierVertex; import org.opentripplanner.street.model.vertex.IntersectionVertex; import org.opentripplanner.street.model.vertex.StreetVertex; @@ -25,6 +26,10 @@ public static IntersectionVertex intersectionVertex(String label, double lat, do return new IntersectionVertex(null, label, lat, lon, label); } + public static BarrierVertex barrierVertex(double lat, double lon) { + return new BarrierVertex(null, "barrier_lat:%s_lon:%s".formatted(lat, lon), lat, lon, 111555); + } + public static StreetEdge streetEdge(StreetVertex vA, StreetVertex vB) { var meters = SphericalDistanceLibrary.distance(vA.getCoordinate(), vB.getCoordinate()); return streetEdge(vA, vB, meters, StreetTraversalPermission.ALL); diff --git a/src/test/java/org/opentripplanner/street/model/edge/StairsEdgeTest.java b/src/test/java/org/opentripplanner/street/model/edge/StairsEdgeTest.java new file mode 100644 index 00000000000..bfd82fceaa1 --- /dev/null +++ b/src/test/java/org/opentripplanner/street/model/edge/StairsEdgeTest.java @@ -0,0 +1,165 @@ +package org.opentripplanner.street.model.edge; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.street.model.StreetTraversalPermission.NONE; +import static org.opentripplanner.street.model.StreetTraversalPermission.PEDESTRIAN; +import static org.opentripplanner.street.model._data.StreetModelForTest.V1; +import static org.opentripplanner.street.model._data.StreetModelForTest.V2; + +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.opentripplanner.framework.geometry.GeometryUtils; +import org.opentripplanner.framework.i18n.NonLocalizedString; +import org.opentripplanner.routing.api.request.StreetMode; +import org.opentripplanner.routing.api.request.preference.WheelchairPreferences; +import org.opentripplanner.street.model.StreetTraversalPermission; +import org.opentripplanner.street.model._data.StreetModelForTest; +import org.opentripplanner.street.search.request.StreetSearchRequest; +import org.opentripplanner.street.search.state.State; +import org.opentripplanner.test.support.VariableSource; + +class StairsEdgeTest { + + private static final double LENGTH = 10; + private static final StairsEdge STAIRS_EDGE = new StairsEdge( + V1, + V2, + GeometryUtils.makeLineString(V1.getCoordinate(), V2.getCoordinate()), + new NonLocalizedString("stairs"), + LENGTH + ); + + static Stream stairsCases = Stream.of( + Arguments.of(1, 22), + Arguments.of(1.5, 33), + Arguments.of(3, 67) + ); + + @ParameterizedTest(name = "stairs reluctance of {0} should lead to traversal costs of {1}") + @VariableSource("stairsCases") + public void stairsReluctance(double stairsReluctance, long expectedCost) { + var req = StreetSearchRequest.of(); + req.withPreferences(p -> p.withWalk(w -> w.withStairsReluctance(stairsReluctance))); + req.withMode(StreetMode.WALK); + var result = traverse(STAIRS_EDGE, req.build()); + assertEquals(expectedCost, (long) result.weight); + + assertEquals(22, result.getElapsedTimeSeconds()); + + var streetEdge = new StreetEdge( + V1, + V2, + null, + "stairs", + LENGTH, + StreetTraversalPermission.ALL, + false + ); + var notStairsResult = traverse(streetEdge, req.build()); + assertEquals(15, (long) notStairsResult.weight); + } + + static Stream bikeStairsCases = Stream.of( + Arguments.of(1, 45), + Arguments.of(1.5, 68), + Arguments.of(3, 135) + ); + + @ParameterizedTest(name = "bike stairs reluctance of {0} should lead to traversal costs of {1}") + @VariableSource("bikeStairsCases") + public void bikeStairsReluctance(double stairsReluctance, double expectedCost) { + var req = StreetSearchRequest.of(); + req.withPreferences(p -> p.withBike(b -> b.withStairsReluctance(stairsReluctance))); + req.withMode(StreetMode.BIKE); + var result = traverse(STAIRS_EDGE, req.build()); + assertEquals(expectedCost, result.weight, 0.5); + + assertEquals(22, result.getElapsedTimeSeconds()); + var streetEdge = new StreetEdge(V1, V2, null, "stairs", LENGTH, PEDESTRIAN, false); + + var notStairsResult = traverse(streetEdge, req.build()); + assertEquals(37, (long) notStairsResult.weight); + } + + static Stream wheelchairStairsCases = Stream.of( + Arguments.of(1, 22), + Arguments.of(10, 225), + Arguments.of(100, 2255) + ); + + @ParameterizedTest( + name = "wheelchair stairs reluctance of {0} should lead to traversal costs of {1}" + ) + @VariableSource("wheelchairStairsCases") + public void wheelchairStairsReluctance(double stairsReluctance, long expectedCost) { + var req = StreetSearchRequest.of(); + req.withWheelchair(true); + req.withPreferences(preferences -> + preferences.withWheelchair( + WheelchairPreferences + .of() + .withTripOnlyAccessible() + .withStopOnlyAccessible() + .withElevatorOnlyAccessible() + .withInaccessibleStreetReluctance(25) + .withMaxSlope(0) + .withSlopeExceededReluctance(1.1) + .withStairsReluctance(stairsReluctance) + .build() + ) + ); + + req.withPreferences(pref -> pref.withWalk(w -> w.withReluctance(1.0))); + + var result = traverse(STAIRS_EDGE, req.build()); + assertEquals(expectedCost, (long) result.weight); + + var edge = new StreetEdge(V1, V2, null, "stairs", LENGTH, StreetTraversalPermission.ALL, false); + var notStairsResult = traverse(edge, req.build()); + assertEquals(7, (long) notStairsResult.weight); + } + + @Test + void noCar() { + var req = StreetSearchRequest.of(); + req.withMode(StreetMode.CAR); + var state = new State(V1, req.build()); + var result = STAIRS_EDGE.traverse(state); + assertTrue(State.isEmpty(result)); + } + + static Stream barrierCases = Stream.of( + Arguments.of(PEDESTRIAN, false), + Arguments.of(NONE, true) + ); + + @ParameterizedTest(name = "a barrier permission of {0} should block walking traversal={1}") + @VariableSource("barrierCases") + void barriers(StreetTraversalPermission permission, boolean shouldBlockTraversal) { + var barrier = StreetModelForTest.barrierVertex(V2.getLat(), V2.getLon()); + barrier.setBarrierPermissions(permission); + + var edge = new StairsEdge( + V1, + barrier, + GeometryUtils.makeLineString(V1.getCoordinate(), V2.getCoordinate()), + new NonLocalizedString("stairs"), + LENGTH + ); + + var req = StreetSearchRequest.of(); + req.withMode(StreetMode.WALK); + var state = new State(V1, req.build()); + var result = edge.traverse(state); + assertEquals(shouldBlockTraversal, State.isEmpty(result)); + } + + private State traverse(OsmEdge edge, StreetSearchRequest request) { + var state = new State(V1, request); + assertEquals(0, state.weight); + return edge.traverse(state)[0]; + } +} diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeCostTest.java b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeCostTest.java index 533441c12ec..1e46b89d584 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeCostTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeCostTest.java @@ -86,85 +86,6 @@ public void carReluctance(double carReluctance, long expectedCost) { assertEquals(9, result.getElapsedTimeSeconds()); } - static Stream stairsCases = Stream.of( - Arguments.of(1, 22), - Arguments.of(1.5, 33), - Arguments.of(3, 67) - ); - - @ParameterizedTest(name = "stairs reluctance of {0} should lead to traversal costs of {1}") - @VariableSource("stairsCases") - public void stairsReluctance(double stairsReluctance, long expectedCost) { - double length = 10; - var edge = new StairsEdge( - V1, - V2, - GeometryUtils.makeLineString(V1.getCoordinate(), V2.getCoordinate()), - new NonLocalizedString("stairs"), - length - ); - - var req = StreetSearchRequest.of(); - req.withPreferences(p -> p.withWalk(w -> w.withStairsReluctance(stairsReluctance))); - req.withMode(StreetMode.WALK); - var result = traverse(edge, req.build()); - assertEquals(expectedCost, (long) result.weight); - - assertEquals(22, result.getElapsedTimeSeconds()); - - var streetEdge = new StreetEdge( - V1, - V2, - null, - "stairs", - length, - StreetTraversalPermission.ALL, - false - ); - var notStairsResult = traverse(streetEdge, req.build()); - assertEquals(15, (long) notStairsResult.weight); - } - - static Stream bikeStairsCases = Stream.of( - Arguments.of(1, 45), - Arguments.of(1.5, 68), - Arguments.of(3, 135) - ); - - @ParameterizedTest(name = "bike stairs reluctance of {0} should lead to traversal costs of {1}") - @VariableSource("bikeStairsCases") - public void bikeStairsReluctance(double stairsReluctance, double expectedCost) { - double length = 10; - - var edge = new StairsEdge( - V1, - V2, - GeometryUtils.makeLineString(V1.getCoordinate(), V2.getCoordinate()), - new NonLocalizedString("stairs"), - length - ); - - var req = StreetSearchRequest.of(); - req.withPreferences(p -> p.withBike(b -> b.withStairsReluctance(stairsReluctance))); - req.withMode(StreetMode.BIKE); - var result = traverse(edge, req.build()); - assertEquals(expectedCost, result.weight, 0.5); - - assertEquals(22, result.getElapsedTimeSeconds()); - var streetEdge = new StreetEdge( - V1, - V2, - null, - "stairs", - length, - StreetTraversalPermission.PEDESTRIAN, - false - ); - - var notStairsResult = traverse(streetEdge, req.build()); - assertEquals(37, (long) notStairsResult.weight); - } - static Stream walkSafetyCases = Stream.of( Arguments.of(0, 15), Arguments.of(0.5, 22), diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeWheelchairCostTest.java b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeWheelchairCostTest.java index 58562434de9..0498f95e4a4 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeWheelchairCostTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeWheelchairCostTest.java @@ -103,54 +103,6 @@ public void shouldScaleCostWithMaxSlope(double slope, double reluctance, long ex assertEquals(expectedCost, (long) result.weight); } - static Stream wheelchairStairsCases = Stream.of( - Arguments.of(1, 22), - Arguments.of(10, 225), - Arguments.of(100, 2255) - ); - - @ParameterizedTest( - name = "wheelchair stairs reluctance of {0} should lead to traversal costs of {1}" - ) - @VariableSource("wheelchairStairsCases") - public void wheelchairStairsReluctance(double stairsReluctance, long expectedCost) { - double length = 10; - - var stairsEdge = new StairsEdge( - V1, - V2, - GeometryUtils.makeLineString(V1.getCoordinate(), V2.getCoordinate()), - new NonLocalizedString("stairs"), - length - ); - - var req = StreetSearchRequest.of(); - req.withWheelchair(true); - req.withPreferences(preferences -> - preferences.withWheelchair( - WheelchairPreferences - .of() - .withTripOnlyAccessible() - .withStopOnlyAccessible() - .withElevatorOnlyAccessible() - .withInaccessibleStreetReluctance(25) - .withMaxSlope(0) - .withSlopeExceededReluctance(1.1) - .withStairsReluctance(stairsReluctance) - .build() - ) - ); - - req.withPreferences(pref -> pref.withWalk(w -> w.withReluctance(1.0))); - - var result = traverse(stairsEdge, req.build()); - assertEquals(expectedCost, (long) result.weight); - - var edge = new StreetEdge(V1, V2, null, "stairs", length, StreetTraversalPermission.ALL, false); - var notStairsResult = traverse(edge, req.build()); - assertEquals(7, (long) notStairsResult.weight); - } - static Stream inaccessibleStreetCases = Stream.of( Arguments.of(1f, 15), Arguments.of(10f, 150),