From ba302b7b0737faa546fa57a81ea6e47d29be610b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 2 Dec 2021 11:27:13 +0100 Subject: [PATCH] Skip to the egress leg when using flex for transit tails --- .../model/OptimizedPathTail.java | 19 ++++++++++++--- .../model/OptimizedPathTailTest.java | 17 ++++++++++++- .../_data/stoparrival/BasicPathTestCase.java | 24 +++++++++++++++++++ 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTail.java b/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTail.java index 30ca1be3d50..c9710ccc567 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTail.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTail.java @@ -85,9 +85,22 @@ public OptimizedPathTail mutate() { /** Start by adding the last transit leg with the egress leg attached. */ public OptimizedPathTail addTransitTail(TransitPathLeg leg) { - egress(leg.nextLeg().asEgressLeg().egress()); - var times = new BoardAndAlightTime(leg.trip(), leg.getFromStopPosition(), leg.getToStopPosition()); - transit(leg.trip(), times); + var next = leg.nextLeg(); + // this could also be a transfer to a flex leg + if(next.isTransferLeg()) { + next = next.nextLeg(); + } + if (next.isEgressLeg()) { + egress(next.asEgressLeg().egress()); + var times = new BoardAndAlightTime( + leg.trip(), + leg.getFromStopPosition(), + leg.getToStopPosition() + ); + transit(leg.trip(), times); + } else { + throw new IllegalStateException("We expect an egress leg at the end of the RAPTOR path."); + } return this; } diff --git a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTailTest.java b/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTailTest.java index a3c04776563..ef4d17e6173 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTailTest.java +++ b/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTailTest.java @@ -15,6 +15,8 @@ class OptimizedPathTailTest implements RaptorTestConstants { private final Path orgPath = BasicPathTestCase.basicTripAsPath(); + private final Path flexPath = BasicPathTestCase.flexTripAsPath(); + private final TransitPathLeg t1 = orgPath.accessLeg().nextTransitLeg(); @SuppressWarnings("ConstantConditions") private final TransitPathLeg t2 = t1.nextTransitLeg(); @@ -61,7 +63,7 @@ void setup() { } @Test - void testToSting() { + void testToString() { subject.addTransitTail(t3); subject.addTransitAndTransferLeg(t2, tx23); subject.addTransitAndTransferLeg(t1, tx12); @@ -78,6 +80,19 @@ void testToSting() { assertEquals(exp, subject.toString()); } + @Test + void shouldHandleATransferAfterLastTransit() { + subject.addTransitTail(flexPath.accessLeg().nextTransitLeg()); + subject.access(orgPath.accessLeg().access()); + + var exp = "Walk 3m15s ~ A " + + "~ BUS L11 10:04 10:35 ~ B " + + "~ Walk 7m45s " + + "[$3318 $0pri $60wtc]"; + + assertEquals(exp, subject.toString()); + } + @Test void testMutate() { diff --git a/src/test/java/org/opentripplanner/transit/raptor/_data/stoparrival/BasicPathTestCase.java b/src/test/java/org/opentripplanner/transit/raptor/_data/stoparrival/BasicPathTestCase.java index 37a15ce62ab..0af48193de1 100644 --- a/src/test/java/org/opentripplanner/transit/raptor/_data/stoparrival/BasicPathTestCase.java +++ b/src/test/java/org/opentripplanner/transit/raptor/_data/stoparrival/BasicPathTestCase.java @@ -10,6 +10,12 @@ import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.Test; +import org.opentripplanner.ext.flex.FlexAccessEgress; +import org.opentripplanner.model.Stop; +import org.opentripplanner.routing.algorithm.GraphRoutingTest; +import org.opentripplanner.routing.algorithm.raptor.transit.FlexAccessEgressAdapter; +import org.opentripplanner.routing.algorithm.raptor.transit.StopIndexForRaptor; +import org.opentripplanner.routing.algorithm.raptor.transit.TransitTuningParameters; import org.opentripplanner.routing.algorithm.raptor.transit.cost.DefaultCostCalculator; import org.opentripplanner.transit.raptor._data.RaptorTestConstants; import org.opentripplanner.transit.raptor._data.transit.TestTransfer; @@ -141,6 +147,8 @@ public class BasicPathTestCase implements RaptorTestConstants { private static final RaptorTransfer ACCESS = walk(STOP_A, ACCESS_DURATION, ACCESS_COST); private static final RaptorTransfer EGRESS = walk(STOP_E, EGRESS_DURATION, EGRESS_COST); + // this is of course not a real flex egress + private static final RaptorTransfer FLEX = walk(STOP_E, EGRESS_DURATION, EGRESS_COST); public static final String LINE_11 = "L11"; public static final String LINE_21 = "L21"; @@ -251,6 +259,22 @@ public static Path basicTripAsPath() { return new Path<>(RAPTOR_ITERATION_START_TIME, leg1, TOTAL_COST); } + public static Path flexTripAsPath() { + PathLeg leg6 = new EgressPathLeg<>( + FLEX, EGRESS_START, EGRESS_END, EGRESS_COST + ); + var transfer = TestTransfer.walk(STOP_C, TX_END - TX_START); + PathLeg leg3 = new TransferPathLeg<>( + STOP_B, TX_START, TX_END, transfer.generalizedCost(), transfer, leg6 + ); + var times2 = BoardAndAlightTime.create(TRIP_1, STOP_A, L11_START, STOP_B, L11_END); + var leg2 = new TransitPathLeg<>(TRIP_1, times2, EMPTY_CONSTRAINTS, LINE_11_COST, leg3); + AccessPathLeg leg1 = new AccessPathLeg<>( + ACCESS, ACCESS_START, ACCESS_END, ACCESS_COST, leg2.asTransitLeg() + ); + return new Path<>(RAPTOR_ITERATION_START_TIME, leg1, TOTAL_COST); + } + public static List basicTripStops() { return Arrays.asList(STOP_A, STOP_B, STOP_C, STOP_D, STOP_E); }