use of org.opentripplanner.routing.edgetype.TripPattern 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;
}
use of org.opentripplanner.routing.edgetype.TripPattern in project OpenTripPlanner by opentripplanner.
the class AlertPatch method apply.
public void apply(Graph graph) {
Agency agency = null;
if (feedId != null) {
Map<String, Agency> agencies = graph.index.agenciesForFeedId.get(feedId);
agency = this.agency != null ? agencies.get(this.agency) : null;
}
Route route = this.route != null ? graph.index.routeForId.get(this.route) : null;
Stop stop = this.stop != null ? graph.index.stopForId.get(this.stop) : null;
Trip trip = this.trip != null ? graph.index.tripForId.get(this.trip) : null;
if (route != null || trip != null || agency != null) {
Collection<TripPattern> tripPatterns = null;
if (trip != null) {
tripPatterns = new LinkedList<>();
TripPattern tripPattern = graph.index.patternForTrip.get(trip);
if (tripPattern != null) {
tripPatterns.add(tripPattern);
}
} else if (route != null) {
tripPatterns = graph.index.patternsForRoute.get(route);
} else {
// Find patterns for the feed.
tripPatterns = graph.index.patternsForFeedId.get(feedId);
}
if (tripPatterns != null) {
for (TripPattern tripPattern : tripPatterns) {
if (direction != null && !direction.equals(tripPattern.getDirection())) {
continue;
}
if (directionId != -1 && directionId == tripPattern.directionId) {
continue;
}
for (int i = 0; i < tripPattern.stopPattern.stops.length; i++) {
if (stop == null || stop.equals(tripPattern.stopPattern.stops[i])) {
graph.addAlertPatch(tripPattern.boardEdges[i], this);
graph.addAlertPatch(tripPattern.alightEdges[i], this);
}
}
}
}
} else if (stop != null) {
TransitStop transitStop = graph.index.stopVertexForStop.get(stop);
for (Edge edge : transitStop.getOutgoing()) {
if (edge instanceof PreBoardEdge) {
graph.addAlertPatch(edge, this);
break;
}
}
for (Edge edge : transitStop.getIncoming()) {
if (edge instanceof PreAlightEdge) {
graph.addAlertPatch(edge, this);
break;
}
}
}
}
use of org.opentripplanner.routing.edgetype.TripPattern in project OpenTripPlanner by opentripplanner.
the class BusRouteStreetMatcher method buildGraph.
/*
The "extra" parameter is a mechanism for passing arbitrary things between graph builder modules.
Whether or not this is a good idea is open to debate, but that's what it is.
An EdgesForRoute instance is generated by MapBuilder and StreetMatcher, then retrieved later by the
NetworkLinkerLibrary later (actually in LinkRequests).
*/
public void buildGraph(Graph graph, HashMap<Class<?>, Object> extra) {
// Mapbuilder needs transit index
graph.index(new DefaultStreetVertexIndexFactory());
StreetMatcher matcher = new StreetMatcher(graph);
EdgesForRoute edgesForRoute = new EdgesForRoute();
extra.put(EdgesForRoute.class, edgesForRoute);
log.info("Finding corresponding street edges for trip patterns...");
// Why do we need to iterate over the routes? Why not just patterns?
for (Route route : graph.index.routeForId.values()) {
for (TripPattern pattern : graph.index.patternsForRoute.get(route)) {
if (pattern.mode == TraverseMode.BUS) {
/* we can only match geometry to streets on bus routes */
log.debug("Matching {}", pattern);
// that is why pattern.geometry is null in that case
if (pattern.geometry == null) {
continue;
}
List<Edge> edges = matcher.match(pattern.geometry);
if (edges == null || edges.isEmpty()) {
log.warn("Could not match to street network: {}", pattern);
continue;
}
List<Coordinate> coordinates = new ArrayList<Coordinate>();
for (Edge e : edges) {
coordinates.addAll(Arrays.asList(e.getGeometry().getCoordinates()));
edgesForRoute.edgesForRoute.put(route, e);
}
Coordinate[] coordinateArray = new Coordinate[coordinates.size()];
LineString ls = GeometryUtils.getGeometryFactory().createLineString(coordinates.toArray(coordinateArray));
// Replace the pattern's geometry from GTFS with that of the equivalent OSM edges.
pattern.geometry = ls;
}
}
}
}
use of org.opentripplanner.routing.edgetype.TripPattern in project OpenTripPlanner by opentripplanner.
the class IndexAPI method getPatternsForStop.
@GET
@Path("/stops/{stopId}/patterns")
public Response getPatternsForStop(@PathParam("stopId") String stopIdString) {
AgencyAndId id = GtfsLibrary.convertIdFromString(stopIdString);
Stop stop = index.stopForId.get(id);
if (stop == null)
return Response.status(Status.NOT_FOUND).entity(MSG_404).build();
Collection<TripPattern> patterns = index.patternsForStop.get(stop);
return Response.status(Status.OK).entity(PatternShort.list(patterns)).build();
}
use of org.opentripplanner.routing.edgetype.TripPattern in project OpenTripPlanner by opentripplanner.
the class IndexAPI method getPatternsForRoute.
/**
* Return all stop patterns used by trips on the given route.
*/
@GET
@Path("/routes/{routeId}/patterns")
public Response getPatternsForRoute(@PathParam("routeId") String routeIdString) {
AgencyAndId routeId = GtfsLibrary.convertIdFromString(routeIdString);
Route route = index.routeForId.get(routeId);
if (route != null) {
Collection<TripPattern> patterns = index.patternsForRoute.get(route);
return Response.status(Status.OK).entity(PatternShort.list(patterns)).build();
} else {
return Response.status(Status.NOT_FOUND).entity(MSG_404).build();
}
}
Aggregations