Skip to content

Commit

Permalink
VGF-64 use drt_advanced_book_max in routing
Browse files Browse the repository at this point in the history
  • Loading branch information
sdjacobs committed Nov 27, 2017
1 parent a109081 commit e7fa912
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 30 deletions.
10 changes: 10 additions & 0 deletions src/main/java/org/opentripplanner/api/common/RoutingResource.java
Expand Up @@ -383,6 +383,11 @@ public abstract class RoutingResource {
@QueryParam("useEligibilityServices")
protected Boolean useEligibilityServices = true;

/**
* Whether to ignore DRT time limits
*/
@QueryParam("ignoreDrtAdvanceBookMin")
protected Boolean ignoreDrtAdvanceBookMin;

@QueryParam("maxHours")
private Double maxHours;
Expand Down Expand Up @@ -450,6 +455,8 @@ protected RoutingRequest buildRequest() throws ParameterException {
} else {
request.setDateTime(date, time, tz);
}

request.resetClockTime();
}

if (wheelchair != null)
Expand Down Expand Up @@ -641,6 +648,9 @@ protected RoutingRequest buildRequest() throws ParameterException {
if (useEligibilityServices != null)
request.useEligibilityServices = useEligibilityServices;

if (ignoreDrtAdvanceBookMin != null)
request.ignoreDrtAdvanceBookMin = ignoreDrtAdvanceBookMin;

if (maxHours != null)
request.maxHours = maxHours;

Expand Down
17 changes: 15 additions & 2 deletions src/main/java/org/opentripplanner/routing/core/RoutingRequest.java
Expand Up @@ -424,6 +424,11 @@ public class RoutingRequest implements Cloneable, Serializable {
*/
public boolean useEligibilityServices = true;

/**
* Whether to ignore DRT time limits
*/
public boolean ignoreDrtAdvanceBookMin = false;

/**
* The routing context used to actually carry out this search. It is important to build States from TraverseOptions
* rather than RoutingContexts,and just keep a reference to the context in the TraverseOptions, rather than using
Expand Down Expand Up @@ -495,6 +500,8 @@ public class RoutingRequest implements Cloneable, Serializable {
*/
private StreetEdge splitEdge = null;

public long clockTimeSec;

/* CONSTRUCTORS */

/** Constructor for options; modes defaults to walk and transit */
Expand Down Expand Up @@ -1011,7 +1018,8 @@ public boolean equals(Object o) {
&& useTraffic == other.useTraffic
&& disableAlertFiltering == other.disableAlertFiltering
&& geoidElevation == other.geoidElevation
&& tripDiscoveryMode == other.tripDiscoveryMode;
&& tripDiscoveryMode == other.tripDiscoveryMode
&& ignoreDrtAdvanceBookMin == other.ignoreDrtAdvanceBookMin;
}

/**
Expand Down Expand Up @@ -1043,7 +1051,8 @@ public int hashCode() {
+ new Boolean(ignoreRealtimeUpdates).hashCode() * 154329
+ new Boolean(disableRemainingWeightHeuristic).hashCode() * 193939
+ new Boolean(useTraffic).hashCode() * 10169
+ new Boolean(tripDiscoveryMode).hashCode() * 209477;
+ new Boolean(tripDiscoveryMode).hashCode() * 209477
+ Boolean.hashCode(ignoreDrtAdvanceBookMin) * 1371;
if (batch) {
hashCode *= -1;
// batch mode, only one of two endpoints matters
Expand Down Expand Up @@ -1288,4 +1297,8 @@ public void canSplitEdge(StreetEdge edge) {
public void setTripDiscoveryMode(boolean tripDiscoveryMode) {
this.tripDiscoveryMode = tripDiscoveryMode;
}

public void resetClockTime() {
this.clockTimeSec = System.currentTimeMillis() / 1000;
}
}
21 changes: 17 additions & 4 deletions src/main/java/org/opentripplanner/routing/edgetype/Timetable.java
Expand Up @@ -244,22 +244,24 @@ public TripTimes getNextCallNRideTrip(State s0, ServiceDay serviceDay, int stopI
TripTimes bestTrip = null;
Stop currentStop = pattern.getStop(stopIndex);
int bestTime = boarding ? Integer.MAX_VALUE : Integer.MIN_VALUE;
boolean useClockTime = !s0.getOptions().ignoreDrtAdvanceBookMin;
long clockTime = s0.getOptions().clockTimeSec;
for (TripTimes tt : tripTimes) {
if (tt.isCanceled()) continue;
if ( ! serviceDay.serviceRunning(tt.serviceCode)) continue; // TODO merge into call on next line
if ( ! tt.tripAcceptable(s0, stopIndex)) continue;
int adjustedTime = adjustTimeForTransfer(s0, currentStop, tt.trip, boarding, serviceDay, time);
if (adjustedTime == -1) continue;
if (boarding) {
int depTime = tt.getCallAndRideBoardTime(stopIndex, adjustedTime);
if (depTime >= adjustedTime && depTime < bestTime) {
int depTime = tt.getCallAndRideBoardTime(stopIndex, adjustedTime, serviceDay, useClockTime, clockTime);
if (depTime >= adjustedTime && depTime < bestTime && inBounds(depTime)) {
bestTrip = tt;
bestTime = depTime;
}
} else {
int arvTime = tt.getCallAndRideAlightTime(stopIndex, adjustedTime, directTime);
int arvTime = tt.getCallAndRideAlightTime(stopIndex, adjustedTime, directTime, serviceDay, useClockTime, clockTime);
if (arvTime < 0) continue;
if (arvTime <= adjustedTime && arvTime > bestTime) {
if (arvTime <= adjustedTime && arvTime > bestTime && inBounds(arvTime)) {
bestTrip = tt;
bestTime = arvTime;
}
Expand All @@ -269,6 +271,9 @@ public TripTimes getNextCallNRideTrip(State s0, ServiceDay serviceDay, int stopI
return bestTrip;
}

private boolean inBounds(int time) {
return time >= minTime && time <= maxTime;
}

/**
* Check transfer table rules. Given the last alight time from the State,
Expand Down Expand Up @@ -627,4 +632,12 @@ public void setServiceCodes (Map<AgencyAndId, Integer> serviceCodes) {
}
}

public int getMaxTime() {
return maxTime;
}

public int getMinTime() {
return minTime;
}

}
Expand Up @@ -36,7 +36,6 @@ the License, or (at your option) any later version.

import com.vividsolutions.jts.geom.LineString;


/**
* Models boarding or alighting a vehicle - that is to say, traveling from a state off
* vehicle to a state on vehicle. When traversed forward on a boarding or backwards on an
Expand Down Expand Up @@ -268,7 +267,12 @@ public State traverse(State s0, long arrivalTimeAtStop) {
TripTimes bestTripTimes = null;
ServiceDay bestServiceDay = null;
for (ServiceDay sd : rctx.serviceDays) {
TripTimes tripTimes = getNextTrip(s0, sd);
/* Find the proper timetable (updated or original) if there is a realtime snapshot. */
Timetable timetable = getPattern().getUpdatedTimetable(options, sd);
/* Skip this day/timetable if no trip in it could possibly be useful. */
if ( ! timetable.temporallyViable(sd, s0.getTimeSeconds(), bestWait, boarding))
continue;
TripTimes tripTimes = getNextTrip(s0, sd, timetable);
if (tripTimes != null) {
/* Wait is relative to departures on board and arrivals on alight. */
int wait = calculateWait(s0, sd, tripTimes);
Expand Down Expand Up @@ -363,16 +367,8 @@ public long getExtraWeight(RoutingRequest options) {
return 0;
}

public TripTimes getNextTrip(State s0, ServiceDay sd) {
RoutingRequest options = s0.getOptions();
Timetable timetable = getPattern().getUpdatedTimetable(options, sd);
/* Skip this day/timetable if no trip in it could possibly be useful. */
// TODO disabled until frequency representation is stable, and min/max timetable times are set from frequencies
// However, experiments seem to show very little measurable improvement here (due to cache locality?)
// if ( ! timetable.temporallyViable(sd, s0.getTimeSeconds(), bestWait, boarding)) continue;
/* Find the next or prev departure depending on final boolean parameter. */
TripTimes tripTimes = timetable.getNextTrip(s0, sd, stopIndex, boarding);
return tripTimes;
public TripTimes getNextTrip(State s0, ServiceDay sd, Timetable timetable) {
return timetable.getNextTrip(s0, sd, stopIndex, boarding);
}

public int calculateWait(State s0, ServiceDay sd, TripTimes tripTimes) {
Expand Down
Expand Up @@ -72,29 +72,31 @@ public State traverse(State s0) {
}

@Override
public TripTimes getNextTrip(State s0, ServiceDay sd) {
public TripTimes getNextTrip(State s0, ServiceDay sd, Timetable timetable) {
if (hop.isUnscheduled()) {
RoutingRequest options = s0.getOptions();
Timetable timetable = getPattern().getUpdatedTimetable(options, sd);
int time = (int) Math.round(hop.timeLowerBound(options));
return timetable.getNextCallNRideTrip(s0, sd, getStopIndex(), boarding, time);
}
double adjustment = boarding ? startIndex : -1 * (1 - endIndex);
RoutingRequest options = s0.getOptions();
Timetable timetable = getPattern().getUpdatedTimetable(options, sd);
TripTimes tripTimes = timetable.getNextTrip(s0, sd, getStopIndex(), boarding, adjustment, hop.getStartVehicleTime(), hop.getEndVehicleTime());
return tripTimes;
return timetable.getNextTrip(s0, sd, getStopIndex(), boarding, adjustment, hop.getStartVehicleTime(), hop.getEndVehicleTime());
}

@Override
public int calculateWait(State s0, ServiceDay sd, TripTimes tripTimes) {
if (hop.isUnscheduled()) {
int currTime = sd.secondsSinceMidnight(s0.getTimeSeconds());
boolean useClockTime = !s0.getOptions().ignoreDrtAdvanceBookMin;
long clockTime = s0.getOptions().clockTimeSec;
if (boarding) {
int scheduledTime = tripTimes.getCallAndRideBoardTime(getStopIndex(), currTime);
int scheduledTime = tripTimes.getCallAndRideBoardTime(getStopIndex(), currTime, sd, useClockTime, clockTime);
if (scheduledTime < 0)
throw new IllegalArgumentException("Unexpected bad wait time");
return (int) (sd.time(scheduledTime) - s0.getTimeSeconds());
} else {
int scheduledTime = tripTimes.getCallAndRideAlightTime(getStopIndex(), currTime, (int) hop.timeLowerBound(s0.getOptions()));
int scheduledTime = tripTimes.getCallAndRideAlightTime(getStopIndex(), currTime, (int) hop.timeLowerBound(s0.getOptions()), sd, useClockTime, clockTime);
if (scheduledTime < 0)
throw new IllegalArgumentException("Unexpected bad wait time");
return (int) (s0.getTimeSeconds() - (sd.time(scheduledTime)));
}
}
Expand Down
Expand Up @@ -18,12 +18,12 @@ the License, or (at your option) any later version.
import java.util.BitSet;
import java.util.List;

import com.vividsolutions.jts.geom.Polygon;
import org.onebusaway.gtfs.model.StopTime;
import org.onebusaway.gtfs.model.Trip;
import org.opentripplanner.common.MavenVersion;
import org.opentripplanner.gtfs.BikeAccess;
import org.opentripplanner.routing.core.RoutingRequest;
import org.opentripplanner.routing.core.ServiceDay;
import org.opentripplanner.routing.core.State;
import org.opentripplanner.routing.core.TraverseMode;
import org.opentripplanner.routing.request.BannedStopSet;
Expand Down Expand Up @@ -325,14 +325,35 @@ public int getDepartureDelay(final int stop) {
return getDepartureTime(stop) - (scheduledDepartureTimes[stop] + timeShift);
}

public int getCallAndRideBoardTime(int stop, long currTime) {
return (int) Math.min(Math.max(currTime, getDepartureTime(stop)), getArrivalTime(stop + 1));
public int getCallAndRideBoardTime(int stop, long currTime, ServiceDay sd, boolean useClockTime, long startClockTime) {
int ret = (int) Math.min(Math.max(currTime, getDepartureTime(stop)), getArrivalTime(stop + 1));
if (useClockTime) {
int clockTime = sd.secondsSinceMidnight(startClockTime) + (trip.getDrtAdvanceBookMin() * 60);
if (ret >= clockTime) {
return ret;
} else if (clockTime < getArrivalTime(stop + 1)) {
return clockTime;
} else {
return -1;
}
}
return ret;
}

public int getCallAndRideAlightTime(int stop, long currTime, int directTime) {
public int getCallAndRideAlightTime(int stop, long currTime, int directTime, ServiceDay sd, boolean useClockTime, long startClockTime) {
int travelTime = getDemandResponseMaxTime(directTime);
currTime -= travelTime;
int startOfService = (int) Math.min(Math.max(currTime, getDepartureTime(stop - 1)), getArrivalTime(stop));
if (useClockTime) {
int clockTime = sd.secondsSinceMidnight(startClockTime) + (trip.getDrtAdvanceBookMin() * 60);
if (startOfService >= clockTime) {
// do nothing
} else if (clockTime < getArrivalTime(stop)) {
startOfService = clockTime;
} else {
return -1;
}
}
return startOfService + travelTime;
}

Expand Down

0 comments on commit e7fa912

Please sign in to comment.