diff --git a/application/src/ext/java/org/opentripplanner/ext/flex/template/AbstractFlexTemplate.java b/application/src/ext/java/org/opentripplanner/ext/flex/template/AbstractFlexTemplate.java index 8dbcf4d785e..aeeab84259c 100644 --- a/application/src/ext/java/org/opentripplanner/ext/flex/template/AbstractFlexTemplate.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/template/AbstractFlexTemplate.java @@ -199,7 +199,7 @@ private FlexAccessEgress createFlexAccessEgress( return null; } - final var finalStateOpt = EdgeTraverser.traverseEdges(afterFlexState[0], transferEdges); + final var finalStateOpt = EdgeTraverser.traverseEdges(afterFlexState, transferEdges); return finalStateOpt .map(finalState -> { diff --git a/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexDirectPathFactory.java b/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexDirectPathFactory.java index f27a502911f..ae35c262a1e 100644 --- a/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexDirectPathFactory.java +++ b/application/src/ext/java/org/opentripplanner/ext/flex/template/FlexDirectPathFactory.java @@ -113,7 +113,7 @@ private Optional createDirectGraphPath( final State[] afterFlexState = flexEdge.traverse(accessNearbyStop.state); - var finalStateOpt = EdgeTraverser.traverseEdges(afterFlexState[0], egress.edges); + var finalStateOpt = EdgeTraverser.traverseEdges(afterFlexState, egress.edges); if (finalStateOpt.isEmpty()) { return Optional.empty(); diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java index 3819500e605..0fef72f7b3e 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.Set; import org.opentripplanner.astar.model.GraphPath; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.geometry.GeometryUtils; @@ -38,8 +39,8 @@ import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.street.search.request.StreetSearchRequest; import org.opentripplanner.street.search.request.StreetSearchRequestMapper; +import org.opentripplanner.street.search.state.EdgeTraverser; import org.opentripplanner.street.search.state.State; -import org.opentripplanner.street.search.state.StateEditor; import org.opentripplanner.transit.model.timetable.TripIdAndServiceDate; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.service.TransitService; @@ -360,24 +361,15 @@ private List mapNonTransitLeg( .build() ); } else { - StateEditor se = new StateEditor(edges.get(0).getFromVertex(), transferStreetRequest); - se.setTimeSeconds(createZonedDateTime(pathLeg.fromTime()).toEpochSecond()); - - State s = se.makeState(); - ArrayList transferStates = new ArrayList<>(); - transferStates.add(s); - for (Edge e : edges) { - var states = e.traverse(s); - if (State.isEmpty(states)) { - s = null; - } else { - transferStates.add(states[0]); - s = states[0]; - } - } - - State[] states = transferStates.toArray(new State[0]); - var graphPath = new GraphPath<>(states[states.length - 1]); + var legTransferSearchRequest = transferStreetRequest + .copyOf(createZonedDateTime(pathLeg.fromTime()).toInstant()) + .build(); + var initialStates = State.getInitialStates( + Set.of(edges.getFirst().getFromVertex()), + legTransferSearchRequest + ); + var state = EdgeTraverser.traverseEdges(initialStates, edges); + var graphPath = new GraphPath<>(state.get()); Itinerary subItinerary = graphPathToItineraryMapper.generateItinerary(graphPath); diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/Transfer.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/Transfer.java index 7a6e6568bb4..32d54787e6f 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/Transfer.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/Transfer.java @@ -4,6 +4,7 @@ import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.Set; import org.locationtech.jts.geom.Coordinate; import org.opentripplanner.raptor.api.model.RaptorCostConverter; import org.opentripplanner.raptor.api.model.RaptorTransfer; @@ -11,7 +12,7 @@ import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.search.request.StreetSearchRequest; import org.opentripplanner.street.search.state.EdgeTraverser; -import org.opentripplanner.street.search.state.StateEditor; +import org.opentripplanner.street.search.state.State; import org.opentripplanner.utils.logging.Throttle; import org.opentripplanner.utils.tostring.ToStringBuilder; import org.slf4j.Logger; @@ -84,10 +85,8 @@ public Optional asRaptorTransfer(StreetSearchRequest request) { ); } - StateEditor se = new StateEditor(edges.get(0).getFromVertex(), request); - se.setTimeSeconds(0); - - var state = EdgeTraverser.traverseEdges(se.makeState(), edges); + var initialStates = State.getInitialStates(Set.of(edges.getFirst().getFromVertex()), request); + var state = EdgeTraverser.traverseEdges(initialStates, edges); return state.map(s -> new DefaultRaptorTransfer( diff --git a/application/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequest.java b/application/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequest.java index c93ea598256..df8933cd22d 100644 --- a/application/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequest.java +++ b/application/src/main/java/org/opentripplanner/street/search/request/StreetSearchRequest.java @@ -124,6 +124,10 @@ public DataOverlayContext dataOverlayContext() { return dataOverlayContext; } + public StreetSearchRequestBuilder copyOf(Instant time) { + return copyOf(this).withStartTime(time); + } + public StreetSearchRequestBuilder copyOfReversed(Instant time) { return copyOf(this).withStartTime(time).withArriveBy(!arriveBy); } diff --git a/application/src/main/java/org/opentripplanner/street/search/state/EdgeTraverser.java b/application/src/main/java/org/opentripplanner/street/search/state/EdgeTraverser.java index 8755f014e14..502d014e358 100644 --- a/application/src/main/java/org/opentripplanner/street/search/state/EdgeTraverser.java +++ b/application/src/main/java/org/opentripplanner/street/search/state/EdgeTraverser.java @@ -2,7 +2,10 @@ import java.util.Collection; import java.util.Optional; +import org.opentripplanner.astar.model.ShortestPathTree; import org.opentripplanner.street.model.edge.Edge; +import org.opentripplanner.street.model.vertex.Vertex; +import org.opentripplanner.street.search.strategy.DominanceFunctions; /** * This is a very reduced version of the A* algorithm: from an initial state a number of edges are @@ -14,24 +17,49 @@ */ public class EdgeTraverser { - public static Optional traverseEdges(final State s, final Collection edges) { - var state = s; + public static Optional traverseEdges( + final Collection initialStates, + final Collection edges + ) { + return traverseEdges(initialStates.toArray(new State[0]), edges); + } + + public static Optional traverseEdges( + final State[] initialStates, + final Collection edges + ) { + if (edges.isEmpty()) { + return Optional.of(initialStates[0]); + } + + // The shortest path tree is used to prune dominated parallel states. For example, + // CAR_PICKUP can return both a CAR/WALK state after each traversal of which only + // the optimal states need to be continued. + var dominanceFunction = new DominanceFunctions.MinimumWeight(); + var spt = new ShortestPathTree<>(dominanceFunction); + for (State initialState : initialStates) { + spt.add(initialState); + } + + Vertex lastVertex = null; + var isArriveBy = initialStates[0].getRequest().arriveBy(); for (Edge e : edges) { - var afterTraversal = e.traverse(state); - if (afterTraversal.length > 1) { - throw new IllegalStateException( - "Expected only a single state returned from edge %s but received %s".formatted( - e, - afterTraversal.length - ) - ); - } - if (State.isEmpty(afterTraversal)) { + var vertex = isArriveBy ? e.getToVertex() : e.getFromVertex(); + var fromStates = spt.getStates(vertex); + if (fromStates == null || fromStates.isEmpty()) { return Optional.empty(); - } else { - state = afterTraversal[0]; } + + for (State fromState : fromStates) { + var newToStates = e.traverse(fromState); + for (State newToState : newToStates) { + spt.add(newToState); + } + } + + lastVertex = isArriveBy ? e.getFromVertex() : e.getToVertex(); } - return Optional.ofNullable(state); + + return Optional.ofNullable(lastVertex).map(spt::getState); } } diff --git a/application/src/test/java/org/opentripplanner/_support/geometry/Coordinates.java b/application/src/test/java/org/opentripplanner/_support/geometry/Coordinates.java index 5a4526012c9..33569a34b2e 100644 --- a/application/src/test/java/org/opentripplanner/_support/geometry/Coordinates.java +++ b/application/src/test/java/org/opentripplanner/_support/geometry/Coordinates.java @@ -6,6 +6,8 @@ public class Coordinates { public static final Coordinate BERLIN = of(52.5212, 13.4105); public static final Coordinate BERLIN_BRANDENBURG_GATE = of(52.51627, 13.37770); + public static final Coordinate BERLIN_FERNSEHTURM = of(52.52084, 13.40934); + public static final Coordinate BERLIN_ADMIRALBRUCKE = of(52.49526, 13.415093); public static final Coordinate HAMBURG = of(53.5566, 10.0003); public static final Coordinate KONGSBERG_PLATFORM_1 = of(59.67216, 9.65107); public static final Coordinate BOSTON = of(42.36541, -71.06129); diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/CarPickupSnapshotTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/CarPickupSnapshotTest.java new file mode 100644 index 00000000000..c233d0c6bbc --- /dev/null +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/CarPickupSnapshotTest.java @@ -0,0 +1,71 @@ +package org.opentripplanner.routing.algorithm.mapping; + +import au.com.origin.snapshots.junit5.SnapshotExtension; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.opentripplanner.model.GenericLocation; +import org.opentripplanner.model.modes.ExcludeAllTransitFilter; +import org.opentripplanner.routing.api.request.RouteRequest; +import org.opentripplanner.routing.api.request.StreetMode; +import org.opentripplanner.routing.api.request.request.filter.AllowAllTransitFilter; + +@ExtendWith(SnapshotExtension.class) +public class CarPickupSnapshotTest extends SnapshotTestBase { + + static GenericLocation p0 = new GenericLocation( + "SE Stark St. & SE 17th Ave. (P0)", + null, + 45.519320, + -122.648567 + ); + + static GenericLocation p1 = new GenericLocation( + "SE Morrison St. & SE 17th Ave. (P1)", + null, + 45.51726, + -122.64847 + ); + + static GenericLocation p2 = new GenericLocation( + "NW Northrup St. & NW 22nd Ave. (P2)", + null, + 45.53122, + -122.69659 + ); + + @BeforeAll + public static void beforeClass() { + loadGraphBeforeClass(false); + } + + @Test + public void test_trip_planning_with_car_pickup_only() { + RouteRequest request = createTestRequest(2009, 11, 17, 10, 0, 0); + + request.journey().direct().setMode(StreetMode.CAR_PICKUP); + request.journey().transit().setFilters(List.of(ExcludeAllTransitFilter.of())); + + request.setFrom(p0); + request.setTo(p2); + + expectRequestResponseToMatchSnapshot(request); + } + + @Test + public void test_trip_planning_with_car_pickup_transfer() { + RouteRequest request = createTestRequest(2009, 11, 17, 10, 0, 0); + + request.journey().access().setMode(StreetMode.WALK); + request.journey().egress().setMode(StreetMode.WALK); + request.journey().direct().setMode(StreetMode.WALK); + request.journey().transfer().setMode(StreetMode.CAR_PICKUP); + request.journey().transit().setFilters(List.of(AllowAllTransitFilter.of())); + + request.setFrom(p0); + request.setTo(p2); + + expectRequestResponseToMatchSnapshot(request); + } +} diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarPickupSnapshotTest.snap b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarPickupSnapshotTest.snap new file mode 100644 index 00000000000..a3a515f82b4 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarPickupSnapshotTest.snap @@ -0,0 +1,3438 @@ +org.opentripplanner.routing.algorithm.mapping.CarPickupSnapshotTest.test_trip_planning_with_car_pickup_only=[ + [ + { + "arrivedAtDestinationWithRentedBicycle" : false, + "duration" : 634, + "elevationGained" : 0.0, + "elevationLost" : 0.0, + "endTime" : "2009-11-17T18:10:34.000+00:00", + "fare" : { + "details" : { }, + "fare" : { } + }, + "generalizedCost" : 1005, + "legs" : [ + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 5050.5, + "endTime" : "2009-11-17T18:10:34.000+00:00", + "from" : { + "departure" : "2009-11-17T18:00:00.000+00:00", + "lat" : 45.51932, + "lon" : -122.648567, + "name" : "SE Stark St. & SE 17th Ave. (P0)", + "vertexType" : "NORMAL" + }, + "generalizedCost" : 1005, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 200, + "points" : "unytGpxqkVA??dACpB@P?f@?p@?j@?dAAhE?jE?vD?PK?aC?{BAS?mC??hE?nEAfE?hE?hEAnC?^?Z?pB?J?~@?J}B?O?OAo@?A?w@?U?S?iB?O??Z?xC?XAJ?P?R@H@FBFBFBDDDBBDBF@F?d@@H@D@FBFD@BBDBF@H@L?L?b@@RBTGpJCjEA|CArAAxAAxAAdBEzHClF?@Ax@GTAjBAZQ?qBBuA@Y@[@aCDM@K?aCBCV@pCDZ@|D@N@vD?L?F?JBbD?D?N?BK?uBBM?K?uBBI@K?aBBSAM@M@K?GBEDEHIJUX_@f@KNQRSVGFCBQPIHGDGBIBK@W@a@?mA@E?C@C@A?CBQTKJEHIJeC~CYZo@v@g@d@IJAFAD?L@vC@hB@p@?X?T@P?N@P@nA?j@AX?L@`B@dA?R?RBbD?T?NBbD?R?P@|D@jB?x@@J?N?B?P?LBjD@N@fD?T?LBdD?R?PF`K?RDlJ?R?PFlJ?J" + }, + "mode" : "CAR", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:00:00.000+00:00", + "steps" : [ + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 0.69, + "elevation" : "", + "lat" : 45.51932, + "lon" : -122.6485648, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "Southeast 17th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 395.42, + "elevation" : "", + "lat" : 45.5193262, + "lon" : -122.6485648, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Southeast Stark Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 238.05, + "elevation" : "", + "lat" : 45.5193421, + "lon" : -122.6536397, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Southeast 12th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 553.35, + "elevation" : "", + "lat" : 45.5214829, + "lon" : -122.6536226, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Southeast Ash Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 158.48, + "elevation" : "", + "lat" : 45.5215062, + "lon" : -122.6607251, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Southeast Grand Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 78.88, + "elevation" : "", + "lat" : 45.5229315, + "lon" : -122.6607174, + "relativeDirection" : "CONTINUE", + "stayOn" : false, + "streetName" : "Northeast Grand Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 168.84, + "elevation" : "", + "lat" : 45.5236409, + "lon" : -122.6607123, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Northeast Couch Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "SOUTHWEST", + "area" : false, + "bogusName" : false, + "distance" : 64.13, + "elevation" : "", + "lat" : 45.5231423, + "lon" : -122.6623136, + "relativeDirection" : "SLIGHTLY_RIGHT", + "stayOn" : true, + "streetName" : "Northeast Couch Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 144.26, + "elevation" : "", + "lat" : 45.522964, + "lon" : -122.6630306, + "relativeDirection" : "CONTINUE", + "stayOn" : false, + "streetName" : "East Burnside Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 407.38, + "elevation" : "", + "lat" : 45.523001, + "lon" : -122.6648816, + "relativeDirection" : "CONTINUE", + "stayOn" : false, + "streetName" : "Burnside Bridge", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 178.19, + "elevation" : "", + "lat" : 45.5231054, + "lon" : -122.6701087, + "relativeDirection" : "CONTINUE", + "stayOn" : false, + "streetName" : "West Burnside Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 310.7, + "elevation" : "", + "lat" : 45.5231958, + "lon" : -122.6723802, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Northwest 2nd Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 317.18, + "elevation" : "", + "lat" : 45.5259887, + "lon" : -122.6724927, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Northwest Flanders Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 238.16, + "elevation" : "", + "lat" : 45.5259105, + "lon" : -122.6765581, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Northwest 6th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 465.44, + "elevation" : "", + "lat" : 45.5280515, + "lon" : -122.6766232, + "relativeDirection" : "CONTINUE", + "stayOn" : false, + "streetName" : "Northwest Station Way", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 1331.38, + "elevation" : "", + "lat" : 45.5315452, + "lon" : -122.679511, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Northwest Northrup Street", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:10:34.000+00:00", + "lat" : 45.53122, + "lon" : -122.69659, + "name" : "NW Northrup St. & NW 22nd Ave. (P2)", + "vertexType" : "NORMAL" + }, + "transitLeg" : false, + "walkingBike" : false + } + ], + "startTime" : "2009-11-17T18:00:00.000+00:00", + "tooSloped" : false, + "transfers" : 0, + "transitTime" : 0, + "waitingTime" : 0, + "walkDistance" : 5050.5, + "walkLimitExceeded" : false, + "walkTime" : 634 + } + ] +] + + +org.opentripplanner.routing.algorithm.mapping.CarPickupSnapshotTest.test_trip_planning_with_car_pickup_transfer=[ + [ + { + "arrivedAtDestinationWithRentedBicycle" : false, + "duration" : 3804, + "elevationGained" : 0.0, + "elevationLost" : 0.0, + "endTime" : "2009-11-17T19:03:24.000+00:00", + "fare" : { + "details" : { }, + "fare" : { } + }, + "generalizedCost" : 7384, + "legs" : [ + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 4875.79, + "endTime" : "2009-11-17T19:03:24.000+00:00", + "from" : { + "departure" : "2009-11-17T18:00:00.000+00:00", + "lat" : 45.51932, + "lon" : -122.648567, + "name" : "SE Stark St. & SE 17th Ave. (P0)", + "vertexType" : "NORMAL" + }, + "generalizedCost" : 7384, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 252, + "points" : "unytGpxqkVA??dACpB@P?f@?p@?j@?dAAhE?jE?vD?P?RK?GFCDCFADABADADAF?D?FADCF?B?B?@?D@DADABCBC?A?C?AA??GICAAAA?A?A?AACAC?A@ABABC@CDCBCBC@CBABABCJ?J?@?@MR?hE?fEAdB?dB?lE?`A?T?pBA|D?J?x@?r@y@??bBuA?y@AU?{@?O?}@?E?y@?_@Aa@?u@?W??J@N?hA@x@Ap@ATETGpJCjEA|CArAAxAAxAAdBEzHClF?@Ax@GTAjBAZ?R@hC@h@Q@cBBM?M?_CDsA@Y?Q@O?K?Q?mBB[?C?W@[?]@E?IDI@]DO@SBM?S@G@A?GDEJQ|@AL?L@nA?j@@L?V?d@@~@@NI?E?W@Q?Q?m@@Q@AF?DAJBzB?V?NANM@K?GBEDEHIJUX_@f@KNQRSVGFCBQPIHGDGBIBK@W@a@?mA@E?C@C@A?CBQTKJEHIJeC~CYZo@v@g@d@IJAFAD?L@vC@hB@p@?X?T@P?N@P@nA?j@AX?L@`B@dA?R?RBbD?T?NBbD?R?P@|D@jB?x@@J?N?B?P?LBjD@N@fD?T?LBdD?R?PF`K?RDlJ?R?PFlJ?J" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:00:00.000+00:00", + "steps" : [ + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 0.69, + "elevation" : "", + "lat" : 45.51932, + "lon" : -122.6485648, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "Southeast 17th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 402.49, + "elevation" : "", + "lat" : 45.5193262, + "lon" : -122.6485648, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Southeast Stark Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : true, + "distance" : 131.76, + "elevation" : "", + "lat" : 45.5193421, + "lon" : -122.6537305, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "path", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 516.5, + "elevation" : "", + "lat" : 45.5200623, + "lon" : -122.6546522, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Southeast Oak Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : true, + "distance" : 70.84, + "elevation" : "", + "lat" : 45.5200842, + "lon" : -122.6612814, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "parking aisle", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 284.75, + "elevation" : "", + "lat" : 45.5203736, + "lon" : -122.661783, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Southeast Martin Luther King, Junior Boulevard", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 243.45, + "elevation" : "", + "lat" : 45.5229343, + "lon" : -122.6617665, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "East Burnside Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 407.38, + "elevation" : "", + "lat" : 45.523001, + "lon" : -122.6648816, + "relativeDirection" : "CONTINUE", + "stayOn" : false, + "streetName" : "Burnside Bridge", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 256.85, + "elevation" : "", + "lat" : 45.5231054, + "lon" : -122.6701087, + "relativeDirection" : "CONTINUE", + "stayOn" : false, + "streetName" : "West Burnside Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 460.65, + "elevation" : "", + "lat" : 45.5231776, + "lon" : -122.6733895, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Northwest 3rd Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 145.82, + "elevation" : "", + "lat" : 45.5272866, + "lon" : -122.6737165, + "relativeDirection" : "SLIGHTLY_LEFT", + "stayOn" : false, + "streetName" : "Northwest Hoyt Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 77.35, + "elevation" : "", + "lat" : 45.5273496, + "lon" : -122.6755629, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Northwest 5th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 80.53, + "elevation" : "", + "lat" : 45.5280449, + "lon" : -122.6755935, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Northwest Irving Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 465.44, + "elevation" : "", + "lat" : 45.5280515, + "lon" : -122.6766232, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Northwest Station Way", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 1331.38, + "elevation" : "", + "lat" : 45.5315452, + "lon" : -122.679511, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Northwest Northrup Street", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T19:03:24.000+00:00", + "lat" : 45.53122, + "lon" : -122.69659, + "name" : "NW Northrup St. & NW 22nd Ave. (P2)", + "vertexType" : "NORMAL" + }, + "transitLeg" : false, + "walkingBike" : false + } + ], + "startTime" : "2009-11-17T18:00:00.000+00:00", + "tooSloped" : false, + "transfers" : 0, + "transitTime" : 0, + "waitingTime" : 0, + "walkDistance" : 4875.79, + "walkLimitExceeded" : false, + "walkTime" : 3804 + }, + { + "arrivedAtDestinationWithRentedBicycle" : false, + "duration" : 1815, + "elevationGained" : 0.0, + "elevationLost" : 0.0, + "endTime" : "2009-11-17T18:34:19.000+00:00", + "fare" : { + "details" : { }, + "fare" : { }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "regular" + } + ] + }, + { + "legIndices" : [ + 5 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "regular" + } + ] + } + ] + }, + "generalizedCost" : 3832, + "legs" : [ + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 673.56, + "endTime" : "2009-11-17T18:12:58.000+00:00", + "from" : { + "departure" : "2009-11-17T18:04:04.000+00:00", + "lat" : 45.51932, + "lon" : -122.648567, + "name" : "SE Stark St. & SE 17th Ave. (P0)", + "vertexType" : "NORMAL" + }, + "generalizedCost" : 1031, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 42, + "points" : "unytGpxqkVA??dACpB@PoC?_CAM?aC??A?A?A?A??AA?AAA??AAA???A?A?A???A@A??@A@?@??A@?@?BcC?mCAmCAmC?QBIYIWOH" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:04:04.000+00:00", + "steps" : [ + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 0.69, + "elevation" : "", + "lat" : 45.51932, + "lon" : -122.6485648, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "Southeast 17th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 79.12, + "elevation" : "", + "lat" : 45.5193262, + "lon" : -122.6485648, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Southeast Stark Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 402.13, + "elevation" : "", + "lat" : 45.5193388, + "lon" : -122.6495798, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Southeast 16th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 168.89, + "elevation" : "", + "lat" : 45.5228912, + "lon" : -122.6495528, + "relativeDirection" : "CONTINUE", + "stayOn" : false, + "streetName" : "Northeast 16th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTHEAST", + "area" : false, + "bogusName" : false, + "distance" : 22.74, + "elevation" : "", + "lat" : 45.524409, + "lon" : -122.6495675, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Northeast Sandy Boulevard", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:12:58.000+00:00", + "departure" : "2009-11-17T18:12:58.000+00:00", + "lat" : 45.524581, + "lon" : -122.649367, + "name" : "NE Sandy & 16th", + "stopCode" : "5060", + "stopId" : "prt:5060", + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyId" : "prt:prt", + "agencyName" : "TriMet", + "agencyTimeZoneOffset" : -28800000, + "agencyUrl" : "http://trimet.org", + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 2119.06, + "endTime" : "2009-11-17T18:19:00.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:12:58.000+00:00", + "departure" : "2009-11-17T18:12:58.000+00:00", + "lat" : 45.524581, + "lon" : -122.649367, + "name" : "NE Sandy & 16th", + "stopCode" : "5060", + "stopId" : "prt:5060", + "stopIndex" : 92, + "stopSequence" : 93, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "generalizedCost" : 962, + "headsign" : "Beaverton TC", + "interlineWithPreviousLeg" : false, + "intermediateStops" : [ + { + "arrival" : "2009-11-17T18:13:32.000+00:00", + "departure" : "2009-11-17T18:13:32.000+00:00", + "lat" : 45.523767, + "lon" : -122.651428, + "name" : "NE Sandy & 14th", + "stopCode" : "5058", + "stopId" : "prt:5058", + "stopIndex" : 93, + "stopSequence" : 94, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:14:00.000+00:00", + "departure" : "2009-11-17T18:14:00.000+00:00", + "lat" : 45.523103, + "lon" : -122.653064, + "name" : "NE Sandy & 12th", + "stopCode" : "5055", + "stopId" : "prt:5055", + "stopIndex" : 94, + "stopSequence" : 95, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:14:47.000+00:00", + "departure" : "2009-11-17T18:14:47.000+00:00", + "lat" : 45.523024, + "lon" : -122.656526, + "name" : "E Burnside & NE 9th", + "stopCode" : "819", + "stopId" : "prt:819", + "stopIndex" : 95, + "stopSequence" : 96, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:15:24.000+00:00", + "departure" : "2009-11-17T18:15:24.000+00:00", + "lat" : 45.523012, + "lon" : -122.659365, + "name" : "E Burnside & NE 6th", + "stopCode" : "805", + "stopId" : "prt:805", + "stopIndex" : 96, + "stopSequence" : 97, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:15:52.000+00:00", + "departure" : "2009-11-17T18:15:52.000+00:00", + "lat" : 45.523015, + "lon" : -122.661534, + "name" : "E Burnside & NE M L King", + "stopCode" : "705", + "stopId" : "prt:705", + "stopIndex" : 97, + "stopSequence" : 98, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:18:00.000+00:00", + "departure" : "2009-11-17T18:18:00.000+00:00", + "lat" : 45.523249, + "lon" : -122.671269, + "name" : "W Burnside & Burnside Bridge", + "stopCode" : "689", + "stopId" : "prt:689", + "stopIndex" : 98, + "stopSequence" : 99, + "vertexType" : "TRANSIT", + "zoneId" : "0" + } + ], + "legGeometry" : { + "length" : 50, + "points" : "coztGd}qkVNl@r@`CZhA`A`D??Ph@l@tBb@rARh@Pd@???BPj@@jA?jEAhE?pD???VAjE?hE?dB?b@???`AAhE?dD???l@C`EAhEEhE?bAA|@?XAZ@\\AzACnGKbKAjC?bE???JEnE@fEDlE@hE@~A" + }, + "mode" : "BUS", + "pathway" : false, + "realTime" : false, + "route" : "Burnside/Stark", + "routeId" : "prt:20", + "routeLongName" : "Burnside/Stark", + "routeShortName" : "20", + "routeType" : 3, + "serviceDate" : "2009-11-17", + "startTime" : "2009-11-17T18:12:58.000+00:00", + "steps" : [ ], + "to" : { + "arrival" : "2009-11-17T18:19:00.000+00:00", + "departure" : "2009-11-17T18:19:00.000+00:00", + "lat" : 45.523169, + "lon" : -122.675893, + "name" : "W Burnside & NW 5th", + "stopCode" : "782", + "stopId" : "prt:782", + "stopIndex" : 99, + "stopSequence" : 100, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + "transitLeg" : true, + "tripBlockId" : "2002", + "tripId" : "prt:200W1200" + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 0.0, + "endTime" : "2009-11-17T18:19:00.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:19:00.000+00:00", + "departure" : "2009-11-17T18:19:00.000+00:00", + "lat" : 45.523169, + "lon" : -122.675893, + "name" : "W Burnside & NW 5th", + "stopCode" : "782", + "stopId" : "prt:782", + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + "generalizedCost" : 1, + "interlineWithPreviousLeg" : false, + "legElevation" : "", + "legGeometry" : { + "length" : 2, + "points" : "wfztGjcwkVD?" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:19:00.000+00:00", + "steps" : [ ], + "to" : { + "arrival" : "2009-11-17T18:19:00.000+00:00", + "departure" : "2009-11-17T18:19:00.000+00:00", + "lat" : 45.5231324, + "lon" : -122.6758917, + "name" : "West Burnside Street", + "vertexType" : "NORMAL" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 1767.93, + "endTime" : "2009-11-17T18:24:16.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:19:00.000+00:00", + "departure" : "2009-11-17T18:19:00.000+00:00", + "lat" : 45.5231324, + "lon" : -122.6758917, + "name" : "West Burnside Street", + "vertexType" : "NORMAL" + }, + "generalizedCost" : 510, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 97, + "points" : "qfztGjcwkV@`B?H?BM?iBBI?K?wBBK?K?sBDM@M@sB@K?K?uBBM?K?uBBI@K?aBBSAM@M@K?GBEDEHIJUX_@f@KNQRSVGFCBQPIHGDGBIBK@W@a@?mA@E?C@C@A?CBQTKJEHIJeC~CYZo@v@g@d@IJAFAD?L@vC@hB@p@?X?T@P?N@P@nA?j@AX?L@`B@dA?R?RBbD?T?NBbD?R?P@|D@jB?x@@J?N?B?P?LBjD@N" + }, + "mode" : "CAR", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:19:00.000+00:00", + "steps" : [ + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 44.21, + "elevation" : "", + "lat" : 45.5231324, + "lon" : -122.6758917, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "West Burnside Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 548.38, + "elevation" : "", + "lat" : 45.5231221, + "lon" : -122.676459, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Northwest 6th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 465.44, + "elevation" : "", + "lat" : 45.5280515, + "lon" : -122.6766232, + "relativeDirection" : "CONTINUE", + "stayOn" : false, + "streetName" : "Northwest Station Way", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 709.95, + "elevation" : "", + "lat" : 45.5315452, + "lon" : -122.679511, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Northwest Northrup Street", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:24:16.000+00:00", + "departure" : "2009-11-17T18:24:16.000+00:00", + "lat" : 45.5313992, + "lon" : -122.6886162, + "name" : "corner of Northwest Northrup Street and path", + "vertexType" : "NORMAL" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 70.46, + "endTime" : "2009-11-17T18:26:18.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:24:16.000+00:00", + "departure" : "2009-11-17T18:24:16.000+00:00", + "lat" : 45.5313992, + "lon" : -122.6886162, + "name" : "corner of Northwest Northrup Street and path", + "vertexType" : "NORMAL" + }, + "generalizedCost" : 233, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 7, + "points" : "ez{tGzrykVC?I?@nBBH?d@??" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:24:16.000+00:00", + "steps" : [ + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : true, + "distance" : 7.61, + "elevation" : "", + "lat" : 45.5313992, + "lon" : -122.6886162, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "path", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 62.85, + "elevation" : "", + "lat" : 45.5314676, + "lon" : -122.6886182, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Northwest Northrup Street", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:26:18.000+00:00", + "departure" : "2009-11-17T18:31:26.000+00:00", + "lat" : 45.531434, + "lon" : -122.689417, + "name" : "NW Northrup & 18th", + "stopCode" : "10776", + "stopId" : "prt:10776", + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyId" : "prt:prt", + "agencyName" : "TriMet", + "agencyTimeZoneOffset" : -28800000, + "agencyUrl" : "http://trimet.org", + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 547.79, + "endTime" : "2009-11-17T18:33:55.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:26:18.000+00:00", + "departure" : "2009-11-17T18:31:26.000+00:00", + "lat" : 45.531434, + "lon" : -122.689417, + "name" : "NW Northrup & 18th", + "stopCode" : "10776", + "stopId" : "prt:10776", + "stopIndex" : 20, + "stopSequence" : 21, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "generalizedCost" : 1057, + "headsign" : "NW 23rd Ave", + "interlineWithPreviousLeg" : false, + "intermediateStops" : [ + { + "arrival" : "2009-11-17T18:33:13.000+00:00", + "departure" : "2009-11-17T18:33:13.000+00:00", + "lat" : 45.531346, + "lon" : -122.694455, + "name" : "NW Northrup & 21st", + "stopCode" : "10777", + "stopId" : "prt:10777", + "stopIndex" : 21, + "stopSequence" : 22, + "vertexType" : "TRANSIT", + "zoneId" : "1" + } + ], + "legGeometry" : { + "length" : 8, + "points" : "cz{tGzwykV?VBhEFtKDvJ??@\\DnJ" + }, + "mode" : "TRAM", + "pathway" : false, + "realTime" : false, + "route" : "Portland Streetcar", + "routeId" : "prt:193", + "routeLongName" : "Portland Streetcar", + "routeType" : 0, + "serviceDate" : "2009-11-17", + "startTime" : "2009-11-17T18:31:26.000+00:00", + "steps" : [ ], + "to" : { + "arrival" : "2009-11-17T18:33:55.000+00:00", + "departure" : "2009-11-17T18:33:55.000+00:00", + "lat" : 45.531308, + "lon" : -122.696445, + "name" : "NW Northrup & 22nd", + "stopCode" : "10778", + "stopId" : "prt:10778", + "stopIndex" : 22, + "stopSequence" : 23, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "transitLeg" : true, + "tripBlockId" : "9384", + "tripId" : "prt:1930W1210" + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 18.81, + "endTime" : "2009-11-17T18:34:19.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:33:55.000+00:00", + "departure" : "2009-11-17T18:33:55.000+00:00", + "lat" : 45.531308, + "lon" : -122.696445, + "name" : "NW Northrup & 22nd", + "stopCode" : "10778", + "stopId" : "prt:10778", + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "generalizedCost" : 37, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 7, + "points" : "sy{tGxc{kV???LABF?B??J" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:33:55.000+00:00", + "steps" : [ + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 18.81, + "elevation" : "", + "lat" : 45.5313019, + "lon" : -122.6964448, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "Northwest Northrup Street", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:34:19.000+00:00", + "lat" : 45.53122, + "lon" : -122.69659, + "name" : "NW Northrup St. & NW 22nd Ave. (P2)", + "vertexType" : "NORMAL" + }, + "transitLeg" : false, + "walkingBike" : false + } + ], + "startTime" : "2009-11-17T18:04:04.000+00:00", + "tooSloped" : false, + "transfers" : 1, + "transitTime" : 511, + "waitingTime" : 308, + "walkDistance" : 2530.76, + "walkLimitExceeded" : false, + "walkTime" : 996 + }, + { + "arrivedAtDestinationWithRentedBicycle" : false, + "duration" : 1598, + "elevationGained" : 0.0, + "elevationLost" : 0.0, + "endTime" : "2009-11-17T18:35:19.000+00:00", + "fare" : { + "details" : { }, + "fare" : { }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "regular" + } + ] + }, + { + "legIndices" : [ + 5 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "regular" + } + ] + } + ] + }, + "generalizedCost" : 3378, + "legs" : [ + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 408.65, + "endTime" : "2009-11-17T18:14:00.000+00:00", + "from" : { + "departure" : "2009-11-17T18:08:41.000+00:00", + "lat" : 45.51932, + "lon" : -122.648567, + "name" : "SE Stark St. & SE 17th Ave. (P0)", + "vertexType" : "NORMAL" + }, + "generalizedCost" : 623, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 16, + "points" : "unytGpxqkVA??dACpB@P?f@?p@?j@?dAAhE?jE?vD?PJ?J@?S" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:08:41.000+00:00", + "steps" : [ + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 0.69, + "elevation" : "", + "lat" : 45.51932, + "lon" : -122.6485648, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "Southeast 17th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 395.42, + "elevation" : "", + "lat" : 45.5193262, + "lon" : -122.6485648, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Southeast Stark Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "SOUTH", + "area" : false, + "bogusName" : false, + "distance" : 12.54, + "elevation" : "", + "lat" : 45.5193421, + "lon" : -122.6536397, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Southeast 12th Avenue", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:14:00.000+00:00", + "departure" : "2009-11-17T18:14:00.000+00:00", + "lat" : 45.519229, + "lon" : -122.653546, + "name" : "SE 12th & Stark", + "stopCode" : "6594", + "stopId" : "prt:6594", + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyId" : "prt:prt", + "agencyName" : "TriMet", + "agencyTimeZoneOffset" : -28800000, + "agencyUrl" : "http://trimet.org", + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 439.45, + "endTime" : "2009-11-17T18:16:00.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:14:00.000+00:00", + "departure" : "2009-11-17T18:14:00.000+00:00", + "lat" : 45.519229, + "lon" : -122.653546, + "name" : "SE 12th & Stark", + "stopCode" : "6594", + "stopId" : "prt:6594", + "stopIndex" : 32, + "stopSequence" : 33, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "generalizedCost" : 720, + "headsign" : "Rose Qtr TC", + "interlineWithPreviousLeg" : false, + "intermediateStops" : [ + { + "arrival" : "2009-11-17T18:14:44.000+00:00", + "departure" : "2009-11-17T18:14:44.000+00:00", + "lat" : 45.520674, + "lon" : -122.653544, + "name" : "SE 12th & Pine", + "stopCode" : "6589", + "stopId" : "prt:6589", + "stopIndex" : 33, + "stopSequence" : 34, + "vertexType" : "TRANSIT", + "zoneId" : "1" + } + ], + "legGeometry" : { + "length" : 11, + "points" : "cnytGdxrkVW?mC?{BA??Q?oC?mC?kBAa@?w@?" + }, + "mode" : "BUS", + "pathway" : false, + "realTime" : false, + "route" : "12th Ave", + "routeId" : "prt:70", + "routeLongName" : "12th Ave", + "routeShortName" : "70", + "routeType" : 3, + "serviceDate" : "2009-11-17", + "startTime" : "2009-11-17T18:14:00.000+00:00", + "steps" : [ ], + "to" : { + "arrival" : "2009-11-17T18:16:00.000+00:00", + "departure" : "2009-11-17T18:16:00.000+00:00", + "lat" : 45.52318, + "lon" : -122.653507, + "name" : "NE 12th & Sandy", + "stopCode" : "6592", + "stopId" : "prt:6592", + "stopIndex" : 34, + "stopSequence" : 35, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "transitLeg" : true, + "tripBlockId" : "7004", + "tripId" : "prt:700W1150" + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 0.0, + "endTime" : "2009-11-17T18:16:00.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:16:00.000+00:00", + "departure" : "2009-11-17T18:16:00.000+00:00", + "lat" : 45.52318, + "lon" : -122.653507, + "name" : "NE 12th & Sandy", + "stopCode" : "6592", + "stopId" : "prt:6592", + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "generalizedCost" : 1, + "interlineWithPreviousLeg" : false, + "legElevation" : "", + "legGeometry" : { + "length" : 2, + "points" : "{fztGlwrkV?V" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:16:00.000+00:00", + "steps" : [ ], + "to" : { + "arrival" : "2009-11-17T18:16:00.000+00:00", + "departure" : "2009-11-17T18:16:00.000+00:00", + "lat" : 45.5231819, + "lon" : -122.6536285, + "name" : "Northeast 12th Avenue", + "vertexType" : "NORMAL" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 1607.0, + "endTime" : "2009-11-17T18:21:03.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:16:00.000+00:00", + "departure" : "2009-11-17T18:16:00.000+00:00", + "lat" : 45.5231819, + "lon" : -122.6536285, + "name" : "Northeast 12th Avenue", + "vertexType" : "NORMAL" + }, + "generalizedCost" : 473, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 81, + "points" : "{fztGdxrkVc@?C?_@AM?O?oBAO??jE?hEAhE?jE?hEAjE?lD?R?FO?]?qA?O?UBmE?k@EU??X?tC?X?P?HAjG?j@ARANCRG\\KFM\\IXCPKXELCJAHMd@?HM\\O`@KPKNKHMLKFIFYJk@P]JIBM@M@O@O?W@O?O?O?q@?Q@K@IBKDIFGFEFGLSFGHEHKZELGP" + }, + "mode" : "CAR", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:16:00.000+00:00", + "steps" : [ + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 128.28, + "elevation" : "", + "lat" : 45.5231819, + "lon" : -122.6536285, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "Northeast 12th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 553.03, + "elevation" : "", + "lat" : 45.5243354, + "lon" : -122.6536083, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Northeast Davis Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 243.39, + "elevation" : "", + "lat" : 45.5243542, + "lon" : -122.6607071, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Northeast Grand Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 542.09, + "elevation" : "", + "lat" : 45.5265408, + "lon" : -122.6606919, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Northeast Lloyd Boulevard", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 140.22, + "elevation" : "", + "lat" : 45.5286604, + "lon" : -122.6657552, + "relativeDirection" : "CONTINUE", + "stayOn" : false, + "streetName" : "North Interstate Avenue", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:21:03.000+00:00", + "departure" : "2009-11-17T18:21:03.000+00:00", + "lat" : 45.5297183, + "lon" : -122.6664542, + "name" : "corner of North Interstate Avenue and path", + "vertexType" : "NORMAL" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 43.34, + "endTime" : "2009-11-17T18:22:49.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:21:03.000+00:00", + "departure" : "2009-11-17T18:21:03.000+00:00", + "lat" : 45.5297183, + "lon" : -122.6664542, + "name" : "corner of North Interstate Avenue and path", + "vertexType" : "NORMAL" + }, + "generalizedCost" : 196, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 13, + "points" : "uo{tGjhukVKIC?CDABCDABEFCHGCEEGK@A" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:21:03.000+00:00", + "steps" : [ + { + "absoluteDirection" : "NORTHEAST", + "area" : false, + "bogusName" : true, + "distance" : 28.77, + "elevation" : "", + "lat" : 45.5297183, + "lon" : -122.6664542, + "relativeDirection" : "SLIGHTLY_RIGHT", + "stayOn" : false, + "streetName" : "path", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTHEAST", + "area" : false, + "bogusName" : false, + "distance" : 14.56, + "elevation" : "", + "lat" : 45.5299086, + "lon" : -122.6665929, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Rose Quarter Transit Center", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:22:49.000+00:00", + "departure" : "2009-11-17T18:25:00.000+00:00", + "lat" : 45.530005, + "lon" : -122.666476, + "name" : "Rose Quarter Transit Center", + "stopCode" : "2592", + "stopId" : "prt:2592", + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyId" : "prt:prt", + "agencyName" : "TriMet", + "agencyTimeZoneOffset" : -28800000, + "agencyUrl" : "http://trimet.org", + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 2905.12, + "endTime" : "2009-11-17T18:34:55.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:22:49.000+00:00", + "departure" : "2009-11-17T18:25:00.000+00:00", + "lat" : 45.530005, + "lon" : -122.666476, + "name" : "Rose Quarter Transit Center", + "stopCode" : "2592", + "stopId" : "prt:2592", + "stopIndex" : 84, + "stopSequence" : 85, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + "generalizedCost" : 1326, + "headsign" : "Montgomery Park", + "interlineWithPreviousLeg" : false, + "intermediateStops" : [ + { + "arrival" : "2009-11-17T18:28:20.000+00:00", + "departure" : "2009-11-17T18:28:20.000+00:00", + "lat" : 45.526655, + "lon" : -122.676462, + "name" : "NW Glisan & 6th", + "stopCode" : "10803", + "stopId" : "prt:10803", + "stopIndex" : 85, + "stopSequence" : 86, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:29:15.000+00:00", + "departure" : "2009-11-17T18:29:15.000+00:00", + "lat" : 45.528799, + "lon" : -122.677238, + "name" : "NW Station Way & Union Station", + "stopCode" : "12801", + "stopId" : "prt:12801", + "stopIndex" : 86, + "stopSequence" : 87, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:31:00.000+00:00", + "departure" : "2009-11-17T18:31:00.000+00:00", + "lat" : 45.531582, + "lon" : -122.681193, + "name" : "NW Northrup & 10th", + "stopCode" : "12802", + "stopId" : "prt:12802", + "stopIndex" : 87, + "stopSequence" : 88, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:31:33.000+00:00", + "departure" : "2009-11-17T18:31:33.000+00:00", + "lat" : 45.531534, + "lon" : -122.683319, + "name" : "NW 12th & Northrup", + "stopCode" : "12796", + "stopId" : "prt:12796", + "stopIndex" : 88, + "stopSequence" : 89, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:32:04.000+00:00", + "departure" : "2009-11-17T18:32:04.000+00:00", + "lat" : 45.531503, + "lon" : -122.685357, + "name" : "NW Northrup & 14th", + "stopCode" : "10775", + "stopId" : "prt:10775", + "stopIndex" : 89, + "stopSequence" : 90, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:33:07.000+00:00", + "departure" : "2009-11-17T18:33:07.000+00:00", + "lat" : 45.531434, + "lon" : -122.689417, + "name" : "NW Northrup & 18th", + "stopCode" : "10776", + "stopId" : "prt:10776", + "stopIndex" : 90, + "stopSequence" : 91, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:34:24.000+00:00", + "departure" : "2009-11-17T18:34:24.000+00:00", + "lat" : 45.531346, + "lon" : -122.694455, + "name" : "NW Northrup & 21st", + "stopCode" : "10777", + "stopId" : "prt:10777", + "stopIndex" : 91, + "stopSequence" : 92, + "vertexType" : "TRANSIT", + "zoneId" : "1" + } + ], + "legGeometry" : { + "length" : 76, + "points" : "eq{tG`hukVNXJPPVJFf@Vf@Pp@Nd@NRLB@RNXZR\\vAhC@BhAhD`AhClAbDBrDCnG@n@@^@d@HdAP`CBjEDvD???LqCFmCDYBGDEBGJkAzAQR??KNa@b@MJuBBY?OHW@u@~@aD`EcBhBBrD@xC??@l@BlE@lD???XBjEBpD???VBlE?dA@t@?b@?h@BfEBrD???VBhEFtKDvJ??@\\DnJ" + }, + "mode" : "BUS", + "pathway" : false, + "realTime" : false, + "route" : "Broadway/Halsey", + "routeId" : "prt:77", + "routeLongName" : "Broadway/Halsey", + "routeShortName" : "77", + "routeType" : 3, + "serviceDate" : "2009-11-17", + "startTime" : "2009-11-17T18:25:00.000+00:00", + "steps" : [ ], + "to" : { + "arrival" : "2009-11-17T18:34:55.000+00:00", + "departure" : "2009-11-17T18:34:55.000+00:00", + "lat" : 45.531308, + "lon" : -122.696445, + "name" : "NW Northrup & 22nd", + "stopCode" : "10778", + "stopId" : "prt:10778", + "stopIndex" : 92, + "stopSequence" : 93, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "transitLeg" : true, + "tripBlockId" : "7736", + "tripId" : "prt:771W1160" + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 18.81, + "endTime" : "2009-11-17T18:35:19.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:34:55.000+00:00", + "departure" : "2009-11-17T18:34:55.000+00:00", + "lat" : 45.531308, + "lon" : -122.696445, + "name" : "NW Northrup & 22nd", + "stopCode" : "10778", + "stopId" : "prt:10778", + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "generalizedCost" : 37, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 7, + "points" : "sy{tGxc{kV???LABF?B??J" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:34:55.000+00:00", + "steps" : [ + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 18.81, + "elevation" : "", + "lat" : 45.5313019, + "lon" : -122.6964448, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "Northwest Northrup Street", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:35:19.000+00:00", + "lat" : 45.53122, + "lon" : -122.69659, + "name" : "NW Northrup St. & NW 22nd Ave. (P2)", + "vertexType" : "NORMAL" + }, + "transitLeg" : false, + "walkingBike" : false + } + ], + "startTime" : "2009-11-17T18:08:41.000+00:00", + "tooSloped" : false, + "transfers" : 1, + "transitTime" : 715, + "waitingTime" : 131, + "walkDistance" : 2077.8, + "walkLimitExceeded" : false, + "walkTime" : 752 + }, + { + "arrivedAtDestinationWithRentedBicycle" : false, + "duration" : 2077, + "elevationGained" : 0.0, + "elevationLost" : 0.0, + "endTime" : "2009-11-17T18:38:41.000+00:00", + "fare" : { + "details" : { }, + "fare" : { }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "regular" + } + ] + } + ] + }, + "generalizedCost" : 3914, + "legs" : [ + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 673.56, + "endTime" : "2009-11-17T18:12:58.000+00:00", + "from" : { + "departure" : "2009-11-17T18:04:04.000+00:00", + "lat" : 45.51932, + "lon" : -122.648567, + "name" : "SE Stark St. & SE 17th Ave. (P0)", + "vertexType" : "NORMAL" + }, + "generalizedCost" : 1031, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 42, + "points" : "unytGpxqkVA??dACpB@PoC?_CAM?aC??A?A?A?A??AA?AAA??AAA???A?A?A???A@A??@A@?@??A@?@?BcC?mCAmCAmC?QBIYIWOH" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:04:04.000+00:00", + "steps" : [ + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 0.69, + "elevation" : "", + "lat" : 45.51932, + "lon" : -122.6485648, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "Southeast 17th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 79.12, + "elevation" : "", + "lat" : 45.5193262, + "lon" : -122.6485648, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Southeast Stark Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 402.13, + "elevation" : "", + "lat" : 45.5193388, + "lon" : -122.6495798, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Southeast 16th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 168.89, + "elevation" : "", + "lat" : 45.5228912, + "lon" : -122.6495528, + "relativeDirection" : "CONTINUE", + "stayOn" : false, + "streetName" : "Northeast 16th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTHEAST", + "area" : false, + "bogusName" : false, + "distance" : 22.74, + "elevation" : "", + "lat" : 45.524409, + "lon" : -122.6495675, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Northeast Sandy Boulevard", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:12:58.000+00:00", + "departure" : "2009-11-17T18:12:58.000+00:00", + "lat" : 45.524581, + "lon" : -122.649367, + "name" : "NE Sandy & 16th", + "stopCode" : "5060", + "stopId" : "prt:5060", + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyId" : "prt:prt", + "agencyName" : "TriMet", + "agencyTimeZoneOffset" : -28800000, + "agencyUrl" : "http://trimet.org", + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 3602.73, + "endTime" : "2009-11-17T18:25:49.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:12:58.000+00:00", + "departure" : "2009-11-17T18:12:58.000+00:00", + "lat" : 45.524581, + "lon" : -122.649367, + "name" : "NE Sandy & 16th", + "stopCode" : "5060", + "stopId" : "prt:5060", + "stopIndex" : 92, + "stopSequence" : 93, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "generalizedCost" : 1371, + "headsign" : "Beaverton TC", + "interlineWithPreviousLeg" : false, + "intermediateStops" : [ + { + "arrival" : "2009-11-17T18:13:32.000+00:00", + "departure" : "2009-11-17T18:13:32.000+00:00", + "lat" : 45.523767, + "lon" : -122.651428, + "name" : "NE Sandy & 14th", + "stopCode" : "5058", + "stopId" : "prt:5058", + "stopIndex" : 93, + "stopSequence" : 94, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:14:00.000+00:00", + "departure" : "2009-11-17T18:14:00.000+00:00", + "lat" : 45.523103, + "lon" : -122.653064, + "name" : "NE Sandy & 12th", + "stopCode" : "5055", + "stopId" : "prt:5055", + "stopIndex" : 94, + "stopSequence" : 95, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:14:47.000+00:00", + "departure" : "2009-11-17T18:14:47.000+00:00", + "lat" : 45.523024, + "lon" : -122.656526, + "name" : "E Burnside & NE 9th", + "stopCode" : "819", + "stopId" : "prt:819", + "stopIndex" : 95, + "stopSequence" : 96, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:15:24.000+00:00", + "departure" : "2009-11-17T18:15:24.000+00:00", + "lat" : 45.523012, + "lon" : -122.659365, + "name" : "E Burnside & NE 6th", + "stopCode" : "805", + "stopId" : "prt:805", + "stopIndex" : 96, + "stopSequence" : 97, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:15:52.000+00:00", + "departure" : "2009-11-17T18:15:52.000+00:00", + "lat" : 45.523015, + "lon" : -122.661534, + "name" : "E Burnside & NE M L King", + "stopCode" : "705", + "stopId" : "prt:705", + "stopIndex" : 97, + "stopSequence" : 98, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:18:00.000+00:00", + "departure" : "2009-11-17T18:18:00.000+00:00", + "lat" : 45.523249, + "lon" : -122.671269, + "name" : "W Burnside & Burnside Bridge", + "stopCode" : "689", + "stopId" : "prt:689", + "stopIndex" : 98, + "stopSequence" : 99, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:19:00.000+00:00", + "departure" : "2009-11-17T18:19:00.000+00:00", + "lat" : 45.523169, + "lon" : -122.675893, + "name" : "W Burnside & NW 5th", + "stopCode" : "782", + "stopId" : "prt:782", + "stopIndex" : 99, + "stopSequence" : 100, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:20:17.000+00:00", + "departure" : "2009-11-17T18:20:17.000+00:00", + "lat" : 45.523115, + "lon" : -122.678939, + "name" : "W Burnside & NW Park", + "stopCode" : "716", + "stopId" : "prt:716", + "stopIndex" : 100, + "stopSequence" : 101, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:21:25.000+00:00", + "departure" : "2009-11-17T18:21:25.000+00:00", + "lat" : 45.523048, + "lon" : -122.681606, + "name" : "W Burnside & NW 10th", + "stopCode" : "10791", + "stopId" : "prt:10791", + "stopIndex" : 101, + "stopSequence" : 102, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:22:14.000+00:00", + "departure" : "2009-11-17T18:22:14.000+00:00", + "lat" : 45.523, + "lon" : -122.683535, + "name" : "W Burnside & NW 12th", + "stopCode" : "11032", + "stopId" : "prt:11032", + "stopIndex" : 102, + "stopSequence" : 103, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:24:09.000+00:00", + "departure" : "2009-11-17T18:24:09.000+00:00", + "lat" : 45.522985, + "lon" : -122.688091, + "name" : "W Burnside & NW 17th", + "stopCode" : "10809", + "stopId" : "prt:10809", + "stopIndex" : 103, + "stopSequence" : 104, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:25:00.000+00:00", + "departure" : "2009-11-17T18:25:00.000+00:00", + "lat" : 45.523097, + "lon" : -122.690083, + "name" : "W Burnside & NW 19th", + "stopCode" : "735", + "stopId" : "prt:735", + "stopIndex" : 104, + "stopSequence" : 105, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:25:21.000+00:00", + "departure" : "2009-11-17T18:25:21.000+00:00", + "lat" : 45.523176, + "lon" : -122.692139, + "name" : "W Burnside & NW 20th", + "stopCode" : "741", + "stopId" : "prt:741", + "stopIndex" : 105, + "stopSequence" : 106, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:25:31.000+00:00", + "departure" : "2009-11-17T18:25:31.000+00:00", + "lat" : 45.52322, + "lon" : -122.69313, + "name" : "W Burnside & NW 20th Pl", + "stopCode" : "742", + "stopId" : "prt:742", + "stopIndex" : 106, + "stopSequence" : 107, + "vertexType" : "TRANSIT", + "zoneId" : "1" + } + ], + "legGeometry" : { + "length" : 94, + "points" : "coztGd}qkVNl@r@`CZhA`A`D??Ph@l@tBb@rARh@Pd@???BPj@@jA?jEAhE?pD???VAjE?hE?dB?b@???`AAhE?dD???l@C`EAhEEhE?bAA|@?XAZ@\\AzACnGKbKAjC?bE???JEnE@fEDlE@hE@~A??@rBBzDBpE@~A???Z@tD@RBnEB|A???@BdB?lEBjA??BnBApF@dB?X?^@r@?f@@bCAx@EtB???VChAE|BGnD??AXKnEGnD???XGjD??AZEfCC`AEzB" + }, + "mode" : "BUS", + "pathway" : false, + "realTime" : false, + "route" : "Burnside/Stark", + "routeId" : "prt:20", + "routeLongName" : "Burnside/Stark", + "routeShortName" : "20", + "routeType" : 3, + "serviceDate" : "2009-11-17", + "startTime" : "2009-11-17T18:12:58.000+00:00", + "steps" : [ ], + "to" : { + "arrival" : "2009-11-17T18:25:49.000+00:00", + "departure" : "2009-11-17T18:25:49.000+00:00", + "lat" : 45.523312, + "lon" : -122.694901, + "name" : "W Burnside & NW King", + "stopCode" : "747", + "stopId" : "prt:747", + "stopIndex" : 107, + "stopSequence" : 108, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "transitLeg" : true, + "tripBlockId" : "2002", + "tripId" : "prt:200W1200" + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 999.1, + "endTime" : "2009-11-17T18:38:41.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:25:49.000+00:00", + "departure" : "2009-11-17T18:25:49.000+00:00", + "lat" : 45.523312, + "lon" : -122.694901, + "name" : "W Burnside & NW King", + "stopCode" : "747", + "stopId" : "prt:747", + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "generalizedCost" : 1511, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 29, + "points" : "ugztGdzzkVL?ATClAI|DK?G?mCBkCDoCDmCBoCDkCBoCB[?sBD]?Y@eA@K?C?K?W@{A@M@C@I?_CB?G" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:25:49.000+00:00", + "steps" : [ + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 113.27, + "elevation" : "", + "lat" : 45.5232491, + "lon" : -122.6949067, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "West Burnside Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 882.16, + "elevation" : "", + "lat" : 45.5233204, + "lon" : -122.696357, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Northwest 22nd Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "EAST", + "area" : false, + "bogusName" : false, + "distance" : 3.68, + "elevation" : "", + "lat" : 45.5312508, + "lon" : -122.6966386, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Northwest Northrup Street", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:38:41.000+00:00", + "lat" : 45.53122, + "lon" : -122.69659, + "name" : "NW Northrup St. & NW 22nd Ave. (P2)", + "vertexType" : "NORMAL" + }, + "transitLeg" : false, + "walkingBike" : false + } + ], + "startTime" : "2009-11-17T18:04:04.000+00:00", + "tooSloped" : false, + "transfers" : 0, + "transitTime" : 771, + "waitingTime" : 0, + "walkDistance" : 1672.66, + "walkLimitExceeded" : false, + "walkTime" : 1306 + }, + { + "arrivedAtDestinationWithRentedBicycle" : false, + "duration" : 1646, + "elevationGained" : 0.0, + "elevationLost" : 0.0, + "endTime" : "2009-11-17T18:39:22.000+00:00", + "fare" : { + "details" : { }, + "fare" : { }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "regular" + } + ] + } + ] + }, + "generalizedCost" : 2662, + "legs" : [ + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 290.72, + "endTime" : "2009-11-17T18:15:40.000+00:00", + "from" : { + "departure" : "2009-11-17T18:11:56.000+00:00", + "lat" : 45.51932, + "lon" : -122.648567, + "name" : "SE Stark St. & SE 17th Ave. (P0)", + "vertexType" : "NORMAL" + }, + "generalizedCost" : 442, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 6, + "points" : "unytGpxqkVjC?lC@nC@?fCG?" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:11:56.000+00:00", + "steps" : [ + { + "absoluteDirection" : "SOUTH", + "area" : false, + "bogusName" : false, + "distance" : 237.26, + "elevation" : "", + "lat" : 45.51932, + "lon" : -122.6485648, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "Southeast 17th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 53.47, + "elevation" : "", + "lat" : 45.5171863, + "lon" : -122.6485801, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Southeast Morrison Street", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:15:40.000+00:00", + "departure" : "2009-11-17T18:15:40.000+00:00", + "lat" : 45.517226, + "lon" : -122.649266, + "name" : "SE Morrison & 16th", + "stopCode" : "4019", + "stopId" : "prt:4019", + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyId" : "prt:prt", + "agencyName" : "TriMet", + "agencyTimeZoneOffset" : -28800000, + "agencyUrl" : "http://trimet.org", + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 5218.86, + "endTime" : "2009-11-17T18:35:54.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:15:40.000+00:00", + "departure" : "2009-11-17T18:15:40.000+00:00", + "lat" : 45.517226, + "lon" : -122.649266, + "name" : "SE Morrison & 16th", + "stopCode" : "4019", + "stopId" : "prt:4019", + "stopIndex" : 50, + "stopSequence" : 51, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "generalizedCost" : 1814, + "headsign" : "Montgomery Park", + "interlineWithPreviousLeg" : false, + "intermediateStops" : [ + { + "arrival" : "2009-11-17T18:16:15.000+00:00", + "departure" : "2009-11-17T18:16:15.000+00:00", + "lat" : 45.517253, + "lon" : -122.651354, + "name" : "SE Morrison & 14th", + "stopCode" : "4016", + "stopId" : "prt:4016", + "stopIndex" : 51, + "stopSequence" : 52, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:17:00.000+00:00", + "departure" : "2009-11-17T18:17:00.000+00:00", + "lat" : 45.517299, + "lon" : -122.654067, + "name" : "SE Morrison & 12th", + "stopCode" : "4014", + "stopId" : "prt:4014", + "stopIndex" : 52, + "stopSequence" : 53, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:17:38.000+00:00", + "departure" : "2009-11-17T18:17:38.000+00:00", + "lat" : 45.517292, + "lon" : -122.656563, + "name" : "SE Morrison & 9th", + "stopCode" : "4026", + "stopId" : "prt:4026", + "stopIndex" : 53, + "stopSequence" : 54, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:18:08.000+00:00", + "departure" : "2009-11-17T18:18:08.000+00:00", + "lat" : 45.517322, + "lon" : -122.65847, + "name" : "SE Morrison & 7th", + "stopCode" : "4025", + "stopId" : "prt:4025", + "stopIndex" : 54, + "stopSequence" : 55, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:18:39.000+00:00", + "departure" : "2009-11-17T18:18:39.000+00:00", + "lat" : 45.517298, + "lon" : -122.660523, + "name" : "SE Morrison & Grand", + "stopCode" : "4013", + "stopId" : "prt:4013", + "stopIndex" : 55, + "stopSequence" : 56, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:20:03.000+00:00", + "departure" : "2009-11-17T18:20:03.000+00:00", + "lat" : 45.517351, + "lon" : -122.66601, + "name" : "Morrison Bridge", + "stopCode" : "4029", + "stopId" : "prt:4029", + "stopIndex" : 56, + "stopSequence" : 57, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:22:27.000+00:00", + "departure" : "2009-11-17T18:22:27.000+00:00", + "lat" : 45.51959, + "lon" : -122.674599, + "name" : "SW Washington & 3rd", + "stopCode" : "6158", + "stopId" : "prt:6158", + "stopIndex" : 57, + "stopSequence" : 58, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:23:00.000+00:00", + "departure" : "2009-11-17T18:23:00.000+00:00", + "lat" : 45.520129, + "lon" : -122.676635, + "name" : "SW Washington & 5th", + "stopCode" : "6160", + "stopId" : "prt:6160", + "stopIndex" : 58, + "stopSequence" : 59, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:23:52.000+00:00", + "departure" : "2009-11-17T18:23:52.000+00:00", + "lat" : 45.520695, + "lon" : -122.678657, + "name" : "SW Washington & Broadway", + "stopCode" : "6137", + "stopId" : "prt:6137", + "stopIndex" : 59, + "stopSequence" : 60, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:24:34.000+00:00", + "departure" : "2009-11-17T18:24:34.000+00:00", + "lat" : 45.521124, + "lon" : -122.6803, + "name" : "SW Washington & 9th", + "stopCode" : "6169", + "stopId" : "prt:6169", + "stopIndex" : 60, + "stopSequence" : 61, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:25:47.000+00:00", + "departure" : "2009-11-17T18:25:47.000+00:00", + "lat" : 45.521094, + "lon" : -122.682819, + "name" : "SW 11th & Alder", + "stopCode" : "9600", + "stopId" : "prt:9600", + "stopIndex" : 61, + "stopSequence" : 62, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:26:36.000+00:00", + "departure" : "2009-11-17T18:26:36.000+00:00", + "lat" : 45.52055, + "lon" : -122.683933, + "name" : "SW Morrison & 12th", + "stopCode" : "9598", + "stopId" : "prt:9598", + "stopIndex" : 62, + "stopSequence" : 63, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + { + "arrival" : "2009-11-17T18:27:25.000+00:00", + "departure" : "2009-11-17T18:27:25.000+00:00", + "lat" : 45.521063, + "lon" : -122.685848, + "name" : "SW Morrison & 14th", + "stopCode" : "9708", + "stopId" : "prt:9708", + "stopIndex" : 63, + "stopSequence" : 64, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:28:18.000+00:00", + "departure" : "2009-11-17T18:28:18.000+00:00", + "lat" : 45.521641, + "lon" : -122.687932, + "name" : "SW Morrison & 16th", + "stopCode" : "9613", + "stopId" : "prt:9613", + "stopIndex" : 64, + "stopSequence" : 65, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:29:00.000+00:00", + "departure" : "2009-11-17T18:29:00.000+00:00", + "lat" : 45.52206, + "lon" : -122.689577, + "name" : "SW Morrison & 17th", + "stopCode" : "9599", + "stopId" : "prt:9599", + "stopIndex" : 65, + "stopSequence" : 66, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:29:54.000+00:00", + "departure" : "2009-11-17T18:29:54.000+00:00", + "lat" : 45.523097, + "lon" : -122.690083, + "name" : "W Burnside & NW 19th", + "stopCode" : "735", + "stopId" : "prt:735", + "stopIndex" : 66, + "stopSequence" : 67, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:30:31.000+00:00", + "departure" : "2009-11-17T18:30:31.000+00:00", + "lat" : 45.523176, + "lon" : -122.692139, + "name" : "W Burnside & NW 20th", + "stopCode" : "741", + "stopId" : "prt:741", + "stopIndex" : 67, + "stopSequence" : 68, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:30:48.000+00:00", + "departure" : "2009-11-17T18:30:48.000+00:00", + "lat" : 45.52322, + "lon" : -122.69313, + "name" : "W Burnside & NW 20th Pl", + "stopCode" : "742", + "stopId" : "prt:742", + "stopIndex" : 68, + "stopSequence" : 69, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:31:20.000+00:00", + "departure" : "2009-11-17T18:31:20.000+00:00", + "lat" : 45.523312, + "lon" : -122.694901, + "name" : "W Burnside & NW King", + "stopCode" : "747", + "stopId" : "prt:747", + "stopIndex" : 69, + "stopSequence" : 70, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:32:18.000+00:00", + "departure" : "2009-11-17T18:32:18.000+00:00", + "lat" : 45.523512, + "lon" : -122.698081, + "name" : "W Burnside & NW 23rd", + "stopCode" : "755", + "stopId" : "prt:755", + "stopIndex" : 70, + "stopSequence" : 71, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:33:11.000+00:00", + "departure" : "2009-11-17T18:33:11.000+00:00", + "lat" : 45.525416, + "lon" : -122.698381, + "name" : "NW 23rd & Flanders", + "stopCode" : "7157", + "stopId" : "prt:7157", + "stopIndex" : 71, + "stopSequence" : 72, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:34:05.000+00:00", + "departure" : "2009-11-17T18:34:05.000+00:00", + "lat" : 45.527543, + "lon" : -122.698473, + "name" : "NW 23rd & Irving", + "stopCode" : "7161", + "stopId" : "prt:7161", + "stopIndex" : 72, + "stopSequence" : 73, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:35:00.000+00:00", + "departure" : "2009-11-17T18:35:00.000+00:00", + "lat" : 45.529681, + "lon" : -122.698529, + "name" : "NW 23rd & Lovejoy", + "stopCode" : "7163", + "stopId" : "prt:7163", + "stopIndex" : 73, + "stopSequence" : 74, + "vertexType" : "TRANSIT", + "zoneId" : "1" + } + ], + "legGeometry" : { + "length" : 135, + "points" : "kaytG||qkVA~@?jE?tC???r@AhE?jE?rA???tBAjE?nD???X?hE?xC??Ah@?pE?~C???J?`@?vAAvBEbE?jEAlE?`BAbB@d@??@tAAj@Cx@Cb@Cp@_@dEcAtFoA`IS~@i@`BmAzDi@zAc@pAi@~C??Id@u@jEm@bD??If@u@jEk@bD??If@u@|DW`B??CPs@|Du@lElBz@??VJbCfAk@dD??Id@w@rEWvAId@AF??Q~@s@`Ei@~C??Ib@u@dEWzA??]jB]MQSe@WOKOKIIQe@GWE]GnD??AXKnEGnD???XGjD??AZEfCC`AEzB??AXCfAGxDE|AEtBIlC??APkAh@o@?sCB{BD??S?mCDmCDyBB??U?mCDmCDyBB??S?oCDmCDmCBo@@" + }, + "mode" : "BUS", + "pathway" : false, + "realTime" : false, + "route" : "Belmont/NW 23rd", + "routeId" : "prt:15", + "routeLongName" : "Belmont/NW 23rd", + "routeShortName" : "15", + "routeType" : 3, + "serviceDate" : "2009-11-17", + "startTime" : "2009-11-17T18:15:40.000+00:00", + "steps" : [ ], + "to" : { + "arrival" : "2009-11-17T18:35:54.000+00:00", + "departure" : "2009-11-17T18:35:54.000+00:00", + "lat" : 45.532159, + "lon" : -122.698634, + "name" : "NW 23rd & Overton", + "stopCode" : "8981", + "stopId" : "prt:8981", + "stopIndex" : 74, + "stopSequence" : 75, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "transitLeg" : true, + "tripBlockId" : "1549", + "tripId" : "prt:150W1400" + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 266.21, + "endTime" : "2009-11-17T18:39:22.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:35:54.000+00:00", + "departure" : "2009-11-17T18:35:54.000+00:00", + "lat" : 45.532159, + "lon" : -122.698634, + "name" : "NW 23rd & Overton", + "stopCode" : "8981", + "stopId" : "prt:8981", + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "generalizedCost" : 405, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 13, + "points" : "}~{tGnq{kV?LVAF?J?L?rBCLA?Q?EAyAEcH?G" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:35:54.000+00:00", + "steps" : [ + { + "absoluteDirection" : "SOUTH", + "area" : false, + "bogusName" : false, + "distance" : 104.46, + "elevation" : "", + "lat" : 45.5321578, + "lon" : -122.6987026, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "Northwest 23rd Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "EAST", + "area" : false, + "bogusName" : false, + "distance" : 161.77, + "elevation" : "", + "lat" : 45.5312188, + "lon" : -122.6986675, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Northwest Northrup Street", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:39:22.000+00:00", + "lat" : 45.53122, + "lon" : -122.69659, + "name" : "NW Northrup St. & NW 22nd Ave. (P2)", + "vertexType" : "NORMAL" + }, + "transitLeg" : false, + "walkingBike" : false + } + ], + "startTime" : "2009-11-17T18:11:56.000+00:00", + "tooSloped" : false, + "transfers" : 0, + "transitTime" : 1214, + "waitingTime" : 0, + "walkDistance" : 556.93, + "walkLimitExceeded" : false, + "walkTime" : 432 + }, + { + "arrivedAtDestinationWithRentedBicycle" : false, + "duration" : 1635, + "elevationGained" : 0.0, + "elevationLost" : 0.0, + "endTime" : "2009-11-17T18:46:19.000+00:00", + "fare" : { + "details" : { }, + "fare" : { }, + "legProducts" : [ + { + "legIndices" : [ + 1 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "regular" + } + ] + }, + { + "legIndices" : [ + 5 + ], + "products" : [ + { + "amount" : { + "cents" : 200, + "currency" : { + "currency" : "USD", + "currencyCode" : "USD", + "defaultFractionDigits" : 2, + "symbol" : "$" + } + }, + "id" : "prt:8", + "name" : "regular" + } + ] + } + ] + }, + "generalizedCost" : 3652, + "legs" : [ + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 673.56, + "endTime" : "2009-11-17T18:27:58.000+00:00", + "from" : { + "departure" : "2009-11-17T18:19:04.000+00:00", + "lat" : 45.51932, + "lon" : -122.648567, + "name" : "SE Stark St. & SE 17th Ave. (P0)", + "vertexType" : "NORMAL" + }, + "generalizedCost" : 1031, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 42, + "points" : "unytGpxqkVA??dACpB@PoC?_CAM?aC??A?A?A?A??AA?AAA??AAA???A?A?A???A@A??@A@?@??A@?@?BcC?mCAmCAmC?QBIYIWOH" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:19:04.000+00:00", + "steps" : [ + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 0.69, + "elevation" : "", + "lat" : 45.51932, + "lon" : -122.6485648, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "Southeast 17th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 79.12, + "elevation" : "", + "lat" : 45.5193262, + "lon" : -122.6485648, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Southeast Stark Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 402.13, + "elevation" : "", + "lat" : 45.5193388, + "lon" : -122.6495798, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Southeast 16th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 168.89, + "elevation" : "", + "lat" : 45.5228912, + "lon" : -122.6495528, + "relativeDirection" : "CONTINUE", + "stayOn" : false, + "streetName" : "Northeast 16th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTHEAST", + "area" : false, + "bogusName" : false, + "distance" : 22.74, + "elevation" : "", + "lat" : 45.524409, + "lon" : -122.6495675, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Northeast Sandy Boulevard", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:27:58.000+00:00", + "departure" : "2009-11-17T18:27:58.000+00:00", + "lat" : 45.524581, + "lon" : -122.649367, + "name" : "NE Sandy & 16th", + "stopCode" : "5060", + "stopId" : "prt:5060", + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyId" : "prt:prt", + "agencyName" : "TriMet", + "agencyTimeZoneOffset" : -28800000, + "agencyUrl" : "http://trimet.org", + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 2119.06, + "endTime" : "2009-11-17T18:34:00.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:27:58.000+00:00", + "departure" : "2009-11-17T18:27:58.000+00:00", + "lat" : 45.524581, + "lon" : -122.649367, + "name" : "NE Sandy & 16th", + "stopCode" : "5060", + "stopId" : "prt:5060", + "stopIndex" : 92, + "stopSequence" : 93, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "generalizedCost" : 962, + "headsign" : "23rd Ave to Tichner", + "interlineWithPreviousLeg" : false, + "intermediateStops" : [ + { + "arrival" : "2009-11-17T18:28:32.000+00:00", + "departure" : "2009-11-17T18:28:32.000+00:00", + "lat" : 45.523767, + "lon" : -122.651428, + "name" : "NE Sandy & 14th", + "stopCode" : "5058", + "stopId" : "prt:5058", + "stopIndex" : 93, + "stopSequence" : 94, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:29:00.000+00:00", + "departure" : "2009-11-17T18:29:00.000+00:00", + "lat" : 45.523103, + "lon" : -122.653064, + "name" : "NE Sandy & 12th", + "stopCode" : "5055", + "stopId" : "prt:5055", + "stopIndex" : 94, + "stopSequence" : 95, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:29:47.000+00:00", + "departure" : "2009-11-17T18:29:47.000+00:00", + "lat" : 45.523024, + "lon" : -122.656526, + "name" : "E Burnside & NE 9th", + "stopCode" : "819", + "stopId" : "prt:819", + "stopIndex" : 95, + "stopSequence" : 96, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:30:24.000+00:00", + "departure" : "2009-11-17T18:30:24.000+00:00", + "lat" : 45.523012, + "lon" : -122.659365, + "name" : "E Burnside & NE 6th", + "stopCode" : "805", + "stopId" : "prt:805", + "stopIndex" : 96, + "stopSequence" : 97, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:30:52.000+00:00", + "departure" : "2009-11-17T18:30:52.000+00:00", + "lat" : 45.523015, + "lon" : -122.661534, + "name" : "E Burnside & NE M L King", + "stopCode" : "705", + "stopId" : "prt:705", + "stopIndex" : 97, + "stopSequence" : 98, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + { + "arrival" : "2009-11-17T18:33:00.000+00:00", + "departure" : "2009-11-17T18:33:00.000+00:00", + "lat" : 45.523249, + "lon" : -122.671269, + "name" : "W Burnside & Burnside Bridge", + "stopCode" : "689", + "stopId" : "prt:689", + "stopIndex" : 98, + "stopSequence" : 99, + "vertexType" : "TRANSIT", + "zoneId" : "0" + } + ], + "legGeometry" : { + "length" : 50, + "points" : "coztGd}qkVNl@r@`CZhA`A`D??Ph@l@tBb@rARh@Pd@???BPj@@jA?jEAhE?pD???VAjE?hE?dB?b@???`AAhE?dD???l@C`EAhEEhE?bAA|@?XAZ@\\AzACnGKbKAjC?bE???JEnE@fEDlE@hE@~A" + }, + "mode" : "BUS", + "pathway" : false, + "realTime" : false, + "route" : "Burnside/Stark", + "routeId" : "prt:20", + "routeLongName" : "Burnside/Stark", + "routeShortName" : "20", + "routeType" : 3, + "serviceDate" : "2009-11-17", + "startTime" : "2009-11-17T18:27:58.000+00:00", + "steps" : [ ], + "to" : { + "arrival" : "2009-11-17T18:34:00.000+00:00", + "departure" : "2009-11-17T18:34:00.000+00:00", + "lat" : 45.523169, + "lon" : -122.675893, + "name" : "W Burnside & NW 5th", + "stopCode" : "782", + "stopId" : "prt:782", + "stopIndex" : 99, + "stopSequence" : 100, + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + "transitLeg" : true, + "tripBlockId" : "2071", + "tripId" : "prt:200W1210" + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 0.0, + "endTime" : "2009-11-17T18:34:00.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:34:00.000+00:00", + "departure" : "2009-11-17T18:34:00.000+00:00", + "lat" : 45.523169, + "lon" : -122.675893, + "name" : "W Burnside & NW 5th", + "stopCode" : "782", + "stopId" : "prt:782", + "vertexType" : "TRANSIT", + "zoneId" : "0" + }, + "generalizedCost" : 1, + "interlineWithPreviousLeg" : false, + "legElevation" : "", + "legGeometry" : { + "length" : 2, + "points" : "wfztGjcwkVD?" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:34:00.000+00:00", + "steps" : [ ], + "to" : { + "arrival" : "2009-11-17T18:34:00.000+00:00", + "departure" : "2009-11-17T18:34:00.000+00:00", + "lat" : 45.5231324, + "lon" : -122.6758917, + "name" : "West Burnside Street", + "vertexType" : "NORMAL" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 1767.93, + "endTime" : "2009-11-17T18:39:16.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:34:00.000+00:00", + "departure" : "2009-11-17T18:34:00.000+00:00", + "lat" : 45.5231324, + "lon" : -122.6758917, + "name" : "West Burnside Street", + "vertexType" : "NORMAL" + }, + "generalizedCost" : 510, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 97, + "points" : "qfztGjcwkV@`B?H?BM?iBBI?K?wBBK?K?sBDM@M@sB@K?K?uBBM?K?uBBI@K?aBBSAM@M@K?GBEDEHIJUX_@f@KNQRSVGFCBQPIHGDGBIBK@W@a@?mA@E?C@C@A?CBQTKJEHIJeC~CYZo@v@g@d@IJAFAD?L@vC@hB@p@?X?T@P?N@P@nA?j@AX?L@`B@dA?R?RBbD?T?NBbD?R?P@|D@jB?x@@J?N?B?P?LBjD@N" + }, + "mode" : "CAR", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:34:00.000+00:00", + "steps" : [ + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 44.21, + "elevation" : "", + "lat" : 45.5231324, + "lon" : -122.6758917, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "West Burnside Street", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 548.38, + "elevation" : "", + "lat" : 45.5231221, + "lon" : -122.676459, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "Northwest 6th Avenue", + "walkingBike" : false + }, + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : false, + "distance" : 465.44, + "elevation" : "", + "lat" : 45.5280515, + "lon" : -122.6766232, + "relativeDirection" : "CONTINUE", + "stayOn" : false, + "streetName" : "Northwest Station Way", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 709.95, + "elevation" : "", + "lat" : 45.5315452, + "lon" : -122.679511, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Northwest Northrup Street", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:39:16.000+00:00", + "departure" : "2009-11-17T18:39:16.000+00:00", + "lat" : 45.5313992, + "lon" : -122.6886162, + "name" : "corner of Northwest Northrup Street and path", + "vertexType" : "NORMAL" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 70.46, + "endTime" : "2009-11-17T18:41:18.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:39:16.000+00:00", + "departure" : "2009-11-17T18:39:16.000+00:00", + "lat" : 45.5313992, + "lon" : -122.6886162, + "name" : "corner of Northwest Northrup Street and path", + "vertexType" : "NORMAL" + }, + "generalizedCost" : 233, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 7, + "points" : "ez{tGzrykVC?I?@nBBH?d@??" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:39:16.000+00:00", + "steps" : [ + { + "absoluteDirection" : "NORTH", + "area" : false, + "bogusName" : true, + "distance" : 7.61, + "elevation" : "", + "lat" : 45.5313992, + "lon" : -122.6886162, + "relativeDirection" : "RIGHT", + "stayOn" : false, + "streetName" : "path", + "walkingBike" : false + }, + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 62.85, + "elevation" : "", + "lat" : 45.5314676, + "lon" : -122.6886182, + "relativeDirection" : "LEFT", + "stayOn" : false, + "streetName" : "Northwest Northrup Street", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:41:18.000+00:00", + "departure" : "2009-11-17T18:43:26.000+00:00", + "lat" : 45.531434, + "lon" : -122.689417, + "name" : "NW Northrup & 18th", + "stopCode" : "10776", + "stopId" : "prt:10776", + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "transitLeg" : false, + "walkingBike" : false + }, + { + "agencyId" : "prt:prt", + "agencyName" : "TriMet", + "agencyTimeZoneOffset" : -28800000, + "agencyUrl" : "http://trimet.org", + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 547.79, + "endTime" : "2009-11-17T18:45:55.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:41:18.000+00:00", + "departure" : "2009-11-17T18:43:26.000+00:00", + "lat" : 45.531434, + "lon" : -122.689417, + "name" : "NW Northrup & 18th", + "stopCode" : "10776", + "stopId" : "prt:10776", + "stopIndex" : 20, + "stopSequence" : 21, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "generalizedCost" : 877, + "headsign" : "NW 23rd Ave", + "interlineWithPreviousLeg" : false, + "intermediateStops" : [ + { + "arrival" : "2009-11-17T18:45:13.000+00:00", + "departure" : "2009-11-17T18:45:13.000+00:00", + "lat" : 45.531346, + "lon" : -122.694455, + "name" : "NW Northrup & 21st", + "stopCode" : "10777", + "stopId" : "prt:10777", + "stopIndex" : 21, + "stopSequence" : 22, + "vertexType" : "TRANSIT", + "zoneId" : "1" + } + ], + "legGeometry" : { + "length" : 8, + "points" : "cz{tGzwykV?VBhEFtKDvJ??@\\DnJ" + }, + "mode" : "TRAM", + "pathway" : false, + "realTime" : false, + "route" : "Portland Streetcar", + "routeId" : "prt:193", + "routeLongName" : "Portland Streetcar", + "routeType" : 0, + "serviceDate" : "2009-11-17", + "startTime" : "2009-11-17T18:43:26.000+00:00", + "steps" : [ ], + "to" : { + "arrival" : "2009-11-17T18:45:55.000+00:00", + "departure" : "2009-11-17T18:45:55.000+00:00", + "lat" : 45.531308, + "lon" : -122.696445, + "name" : "NW Northrup & 22nd", + "stopCode" : "10778", + "stopId" : "prt:10778", + "stopIndex" : 22, + "stopSequence" : 23, + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "transitLeg" : true, + "tripBlockId" : "9385", + "tripId" : "prt:1930W1220" + }, + { + "agencyTimeZoneOffset" : -28800000, + "arrivalDelay" : 0, + "departureDelay" : 0, + "distance" : 18.81, + "endTime" : "2009-11-17T18:46:19.000+00:00", + "from" : { + "arrival" : "2009-11-17T18:45:55.000+00:00", + "departure" : "2009-11-17T18:45:55.000+00:00", + "lat" : 45.531308, + "lon" : -122.696445, + "name" : "NW Northrup & 22nd", + "stopCode" : "10778", + "stopId" : "prt:10778", + "vertexType" : "TRANSIT", + "zoneId" : "1" + }, + "generalizedCost" : 37, + "interlineWithPreviousLeg" : false, + "legGeometry" : { + "length" : 7, + "points" : "sy{tGxc{kV???LABF?B??J" + }, + "mode" : "WALK", + "pathway" : false, + "realTime" : false, + "rentedBike" : false, + "route" : "", + "startTime" : "2009-11-17T18:45:55.000+00:00", + "steps" : [ + { + "absoluteDirection" : "WEST", + "area" : false, + "bogusName" : false, + "distance" : 18.81, + "elevation" : "", + "lat" : 45.5313019, + "lon" : -122.6964448, + "relativeDirection" : "DEPART", + "stayOn" : false, + "streetName" : "Northwest Northrup Street", + "walkingBike" : false + } + ], + "to" : { + "arrival" : "2009-11-17T18:46:19.000+00:00", + "lat" : 45.53122, + "lon" : -122.69659, + "name" : "NW Northrup St. & NW 22nd Ave. (P2)", + "vertexType" : "NORMAL" + }, + "transitLeg" : false, + "walkingBike" : false + } + ], + "startTime" : "2009-11-17T18:19:04.000+00:00", + "tooSloped" : false, + "transfers" : 1, + "transitTime" : 511, + "waitingTime" : 128, + "walkDistance" : 2530.76, + "walkLimitExceeded" : false, + "walkTime" : 996 + } + ] +] \ No newline at end of file diff --git a/application/src/test/java/org/opentripplanner/street/search/state/EdgeTraverserTest.java b/application/src/test/java/org/opentripplanner/street/search/state/EdgeTraverserTest.java new file mode 100644 index 00000000000..a2cd7e61b62 --- /dev/null +++ b/application/src/test/java/org/opentripplanner/street/search/state/EdgeTraverserTest.java @@ -0,0 +1,191 @@ +package org.opentripplanner.street.search.state; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.street.model._data.StreetModelForTest.intersectionVertex; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.function.Function; +import org.junit.jupiter.api.Test; +import org.opentripplanner._support.geometry.Coordinates; +import org.opentripplanner.routing.api.request.StreetMode; +import org.opentripplanner.street.model.StreetTraversalPermission; +import org.opentripplanner.street.model._data.StreetModelForTest; +import org.opentripplanner.street.model.edge.Edge; +import org.opentripplanner.street.model.vertex.IntersectionVertex; +import org.opentripplanner.street.search.TraverseMode; +import org.opentripplanner.street.search.request.StreetSearchRequest; + +class EdgeTraverserTest { + + private static final IntersectionVertex BERLIN_V = intersectionVertex(Coordinates.BERLIN); + private static final IntersectionVertex BRANDENBURG_GATE_V = intersectionVertex( + Coordinates.BERLIN_BRANDENBURG_GATE + ); + private static final IntersectionVertex FERNSEHTURM_V = intersectionVertex( + Coordinates.BERLIN_FERNSEHTURM + ); + private static final IntersectionVertex ADMIRALBRUCKE_V = intersectionVertex( + Coordinates.BERLIN_ADMIRALBRUCKE + ); + + @Test + void emptyEdges() { + var request = StreetSearchRequest + .of() + .withStartTime(Instant.EPOCH) + .withMode(StreetMode.WALK) + .build(); + var initialStates = State.getInitialStates(Set.of(BERLIN_V), request); + var traversedState = EdgeTraverser.traverseEdges(initialStates, List.of()); + + assertSame(initialStates.iterator().next(), traversedState.get()); + } + + @Test + void failedTraversal() { + var edge = StreetModelForTest + .streetEdge(BERLIN_V, BRANDENBURG_GATE_V) + .toBuilder() + .withPermission(StreetTraversalPermission.NONE) + .buildAndConnect(); + + var edges = List.of(edge); + var request = StreetSearchRequest + .of() + .withStartTime(Instant.EPOCH) + .withMode(StreetMode.WALK) + .build(); + var initialStates = State.getInitialStates(Set.of(edge.getFromVertex()), request); + var traversedState = EdgeTraverser.traverseEdges(initialStates, edges); + + assertTrue(traversedState.isEmpty()); + } + + @Test + void withSingleState() { + var edge = StreetModelForTest + .streetEdge(BERLIN_V, BRANDENBURG_GATE_V) + .toBuilder() + .withPermission(StreetTraversalPermission.ALL) + .buildAndConnect(); + + var edges = List.of(edge); + var request = StreetSearchRequest + .of() + .withStartTime(Instant.EPOCH) + .withMode(StreetMode.WALK) + .build(); + var initialStates = State.getInitialStates(Set.of(edge.getFromVertex()), request); + var traversedState = EdgeTraverser.traverseEdges(initialStates, edges).get(); + + assertEquals(List.of(TraverseMode.WALK), stateValues(traversedState, State::getBackMode)); + assertEquals(1719, traversedState.getElapsedTimeSeconds()); + } + + @Test + void withSingleArriveByState() { + var edge = StreetModelForTest + .streetEdge(BERLIN_V, BRANDENBURG_GATE_V) + .toBuilder() + .withPermission(StreetTraversalPermission.ALL) + .buildAndConnect(); + + var edges = List.of(edge); + var request = StreetSearchRequest + .of() + .withStartTime(Instant.EPOCH) + .withMode(StreetMode.WALK) + .withArriveBy(true) + .build(); + var initialStates = State.getInitialStates(Set.of(edge.getToVertex()), request); + var traversedState = EdgeTraverser.traverseEdges(initialStates, edges).get(); + + assertSame(BERLIN_V, traversedState.getVertex()); + assertEquals(List.of(TraverseMode.WALK), stateValues(traversedState, State::getBackMode)); + assertEquals(1719, traversedState.getElapsedTimeSeconds()); + } + + @Test + void withMultipleStates() { + // CAR_PICKUP creates parallel walking and driving states + // This tests that of the two states (WALKING, CAR) the least weight (CAR) is selected + var edge = StreetModelForTest + .streetEdge(BERLIN_V, BRANDENBURG_GATE_V) + .toBuilder() + .withPermission(StreetTraversalPermission.ALL) + .buildAndConnect(); + + var edges = List.of(edge); + var request = StreetSearchRequest + .of() + .withStartTime(Instant.EPOCH) + .withMode(StreetMode.CAR_PICKUP) + .build(); + var initialStates = State.getInitialStates(Set.of(edge.getFromVertex()), request); + var traversedState = EdgeTraverser.traverseEdges(initialStates, edges).get(); + + assertEquals(List.of(TraverseMode.CAR), stateValues(traversedState, State::getBackMode)); + assertEquals(205, traversedState.getElapsedTimeSeconds()); + } + + @Test + void withDominatedStates() { + // CAR_PICKUP creates parallel walking and driving states + // This tests that the most optimal (walking and driving the last stretch) is found after + // discarding the initial driving state for edge1 + var edge1 = StreetModelForTest + .streetEdge(FERNSEHTURM_V, BERLIN_V) + .toBuilder() + .withPermission(StreetTraversalPermission.ALL) + .buildAndConnect(); + var edge2 = StreetModelForTest + .streetEdge(BERLIN_V, BRANDENBURG_GATE_V) + .toBuilder() + .withPermission(StreetTraversalPermission.PEDESTRIAN) + .buildAndConnect(); + var edge3 = StreetModelForTest + .streetEdge(BRANDENBURG_GATE_V, ADMIRALBRUCKE_V) + .toBuilder() + .withPermission(StreetTraversalPermission.ALL) + .buildAndConnect(); + + var edges = List.of(edge1, edge2, edge3); + var request = StreetSearchRequest + .of() + .withStartTime(Instant.EPOCH) + .withMode(StreetMode.CAR_PICKUP) + .build(); + var initialStates = State.getInitialStates(Set.of(edge1.getFromVertex()), request); + var traversedState = EdgeTraverser.traverseEdges(initialStates, edges).get(); + + assertEquals( + List.of(88.103, 2286.029, 3444.28), + stateValues( + traversedState, + state -> state.getBackEdge() != null ? state.getBackEdge().getDistanceMeters() : null + ) + ); + assertEquals( + List.of(TraverseMode.WALK, TraverseMode.WALK, TraverseMode.CAR), + stateValues(traversedState, State::getBackMode) + ); + assertEquals(2169, traversedState.getElapsedTimeSeconds()); + } + + private List stateValues(State state, Function extractor) { + var values = new ArrayList(); + while (state != null) { + var value = extractor.apply(state); + if (value != null) { + values.add(value); + } + state = state.getBackState(); + } + return values.reversed(); + } +} diff --git a/application/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java b/application/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java index 9605d950ae0..7ea56f66145 100644 --- a/application/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java +++ b/application/src/test/java/org/opentripplanner/street/search/state/TestStateBuilder.java @@ -202,7 +202,7 @@ public TestStateBuilder elevator() { currentState = EdgeTraverser - .traverseEdges(currentState, List.of(link, boardEdge, hopEdge, alightEdge)) + .traverseEdges(new State[] { currentState }, List.of(link, boardEdge, hopEdge, alightEdge)) .orElseThrow(); return this; }