org.opentripplanner.transit.raptor.rangeraptor.standard.StdTransitWorker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of otp Show documentation
Show all versions of otp Show documentation
The OpenTripPlanner multimodal journey planning system
package org.opentripplanner.transit.raptor.rangeraptor.standard;
import org.opentripplanner.transit.raptor.api.transit.RaptorTransfer;
import org.opentripplanner.transit.raptor.api.transit.RaptorTripPattern;
import org.opentripplanner.transit.raptor.api.transit.RaptorTripSchedule;
import org.opentripplanner.transit.raptor.rangeraptor.SlackProvider;
import org.opentripplanner.transit.raptor.rangeraptor.RoutingStrategy;
import org.opentripplanner.transit.raptor.rangeraptor.transit.TransitCalculator;
import org.opentripplanner.transit.raptor.rangeraptor.transit.TripScheduleSearch;
/**
* The purpose of this class is to implement the "Standard" specific functionality of the worker.
*
* @param The TripSchedule type defined by the user of the raptor API.
*/
public final class StdTransitWorker implements RoutingStrategy {
private static final int NOT_SET = -1;
private final StdWorkerState state;
private final TransitCalculator calculator;
private final SlackProvider slackProvider;
private int onTripIndex;
private int onTripBoardTime;
private int onTripBoardStop;
private T onTrip;
private RaptorTripPattern pattern;
private TripScheduleSearch tripSearch;
public StdTransitWorker(
StdWorkerState state,
SlackProvider slackProvider,
TransitCalculator calculator
) {
this.state = state;
this.slackProvider = slackProvider;
this.calculator = calculator;
}
@Override
public void prepareForTransitWith(RaptorTripPattern pattern, TripScheduleSearch tripSearch) {
this.pattern = pattern;
this.tripSearch = tripSearch;
this.onTripIndex = NOT_SET;
this.onTripBoardTime = NOT_SET;
this.onTripBoardStop = NOT_SET;
this.onTrip = null;
this.slackProvider.setCurrentPattern(pattern);
}
@Override
public void routeTransitAtStop(int stopPositionInPattern) {
int stop = pattern.stopIndex(stopPositionInPattern);
// attempt to alight if we're on board, done above the board search so that we don't check
// for alighting when boarding
if (onTripIndex != NOT_SET) {
if (pattern.alightingPossibleAt(stopPositionInPattern)) {
state.transitToStop(
stop,
// In the normal case the trip alightTime is used,
// but in reverse search the board-slack is added; hence the calculator
// delegation
calculator.stopArrivalTime(onTrip,
stopPositionInPattern,
slackProvider.alightSlack()
),
onTripBoardStop,
onTripBoardTime,
onTrip
);
}
}
// Don't attempt to board if this stop was not reached in the last round.
// Allow to reboard the same pattern - a pattern may loop and visit the same stop twice
if (state.isStopReachedInPreviousRound(stop)) {
if (pattern.boardingPossibleAt(stopPositionInPattern)) {
// Calculate the earliest possible board time, adding board slack (alight slack if in
// reverse). The slackProvider takes care of picking the correct board/alight slack.
int earliestBoardTime = calculator.plusDuration(state.bestTimePreviousRound(stop),
slackProvider.boardSlack()
);
// check if we can back up to an earlier trip due to this stop being reached earlier
boolean found = tripSearch.search(earliestBoardTime,
stopPositionInPattern,
onTripIndex
);
if (found) {
onTripIndex = tripSearch.getCandidateTripIndex();
onTrip = tripSearch.getCandidateTrip();
onTripBoardTime = tripSearch.getCandidateTripTime();
onTripBoardStop = stop;
}
}
}
}
@Override
public void setInitialTimeForIteration(RaptorTransfer it, int iterationDepartureTime) {
// Earliest possible departure time from the origin, or latest possible arrival time at the
// destination if searching backwards, using this AccessEgress.
int departureTime = calculator.departureTime(it, iterationDepartureTime);
// This access is not available after the iteration departure time
if (departureTime == -1) return;
state.setInitialTimeForIteration(it, departureTime);
}
}