use of org.opentripplanner.analyst.scenario.TripFilter in project OpenTripPlanner by opentripplanner.
the class RaptorWorkerTimetable method forPattern.
/**
* This is a factory function rather than a constructor to avoid calling the super constructor for rejected patterns.
* BannedRoutes is formatted as agencyid_routeid.
*/
public static RaptorWorkerTimetable forPattern(Graph graph, TripPattern pattern, TimeWindow window, Scenario scenario, TaskStatistics ts) {
// Filter down the trips to only those running during the window
// This filtering can reduce number of trips and run time by 80 percent
BitSet servicesRunning = window.servicesRunning;
List<TripTimes> tripTimes = Lists.newArrayList();
TT: for (TripTimes tt : pattern.scheduledTimetable.tripTimes) {
if (servicesRunning.get(tt.serviceCode) && tt.getArrivalTime(0) < window.to && tt.getDepartureTime(tt.getNumStops() - 1) >= window.from) {
// TODO: need to do this before filtering based on window!
if (scenario != null && scenario.modifications != null) {
for (TripFilter filter : Iterables.filter(scenario.modifications, TripFilter.class)) {
tt = filter.apply(tt.trip, pattern, tt);
if (tt == null)
continue TT;
}
}
tripTimes.add(tt);
}
}
// find frequency trips
List<FrequencyEntry> freqs = Lists.newArrayList();
FREQUENCIES: for (FrequencyEntry fe : pattern.scheduledTimetable.frequencyEntries) {
if (servicesRunning.get(fe.tripTimes.serviceCode) && fe.getMinDeparture() < window.to && fe.getMaxArrival() > window.from) {
if (fe.exactTimes) {
LOG.warn("Exact-times frequency trips not yet supported");
continue;
}
if (scenario != null && scenario.modifications != null) {
for (TripFilter filter : Iterables.filter(scenario.modifications, TripFilter.class)) {
fe = filter.apply(fe.tripTimes.trip, pattern, fe);
if (fe == null)
continue FREQUENCIES;
}
}
freqs.add(fe);
}
}
if (tripTimes.isEmpty() && freqs.isEmpty()) {
// no trips active, don't bother storing a timetable
return null;
}
// Sort the trip times by their first arrival time
Collections.sort(tripTimes, new Comparator<TripTimes>() {
@Override
public int compare(TripTimes tt1, TripTimes tt2) {
return (tt1.getArrivalTime(0) - tt2.getArrivalTime(0));
}
});
// Copy the times into the compacted table
RaptorWorkerTimetable rwtt = new RaptorWorkerTimetable(tripTimes.size(), pattern.getStops().size());
int t = 0;
for (TripTimes tt : tripTimes) {
int[] times = new int[rwtt.nStops * 2];
for (int s = 0; s < pattern.getStops().size(); s++) {
int arrival = tt.getArrivalTime(s);
int departure = tt.getDepartureTime(s);
times[s * 2] = arrival;
times[s * 2 + 1] = departure;
}
rwtt.timesPerTrip[t++] = times;
}
ts.scheduledTripCount += rwtt.timesPerTrip.length;
// save frequency times
rwtt.frequencyTrips = new int[freqs.size()][pattern.getStops().size() * 2];
rwtt.endTimes = new int[freqs.size()];
rwtt.startTimes = new int[freqs.size()];
rwtt.headwaySecs = new int[freqs.size()];
{
int i = 0;
for (FrequencyEntry fe : freqs) {
rwtt.headwaySecs[i] = fe.headway;
rwtt.startTimes[i] = fe.startTime;
rwtt.endTimes[i] = fe.endTime;
ts.frequencyTripCount += fe.numTrips();
int[] times = rwtt.frequencyTrips[i];
// It's generally considered good practice to have frequency trips start at midnight, however that is
// not always the case, and we need to preserve the original times so that we can update them in
// real time.
int startTime = fe.tripTimes.getArrivalTime(0);
for (int s = 0; s < fe.tripTimes.getNumStops(); s++) {
times[s * 2] = fe.tripTimes.getArrivalTime(s) - startTime;
times[s * 2 + 1] = fe.tripTimes.getDepartureTime(s) - startTime;
}
i++;
}
}
ts.frequencyEntryCount += rwtt.getFrequencyTripCount();
rwtt.mode = pattern.route.getType();
return rwtt;
}
Aggregations