use of org.opentripplanner.model.TripPattern in project OpenTripPlanner by opentripplanner.
the class TransitLayerMapper method mapTripPatterns.
/**
* Map pre-Raptor TripPatterns and Trips to the corresponding Raptor classes.
* <p>
* Part of this method runs IN PARALLEL.
* <p>
*/
private HashMap<LocalDate, List<TripPatternForDate>> mapTripPatterns(StopIndexForRaptor stopIndex) {
Collection<TripPattern> allTripPatterns = graph.tripPatternForId.values();
final Map<TripPattern, TripPatternWithRaptorStopIndexes> newTripPatternForOld = mapOldTripPatternToRaptorTripPattern(stopIndex, allTripPatterns);
TripPatternForDateMapper tripPatternForDateMapper = new TripPatternForDateMapper(graph.index.getServiceCodesRunningForDate(), newTripPatternForOld);
Set<ServiceDate> allServiceDates = graph.index.getServiceCodesRunningForDate().keySet();
// The return value of this entire process.
ConcurrentHashMap<LocalDate, List<TripPatternForDate>> result = new ConcurrentHashMap<>();
// THIS CODE RUNS IN PARALLEL
allServiceDates.parallelStream().forEach(serviceDate -> {
// Create LocalDate equivalent to the OTP/GTFS ServiceDate object, serving as the key of
// the return Map.
LocalDate localDate = ServiceCalendarMapper.localDateFromServiceDate(serviceDate);
// Create a List to hold the values for one entry in the return Map.
List<TripPatternForDate> values = new ArrayList<>();
// Maybe determine in advance which patterns are running on each service and day.
for (org.opentripplanner.model.TripPattern oldTripPattern : allTripPatterns) {
TripPatternForDate tripPatternForDate = tripPatternForDateMapper.map(oldTripPattern.scheduledTimetable, serviceDate);
if (tripPatternForDate != null) {
values.add(tripPatternForDate);
}
}
if (!values.isEmpty()) {
result.put(localDate, values);
}
});
return new HashMap<>(result);
}
use of org.opentripplanner.model.TripPattern in project OpenTripPlanner by opentripplanner.
the class Graph method index.
/**
* Perform indexing on vertices, edges, and timetables, and create transient data structures.
* This used to be done in readObject methods upon deserialization, but stand-alone mode now
* allows passing graphs from graphbuilder to server in memory, without a round trip through
* serialization.
* TODO: do we really need a factory for different street vertex indexes?
*/
public void index() {
LOG.info("Index graph...");
streetIndex = new StreetVertexIndex(this);
LOG.debug("Rebuilding edge and vertex indices.");
for (TripPattern tp : tripPatternForId.values()) {
// Skip frequency-based patterns which have no timetable (null)
if (tp != null)
tp.scheduledTimetable.finish();
}
// TODO: Move this ^ stuff into the graph index
this.index = new GraphIndex(this);
LOG.info("Index graph complete.");
}
use of org.opentripplanner.model.TripPattern in project OpenTripPlanner by opentripplanner.
the class TimetableSnapshotSource method addTripToGraphAndBuffer.
/**
* Add a (new) trip to the graph and the buffer
*
* @param graph graph
* @param trip trip
* @param tripUpdate trip update containing stop time updates
* @param stops list of stops corresponding to stop time updates
* @param serviceDate service date of trip
* @param realTimeState real-time state of new trip
* @return true iff successful
*/
private boolean addTripToGraphAndBuffer(final String feedId, final Graph graph, final Trip trip, final TripUpdate tripUpdate, final List<Stop> stops, final ServiceDate serviceDate, final RealTimeState realTimeState) {
// Preconditions
Preconditions.checkNotNull(stops);
Preconditions.checkArgument(tripUpdate.getStopTimeUpdateCount() == stops.size(), "number of stop should match the number of stop time updates");
// Calculate seconds since epoch on GTFS midnight (noon minus 12h) of service date
final Calendar serviceCalendar = serviceDate.getAsCalendar(timeZone);
final long midnightSecondsSinceEpoch = serviceCalendar.getTimeInMillis() / MILLIS_PER_SECOND;
// Create StopTimes
final List<StopTime> stopTimes = new ArrayList<>(tripUpdate.getStopTimeUpdateCount());
for (int index = 0; index < tripUpdate.getStopTimeUpdateCount(); ++index) {
final StopTimeUpdate stopTimeUpdate = tripUpdate.getStopTimeUpdate(index);
final Stop stop = stops.get(index);
// Determine whether stop is skipped
final boolean skippedStop = isStopSkipped(stopTimeUpdate);
// Only create stop time for non-skipped stops
if (!skippedStop) {
// Create stop time
final StopTime stopTime = new StopTime();
stopTime.setTrip(trip);
stopTime.setStop(stop);
// Set arrival time
if (stopTimeUpdate.hasArrival() && stopTimeUpdate.getArrival().hasTime()) {
final long arrivalTime = stopTimeUpdate.getArrival().getTime() - midnightSecondsSinceEpoch;
if (arrivalTime < 0 || arrivalTime > MAX_ARRIVAL_DEPARTURE_TIME) {
LOG.warn("ADDED trip has invalid arrival time (compared to start date in " + "TripDescriptor), skipping.");
return false;
}
stopTime.setArrivalTime((int) arrivalTime);
}
// Set departure time
if (stopTimeUpdate.hasDeparture() && stopTimeUpdate.getDeparture().hasTime()) {
final long departureTime = stopTimeUpdate.getDeparture().getTime() - midnightSecondsSinceEpoch;
if (departureTime < 0 || departureTime > MAX_ARRIVAL_DEPARTURE_TIME) {
LOG.warn("ADDED trip has invalid departure time (compared to start date in " + "TripDescriptor), skipping.");
return false;
}
stopTime.setDepartureTime((int) departureTime);
}
// Exact time
stopTime.setTimepoint(1);
if (stopTimeUpdate.hasStopSequence()) {
stopTime.setStopSequence(stopTimeUpdate.getStopSequence());
}
// Set different pickup type for last stop
if (index == tripUpdate.getStopTimeUpdateCount() - 1) {
// No pickup available
stopTime.setPickupType(1);
} else {
// Regularly scheduled pickup
stopTime.setPickupType(0);
}
// Set different drop off type for first stop
if (index == 0) {
// No drop off available
stopTime.setDropOffType(1);
} else {
// Regularly scheduled drop off
stopTime.setDropOffType(0);
}
// Add stop time to list
stopTimes.add(stopTime);
}
}
// TODO: filter/interpolate stop times like in PatternHopFactory?
// Create StopPattern
final StopPattern stopPattern = new StopPattern(stopTimes);
// Get cached trip pattern or create one if it doesn't exist yet
final TripPattern pattern = tripPatternCache.getOrCreateTripPattern(stopPattern, trip, graph);
// Add service code to bitset of pattern if needed (using copy on write)
final int serviceCode = graph.getServiceCodes().get(trip.getServiceId());
if (!pattern.getServices().get(serviceCode)) {
final BitSet services = (BitSet) pattern.getServices().clone();
services.set(serviceCode);
pattern.setServices(services);
}
// Create new trip times
final TripTimes newTripTimes = new TripTimes(trip, stopTimes, graph.deduplicator);
// TODO: should we incorporate the delay field if present?
for (int stopIndex = 0; stopIndex < newTripTimes.getNumStops(); stopIndex++) {
newTripTimes.updateArrivalTime(stopIndex, newTripTimes.getScheduledArrivalTime(stopIndex));
newTripTimes.updateDepartureTime(stopIndex, newTripTimes.getScheduledDepartureTime(stopIndex));
}
// Set service code of new trip times
newTripTimes.serviceCode = serviceCode;
// Make sure that updated trip times have the correct real time state
newTripTimes.setRealTimeState(realTimeState);
// Add new trip times to the buffer
final boolean success = buffer.update(pattern, newTripTimes, serviceDate);
return success;
}
use of org.opentripplanner.model.TripPattern in project OpenTripPlanner by opentripplanner.
the class TimetableSnapshotSource method cancelPreviouslyAddedTrip.
/**
* Cancel previously added trip from buffer if there is a previously added trip with given trip
* id (without agency id) on service date. This does not remove the modified/added trip from the buffer, it just
* marks it as canceled. This also does not remove the corresponding vertices and edges from the Graph. Any
* TripPattern that was created for the added/modified trip continues to exist, and will be reused if a similar
* added/modified trip message is received with the same route and stop sequence.
*
* @param tripId trip id without agency id
* @param serviceDate service date
* @return true if a previously added trip was cancelled
*/
private boolean cancelPreviouslyAddedTrip(FeedScopedId tripId, final ServiceDate serviceDate) {
boolean success = false;
final TripPattern pattern = buffer.getLastAddedTripPattern(tripId, serviceDate);
if (pattern != null) {
// Cancel trip times for this trip in this pattern
final Timetable timetable = buffer.resolve(pattern, serviceDate);
final int tripIndex = timetable.getTripIndex(tripId);
if (tripIndex == -1) {
LOG.warn("Could not cancel previously added trip {}", tripId);
} else {
final TripTimes newTripTimes = new TripTimes(timetable.getTripTimes(tripIndex));
newTripTimes.cancel();
buffer.update(pattern, newTripTimes, serviceDate);
success = true;
}
}
return success;
}
use of org.opentripplanner.model.TripPattern in project OpenTripPlanner by opentripplanner.
the class TimetableSnapshotSource method handleScheduledTrip.
private boolean handleScheduledTrip(final TripUpdate tripUpdate, final String feedId, final ServiceDate serviceDate) {
final TripDescriptor tripDescriptor = tripUpdate.getTrip();
// This does not include Agency ID or feed ID, trips are feed-unique and we currently assume a single static feed.
final String tripId = tripDescriptor.getTripId();
final TripPattern pattern = getPatternForTripId(feedId, tripId);
if (pattern == null) {
LOG.warn("No pattern found for tripId {}, skipping TripUpdate.", tripId);
return false;
}
if (tripUpdate.getStopTimeUpdateCount() < 1) {
LOG.warn("TripUpdate contains no updates, skipping.");
return false;
}
// If this trip_id has been used for previously ADDED/MODIFIED trip message (e.g. when the sequence of stops has
// changed, and is now changing back to the originally scheduled one) cancel that previously created trip.
cancelPreviouslyAddedTrip(new FeedScopedId(feedId, tripId), serviceDate);
// Apply update on the *scheduled* time table and set the updated trip times in the buffer
final TripTimes updatedTripTimes = pattern.scheduledTimetable.createUpdatedTripTimes(tripUpdate, timeZone, serviceDate);
if (updatedTripTimes == null) {
return false;
}
// Make sure that updated trip times have the correct real time state
updatedTripTimes.setRealTimeState(RealTimeState.UPDATED);
final boolean success = buffer.update(pattern, updatedTripTimes, serviceDate);
return success;
}
Aggregations