From dd394a57c8370dffdb88719f1025ca89c5416a58 Mon Sep 17 00:00:00 2001 From: Cyprien Huissoud Date: Wed, 23 Oct 2024 18:34:46 +0200 Subject: [PATCH] incrementally update generated transfers for new patterns --- .../TransferIndexGenerator.java | 90 +++++++++++++++---- 1 file changed, 73 insertions(+), 17 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferIndexGenerator.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferIndexGenerator.java index 7acddd9cea5..352280458f7 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferIndexGenerator.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/constrainedtransfer/TransferIndexGenerator.java @@ -42,6 +42,10 @@ public class TransferIndexGenerator { private final Map> patternsByRoute = new HashMap<>(); private final Map> patternsByTrip = new HashMap<>(); + private int lastPatternIndex = 0; + private TransferForPatternByStopPos[] prevForwardTransfers = {}; + private TransferForPatternByStopPos[] prevReverseTransfers = {}; + public TransferIndexGenerator( Collection constrainedTransfers, Collection tripPatterns @@ -52,9 +56,22 @@ public TransferIndexGenerator( public ConstrainedTransfersForPatterns generateTransfers() { int nPatterns = RoutingTripPattern.indexCounter(); + + // If no new patterns have been added, return the previously generated transfers + if (lastPatternIndex == nPatterns - 1) { + return new ConstrainedTransfersForPatterns( + Arrays.asList(prevForwardTransfers), + Arrays.asList(prevReverseTransfers) + ); + } + TransferForPatternByStopPos[] forwardTransfers = new TransferForPatternByStopPos[nPatterns]; TransferForPatternByStopPos[] reverseTransfers = new TransferForPatternByStopPos[nPatterns]; + // Copy previously generated transfers + System.arraycopy(prevForwardTransfers, 0, forwardTransfers, 0, prevForwardTransfers.length); + System.arraycopy(prevReverseTransfers, 0, reverseTransfers, 0, prevReverseTransfers.length); + for (ConstrainedTransfer tx : constrainedTransfers) { var c = tx.getTransferConstraint(); // Only add transfers which have an effect on the Raptor routing here. @@ -65,11 +82,13 @@ public ConstrainedTransfersForPatterns generateTransfers() { } try { - findTPoints(tx.getFrom(), ALIGHT) + findTPoints(tx.getFrom(), ALIGHT, false) .stream() .filter(TPoint::canAlight) .forEachOrdered(fromPoint -> { - for (var toPoint : findTPoints(tx.getTo(), BOARD)) { + boolean alightFromPreviouslySeenPattern = + fromPoint.pattern.patternIndex() <= lastPatternIndex; + for (var toPoint : findTPoints(tx.getTo(), BOARD, alightFromPreviouslySeenPattern)) { if (toPoint.canBoard() && !fromPoint.equals(toPoint)) { fromPoint.addTransferConstraints(tx, toPoint, forwardTransfers, reverseTransfers); } @@ -83,6 +102,11 @@ public ConstrainedTransfersForPatterns generateTransfers() { sortTransfers(forwardTransfers); sortTransfers(reverseTransfers); + // Update the last pattern handled index and store the generated transfers + lastPatternIndex = nPatterns - 1; + prevForwardTransfers = forwardTransfers; + prevReverseTransfers = reverseTransfers; + return new ConstrainedTransfersForPatterns( Arrays.asList(forwardTransfers), Arrays.asList(reverseTransfers) @@ -132,21 +156,25 @@ private void sortTransfers(TransferForPatternByStopPos[] transfers) { } } - private Collection findTPoints(TransferPoint txPoint, boolean boarding) { + private Collection findTPoints( + TransferPoint txPoint, + boolean boarding, + boolean onlyNewPatterns + ) { if (txPoint.isStationTransferPoint()) { - return findTPoints(txPoint.asStationTransferPoint()); + return findTPoints(txPoint.asStationTransferPoint(), onlyNewPatterns); } else if (txPoint.isStopTransferPoint()) { - return findTPoints(txPoint.asStopTransferPoint()); + return findTPoints(txPoint.asStopTransferPoint(), onlyNewPatterns); } else if (txPoint.isRouteStationTransferPoint()) { - return findTPoint(txPoint.asRouteStationTransferPoint(), boarding); + return findTPoint(txPoint.asRouteStationTransferPoint(), boarding, onlyNewPatterns); } else if (txPoint.isRouteStopTransferPoint()) { - return findTPoint(txPoint.asRouteStopTransferPoint(), boarding); + return findTPoint(txPoint.asRouteStopTransferPoint(), boarding, onlyNewPatterns); } else { - return findTPoints(txPoint.asTripTransferPoint()); + return findTPoints(txPoint.asTripTransferPoint(), onlyNewPatterns); } } - private List findTPoints(StationTransferPoint point) { + private List findTPoints(StationTransferPoint point, boolean onlyNewPatterns) { var station = point.getStation(); var patterns = patternsByStation.get(station); @@ -158,6 +186,9 @@ private List findTPoints(StationTransferPoint point) { var result = new ArrayList(); for (RoutingTripPattern pattern : patterns) { + if (onlyNewPatterns && pattern.patternIndex() <= lastPatternIndex) { + continue; + } var tripPattern = pattern.getPattern(); for (int pos = 0; pos < tripPattern.numberOfStops(); ++pos) { if (point.getStation() == tripPattern.getStop(pos).getParentStation()) { @@ -168,7 +199,7 @@ private List findTPoints(StationTransferPoint point) { return result; } - private List findTPoints(StopTransferPoint point) { + private List findTPoints(StopTransferPoint point, boolean onlyNewPatterns) { var stop = point.asStopTransferPoint().getStop(); var patterns = patternsByStop.get(stop); @@ -180,6 +211,9 @@ private List findTPoints(StopTransferPoint point) { var result = new ArrayList(); for (RoutingTripPattern pattern : patterns) { + if (onlyNewPatterns && pattern.patternIndex() <= lastPatternIndex) { + continue; + } var p = pattern.getPattern(); for (int pos = 0; pos < p.numberOfStops(); ++pos) { if (point.getStop() == p.getStop(pos)) { @@ -190,27 +224,38 @@ private List findTPoints(StopTransferPoint point) { return result; } - private List findTPoint(RouteStationTransferPoint point, boolean boarding) { + private List findTPoint( + RouteStationTransferPoint point, + boolean boarding, + boolean onlyNewPatterns + ) { return findTPointForRoute( point.getRoute(), boarding ? p -> p.findBoardingStopPositionInPattern(point.getStation()) - : p -> p.findAlightStopPositionInPattern(point.getStation()) + : p -> p.findAlightStopPositionInPattern(point.getStation()), + onlyNewPatterns ); } - private List findTPoint(RouteStopTransferPoint point, boolean boarding) { + private List findTPoint( + RouteStopTransferPoint point, + boolean boarding, + boolean onlyNewPatterns + ) { return findTPointForRoute( point.getRoute(), boarding ? p -> p.findBoardingStopPositionInPattern(point.getStop()) - : p -> p.findAlightStopPositionInPattern(point.getStop()) + : p -> p.findAlightStopPositionInPattern(point.getStop()), + onlyNewPatterns ); } private List findTPointForRoute( Route route, - ToIntFunction resolveStopPosInPattern + ToIntFunction resolveStopPosInPattern, + boolean onlyNewPatterns ) { var patterns = patternsByRoute.get(route); @@ -222,6 +267,9 @@ private List findTPointForRoute( var points = new ArrayList(); for (var pattern : patterns) { + if (onlyNewPatterns && pattern.patternIndex() <= lastPatternIndex) { + continue; + } int stopPosInPattern = resolveStopPosInPattern.applyAsInt(pattern.getPattern()); // stopPosInPattern == -1 means stop is not on pattern if (stopPosInPattern >= 0) { @@ -233,7 +281,7 @@ private List findTPointForRoute( return points; } - private List findTPoints(TripTransferPoint point) { + private List findTPoints(TripTransferPoint point, boolean onlyNewPatterns) { var trip = point.getTrip(); // All trips have at least one pattern, no need to check for null here @@ -263,6 +311,9 @@ private List findTPoints(TripTransferPoint point) { // Return early if only scheduled pattern exists var realtimePatterns = patternsByRealtimeOrScheduled.get(Boolean.TRUE); if (realtimePatterns == null || realtimePatterns.isEmpty()) { + if (onlyNewPatterns && scheduledPattern.patternIndex() <= lastPatternIndex) { + return List.of(); + } return List.of(scheduledPoint); } @@ -270,8 +321,13 @@ private List findTPoints(TripTransferPoint point) { StopLocation scheduledStop = scheduledPattern.getPattern().getStop(stopPosInPattern); List res = new ArrayList<>(); - res.add(scheduledPoint); + if (!onlyNewPatterns || scheduledPattern.patternIndex() > lastPatternIndex) { + res.add(scheduledPoint); + } for (RoutingTripPattern pattern : realtimePatterns) { + if (onlyNewPatterns && pattern.patternIndex() <= lastPatternIndex) { + continue; + } // Check if the same stop or its sibling is at the same position, if yes, generate a transfer point if (stopPosInPattern < pattern.numberOfStopsInPattern()) { StopLocation stop = pattern.getPattern().getStop(stopPosInPattern);