use of org.opentripplanner.index.model.StopTimesInPattern in project OpenTripPlanner by opentripplanner.
the class IndexAPI method getStoptimesForStopAndDate.
/**
* Return upcoming vehicle arrival/departure times at the given stop.
* @param date in YYYYMMDD format
*/
@GET
@Path("/stops/{stopId}/stoptimes/{date}")
public Response getStoptimesForStopAndDate(@PathParam("stopId") String stopIdString, @PathParam("date") String date, @QueryParam("omitNonPickups") boolean omitNonPickups) {
Stop stop = index.stopForId.get(GtfsLibrary.convertIdFromString(stopIdString));
if (stop == null)
return Response.status(Status.NOT_FOUND).entity(MSG_404).build();
ServiceDate sd;
try {
sd = ServiceDate.parseString(date);
} catch (ParseException e) {
return Response.status(Status.BAD_REQUEST).entity(MSG_400).build();
}
List<StopTimesInPattern> ret = index.getStopTimesForStop(stop, sd, omitNonPickups);
return Response.status(Status.OK).entity(ret).build();
}
use of org.opentripplanner.index.model.StopTimesInPattern in project OpenTripPlanner by opentripplanner.
the class GraphIndex method getStopTimesForStop.
/**
* Get a list of all trips that pass through a stop during a single ServiceDate. Useful when creating complete stop
* timetables for a single day.
*
* @param stop Stop object to perform the search for
* @param serviceDate Return all departures for the specified date
* @return
*/
public List<StopTimesInPattern> getStopTimesForStop(Stop stop, ServiceDate serviceDate, boolean omitNonPickups) {
List<StopTimesInPattern> ret = new ArrayList<>();
TimetableSnapshot snapshot = null;
if (graph.timetableSnapshotSource != null) {
snapshot = graph.timetableSnapshotSource.getTimetableSnapshot();
}
Collection<TripPattern> patterns = patternsForStop.get(stop);
for (TripPattern pattern : patterns) {
StopTimesInPattern stopTimes = new StopTimesInPattern(pattern);
Timetable tt;
if (snapshot != null) {
tt = snapshot.resolve(pattern, serviceDate);
} else {
tt = pattern.scheduledTimetable;
}
ServiceDay sd = new ServiceDay(graph, serviceDate, calendarService, pattern.route.getAgency().getId());
int sidx = 0;
for (Stop currStop : pattern.stopPattern.stops) {
if (currStop == stop) {
if (omitNonPickups && pattern.stopPattern.pickups[sidx] == pattern.stopPattern.PICKDROP_NONE)
continue;
for (TripTimes t : tt.tripTimes) {
if (!sd.serviceRunning(t.serviceCode))
continue;
stopTimes.times.add(new TripTimeShort(t, sidx, stop, sd));
}
}
sidx++;
}
ret.add(stopTimes);
}
return ret;
}
use of org.opentripplanner.index.model.StopTimesInPattern in project OpenTripPlanner by opentripplanner.
the class GraphIndex method stopTimesForStop.
/**
* Fetch upcoming vehicle departures from a stop.
* It goes though all patterns passing the stop for the previous, current and next service date.
* It uses a priority queue to keep track of the next departures. The queue is shared between all dates, as services
* from the previous service date can visit the stop later than the current service date's services. This happens
* eg. with sleeper trains.
*
* TODO: Add frequency based trips
* @param stop Stop object to perform the search for
* @param startTime Start time for the search. Seconds from UNIX epoch
* @param timeRange Searches forward for timeRange seconds from startTime
* @param numberOfDepartures Number of departures to fetch per pattern
* @param omitNonPickups If true, do not include vehicles that will not pick up passengers.
* @return
*/
public List<StopTimesInPattern> stopTimesForStop(Stop stop, long startTime, int timeRange, int numberOfDepartures, boolean omitNonPickups) {
if (startTime == 0) {
startTime = System.currentTimeMillis() / 1000;
}
List<StopTimesInPattern> ret = new ArrayList<>();
TimetableSnapshot snapshot = null;
if (graph.timetableSnapshotSource != null) {
snapshot = graph.timetableSnapshotSource.getTimetableSnapshot();
}
Date date = new Date(startTime * 1000);
ServiceDate[] serviceDates = { new ServiceDate(date).previous(), new ServiceDate(date), new ServiceDate(date).next() };
for (TripPattern pattern : patternsForStop.get(stop)) {
// Use the Lucene PriorityQueue, which has a fixed size
PriorityQueue<TripTimeShort> pq = new PriorityQueue<TripTimeShort>(numberOfDepartures) {
@Override
protected boolean lessThan(TripTimeShort tripTimeShort, TripTimeShort t1) {
// Calculate exact timestamp
return (tripTimeShort.serviceDay + tripTimeShort.realtimeDeparture) > (t1.serviceDay + t1.realtimeDeparture);
}
};
// Loop through all possible days
for (ServiceDate serviceDate : serviceDates) {
ServiceDay sd = new ServiceDay(graph, serviceDate, calendarService, pattern.route.getAgency().getId());
Timetable tt;
if (snapshot != null) {
tt = snapshot.resolve(pattern, serviceDate);
} else {
tt = pattern.scheduledTimetable;
}
if (!tt.temporallyViable(sd, startTime, timeRange, true))
continue;
int secondsSinceMidnight = sd.secondsSinceMidnight(startTime);
int sidx = 0;
for (Stop currStop : pattern.stopPattern.stops) {
if (currStop == stop) {
if (omitNonPickups && pattern.stopPattern.pickups[sidx] == pattern.stopPattern.PICKDROP_NONE)
continue;
for (TripTimes t : tt.tripTimes) {
if (!sd.serviceRunning(t.serviceCode))
continue;
if (t.getDepartureTime(sidx) != -1 && t.getDepartureTime(sidx) >= secondsSinceMidnight) {
pq.insertWithOverflow(new TripTimeShort(t, sidx, stop, sd));
}
}
// TODO: This needs to be adapted after #1647 is merged
for (FrequencyEntry freq : tt.frequencyEntries) {
if (!sd.serviceRunning(freq.tripTimes.serviceCode))
continue;
int departureTime = freq.nextDepartureTime(sidx, secondsSinceMidnight);
if (departureTime == -1)
continue;
int lastDeparture = freq.endTime + freq.tripTimes.getArrivalTime(sidx) - freq.tripTimes.getDepartureTime(0);
int i = 0;
while (departureTime <= lastDeparture && i < numberOfDepartures) {
pq.insertWithOverflow(new TripTimeShort(freq.materialize(sidx, departureTime, true), sidx, stop, sd));
departureTime += freq.headway;
i++;
}
}
}
sidx++;
}
}
if (pq.size() != 0) {
StopTimesInPattern stopTimes = new StopTimesInPattern(pattern);
while (pq.size() != 0) {
stopTimes.times.add(0, pq.pop());
}
ret.add(stopTimes);
}
}
return ret;
}
Aggregations