1111
1212import java .util .Arrays ;
1313import java .util .List ;
14+ import java .util .Set ;
1415import org .junit .jupiter .api .Test ;
1516import org .opentripplanner .ext .flex .trip .UnscheduledTrip ;
1617import org .opentripplanner .framework .application .OTPFeature ;
2021import org .opentripplanner .routing .graph .Graph ;
2122import org .opentripplanner .service .vehicleparking .internal .DefaultVehicleParkingRepository ;
2223import org .opentripplanner .street .model ._data .StreetModelForTest ;
24+ import org .opentripplanner .street .model .edge .BoardingLocationToStopLink ;
2325import org .opentripplanner .street .model .edge .Edge ;
2426import org .opentripplanner .street .model .edge .StreetTransitStopLink ;
27+ import org .opentripplanner .street .model .vertex .OsmBoardingLocationVertex ;
2528import org .opentripplanner .street .model .vertex .SplitterVertex ;
2629import org .opentripplanner .street .model .vertex .TransitStopVertex ;
2730import org .opentripplanner .transit .model ._data .TimetableRepositoryForTest ;
@@ -103,6 +106,38 @@ void linkFlexStop() {
103106 });
104107 }
105108
109+ @ Test
110+ void linkFlexStopWithBoardingLocation () {
111+ OTPFeature .FlexRouting .testOn (() -> {
112+ var model = new TestModel ().withStopLinkedToBoardingLocation ();
113+ var flexTrip = TimetableRepositoryForTest .of ().unscheduledTrip ("flex" , model .stop ());
114+ model .withFlexTrip (flexTrip );
115+
116+ var module = model .streetLinkerModule ();
117+
118+ module .buildGraph ();
119+
120+ assertTrue (model .stopVertex ().isConnectedToGraph ());
121+
122+ // stop is used by a flex trip, needs to be linked to both the walk and car edge,
123+ // also linked to the boarding location
124+ assertThat (model .stopVertex ().getOutgoing ()).hasSize (3 );
125+ var links = model .outgoingLinks ();
126+ assertInstanceOf (BoardingLocationToStopLink .class , links .getFirst ());
127+ var linkToWalk = links .get (1 );
128+ SplitterVertex walkSplit = (SplitterVertex ) linkToWalk .getToVertex ();
129+
130+ assertTrue (walkSplit .isConnectedToWalkingEdge ());
131+ assertFalse (walkSplit .isConnectedToDriveableEdge ());
132+
133+ var linkToCar = links .getLast ();
134+ SplitterVertex carSplit = (SplitterVertex ) linkToCar .getToVertex ();
135+
136+ assertFalse (carSplit .isConnectedToWalkingEdge ());
137+ assertTrue (carSplit .isConnectedToDriveableEdge ());
138+ });
139+ }
140+
106141 @ Test
107142 void linkCarsAllowedStop () {
108143 var model = new TestModel ();
@@ -140,6 +175,7 @@ private static class TestModel {
140175 private final StreetLinkerModule module ;
141176 private final RegularStop stop ;
142177 private final TimetableRepository timetableRepository ;
178+ private final Graph graph ;
143179
144180 public TestModel () {
145181 var from = StreetModelForTest .intersectionVertex (
@@ -151,7 +187,7 @@ public TestModel() {
151187 KONGSBERG_PLATFORM_1 .x + DELTA
152188 );
153189
154- Graph graph = new Graph ();
190+ this . graph = new Graph ();
155191 graph .addVertex (from );
156192 graph .addVertex (to );
157193
@@ -232,5 +268,23 @@ public void withCarsAllowedTrip(Trip trip, StopLocation... stops) {
232268
233269 timetableRepository .addTripPattern (tripPattern .getId (), tripPattern );
234270 }
271+
272+ /**
273+ * Links the stop to a boarding location as can happen during regular graph build.
274+ */
275+ public TestModel withStopLinkedToBoardingLocation () {
276+ var boardingLocation = new OsmBoardingLocationVertex (
277+ "boarding-location" ,
278+ KONGSBERG_PLATFORM_1 .x - 0.0001 ,
279+ KONGSBERG_PLATFORM_1 .y - 0.0001 ,
280+ null ,
281+ Set .of (stop .getId ().getId ())
282+ );
283+ graph .addVertex (boardingLocation );
284+
285+ BoardingLocationToStopLink .createBoardingLocationToStopLink (boardingLocation , stopVertex );
286+ BoardingLocationToStopLink .createBoardingLocationToStopLink (stopVertex , boardingLocation );
287+ return this ;
288+ }
235289 }
236290}
0 commit comments