Skip to content

Commit

Permalink
Add searchWindow for TravelTimeResource
Browse files Browse the repository at this point in the history
  • Loading branch information
hannesj committed Mar 7, 2023
1 parent 50eeeb6 commit ea1530e
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.StreamingOutput;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.Period;
Expand Down Expand Up @@ -72,12 +73,14 @@ public class TravelTimeResource {
private final RaptorService<TripSchedule> raptorService;
private final Graph graph;
private final TransitService transitService;
private final Duration searchWindow;

public TravelTimeResource(
@Context OtpServerRequestContext serverContext,
@QueryParam("location") String location,
@QueryParam("time") String time,
@QueryParam("cutoff") @DefaultValue("60m") List<String> cutoffs,
@QueryParam("searchWindow") @DefaultValue("0s") String searchWindow,
@QueryParam("modes") String modes,
@QueryParam("arriveBy") @DefaultValue("false") boolean arriveBy
) {
Expand Down Expand Up @@ -106,14 +109,15 @@ public TravelTimeResource(
var parsedLocation = LocationStringParser.fromOldStyleString(location);
var requestTime = time != null ? Instant.parse(time) : Instant.now();
routingRequest.setDateTime(requestTime);
this.searchWindow = DurationUtils.duration(searchWindow);

if (routingRequest.arriveBy()) {
startTime = requestTime.minus(traveltimeRequest.maxCutoff);
startTime = requestTime.minus(traveltimeRequest.maxCutoff).minus(this.searchWindow);
endTime = requestTime;
routingRequest.setTo(parsedLocation);
} else {
startTime = requestTime;
endTime = startTime.plus(traveltimeRequest.maxCutoff);
endTime = startTime.plus(traveltimeRequest.maxCutoff).plus(this.searchWindow);
routingRequest.setFrom(parsedLocation);
}

Expand Down Expand Up @@ -246,22 +250,21 @@ private List<State> getInitialStates(
if (!arrivals.reachedByTransit(index)) {
continue;
}
final int arrivalTime = arrivals.bestTransitArrivalTime(index);
Vertex v = graph.getStopVertexForStopId(stop.getId());
if (v == null) {
continue;
}
Instant time = startOfTime.plusSeconds(arrivalTime).toInstant();
int duration = arrivals.bestTransitArrivalDuration(index);
var time = routingRequest.arriveBy()
? endTime.minusSeconds(duration)
: startTime.plusSeconds(duration);
List<StateData> egressStateDatas = StateData.getInitialStateDatas(
egressStreetSearchRequest,
mode -> new TravelTimeStateData(mode, time.getEpochSecond())
);
for (var stopStateData : egressStateDatas) {
State s = new State(v, time, stopStateData, directStreetSearchRequest);
s.weight =
routingRequest.arriveBy()
? time.until(endTime, ChronoUnit.SECONDS)
: startTime.until(time, ChronoUnit.SECONDS);
s.weight = duration;
initialStates.add(s);
}
}
Expand All @@ -276,8 +279,8 @@ private RaptorResponse<TripSchedule> route(Collection<? extends RaptorAccessEgre
.searchParams()
.earliestDepartureTime(ServiceDateUtils.secondsSinceStartOfTime(startOfTime, startTime))
.latestArrivalTime(ServiceDateUtils.secondsSinceStartOfTime(startOfTime, endTime))
.searchOneIterationOnly()
.timetable(false)
.searchWindow(searchWindow)
.timetable(!searchWindow.isZero())
.allowEmptyAccessEgressPaths(true)
.constrainedTransfers(false); // TODO: Not compatible with best times

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ public interface StopArrivals {
@SuppressWarnings("unused")
int bestArrivalTime(int stopIndex);

/**
* The minimum time between the raptor iteration stort time and the arrival at the given stop. If
* the stop is not reached, the behavior is undefined; It may return an arbitrary value or throw
* an exception.
*/
int bestTransitArrivalDuration(int index);

/**
* Returns {@code true} if the stop is reached.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ public interface RaptorWorkerResult<T extends RaptorTripSchedule> {
*/
SingleCriteriaStopArrivals extractBestTransitArrivals();

/**
* Get transit arrival duration for each stop reached in the search.
*/
SingleCriteriaStopArrivals extractBestTransitDurations();

/**
* Extract information about the best number of transfers for each stop arrival.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ public int value(int stop) {
};
}

@Override
public SingleCriteriaStopArrivals extractBestTransitDurations() {
throw new UnsupportedOperationException();
}

@Override
public SingleCriteriaStopArrivals extractBestNumberOfTransfers() {
return new SingleCriteriaStopArrivals() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ public SingleCriteriaStopArrivals extractBestTransitArrivals() {
return bestTimes.extractBestTransitArrivals();
}

@Override
public SingleCriteriaStopArrivals extractBestTransitDurations() {
return bestTimes.extractBestTransitDurations();
}

@Override
public SingleCriteriaStopArrivals extractBestNumberOfTransfers() {
return state.extractBestNumberOfTransfers();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import java.util.BitSet;
import org.opentripplanner.framework.tostring.ToStringBuilder;
import org.opentripplanner.raptor.api.RaptorConstants;
import org.opentripplanner.raptor.rangeraptor.internalapi.SingleCriteriaStopArrivals;
import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle;
import org.opentripplanner.raptor.rangeraptor.support.IntArraySingleCriteriaArrivals;
Expand All @@ -27,6 +28,9 @@
*/
public final class BestTimes {

/** Duration is always positive, and negative is lower so use unreached high value. */
private static final int UNREACHED_DURATION = RaptorConstants.UNREACHED_HIGH;

/** The best times to reach a stop, across rounds and iterations. */
private final int[] times;

Expand All @@ -35,12 +39,17 @@ public final class BestTimes {
* both transit arrivals and access-on-board arrivals.
*/
private final int[] transitArrivalTimes;
/**
* The best duration from the departure time of the raptor round to the arrival at the stop
*/
private final int[] transitArrivalDurations;
private final BitSet reachedByTransitCurrentRound;
private final TransitCalculator<?> calculator;
/** Stops touched in the CURRENT round. */
private BitSet reachedCurrentRound;
/** Stops touched by in LAST round. */
private BitSet reachedLastRound;
private int departureTime;

public BestTimes(int nStops, TransitCalculator<?> calculator, WorkerLifeCycle lifeCycle) {
this.calculator = calculator;
Expand All @@ -49,10 +58,11 @@ public BestTimes(int nStops, TransitCalculator<?> calculator, WorkerLifeCycle li
this.reachedLastRound = new BitSet(nStops);

this.transitArrivalTimes = intArray(nStops, calculator.unreachedTime());
this.transitArrivalDurations = intArray(nStops, UNREACHED_DURATION);
this.reachedByTransitCurrentRound = new BitSet(nStops);

// Attach to Worker life cycle
lifeCycle.onSetupIteration(ignore -> setupIteration());
lifeCycle.onSetupIteration(this::setupIteration);
lifeCycle.onPrepareForNextRound(round -> prepareForNextRound());
}

Expand Down Expand Up @@ -112,6 +122,7 @@ public boolean isStopReachedByTransit(int stop) {
public boolean updateBestTransitArrivalTime(int stop, int time) {
if (isBestTransitArrivalTime(stop, time)) {
setBestTransitTime(stop, time);
setBestTransitDuration(stop, time);
return true;
}
return false;
Expand Down Expand Up @@ -140,6 +151,10 @@ public SingleCriteriaStopArrivals extractBestTransitArrivals() {
return new IntArraySingleCriteriaArrivals(calculator.unreachedTime(), transitArrivalTimes);
}

public SingleCriteriaStopArrivals extractBestTransitDurations() {
return new IntArraySingleCriteriaArrivals(UNREACHED_DURATION, transitArrivalDurations);
}

@Override
public String toString() {
final int unreachedTime = calculator.unreachedTime();
Expand Down Expand Up @@ -171,10 +186,11 @@ boolean isStopReachedInCurrentRound(int stop) {
* Clear all reached flags before we start a new iteration. This is important so stops visited in
* the previous iteration in the last round does not "overflow" into the next iteration.
*/
private void setupIteration() {
private void setupIteration(int departureTime) {
// clear all touched stops to avoid constant reëxploration
reachedCurrentRound.clear();
reachedByTransitCurrentRound.clear();
this.departureTime = departureTime;
}

/**
Expand Down Expand Up @@ -206,6 +222,13 @@ private void setBestTransitTime(int stop, int time) {
reachedByTransitCurrentRound.set(stop);
}

private void setBestTransitDuration(int stop, int time) {
int duration = calculator.duration(departureTime, time);
if (duration < transitArrivalDurations[stop]) {
transitArrivalDurations[stop] = duration;
}
}

private void swapReachedCurrentAndLastRound() {
BitSet tmp = reachedLastRound;
reachedLastRound = reachedCurrentRound;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class DefaultStopArrivals implements StopArrivals {

private SingleCriteriaStopArrivals bestOverallArrivalTime = null;
private SingleCriteriaStopArrivals bestTransitArrivalTime = null;
private SingleCriteriaStopArrivals bestTransitArrivalDuration = null;
private SingleCriteriaStopArrivals bestNumberOfTransfers = null;

private final RaptorWorkerResult<?> results;
Expand Down Expand Up @@ -39,6 +40,11 @@ public int bestTransitArrivalTime(int stopIndex) {
return bestTransitArrivalTime().value(stopIndex);
}

@Override
public int bestTransitArrivalDuration(int stopIndex) {
return bestTransitArrivalDuration().value(stopIndex);
}

@Override
public int smallestNumberOfTransfers(int stopIndex) {
return bestNumberOfTransfers().value(stopIndex);
Expand All @@ -58,6 +64,13 @@ private SingleCriteriaStopArrivals bestTransitArrivalTime() {
return bestTransitArrivalTime;
}

private SingleCriteriaStopArrivals bestTransitArrivalDuration() {
if (bestTransitArrivalDuration == null) {
this.bestTransitArrivalDuration = results.extractBestTransitDurations();
}
return bestTransitArrivalDuration;
}

private SingleCriteriaStopArrivals bestNumberOfTransfers() {
if (bestNumberOfTransfers == null) {
this.bestNumberOfTransfers = results.extractBestNumberOfTransfers();
Expand Down

0 comments on commit ea1530e

Please sign in to comment.