use of org.opentripplanner.model.calendar.ServiceDate in project OpenTripPlanner by opentripplanner.
the class StopTimesHelper method listTripTimeShortsForPatternAtStop.
private static Queue<TripTimeShort> listTripTimeShortsForPatternAtStop(RoutingService routingService, TimetableSnapshot timetableSnapshot, Stop stop, TripPattern pattern, long startTime, int timeRange, int numberOfDepartures, boolean omitNonPickups, ServiceDate[] serviceDates) {
// The bounded priority Q is used to keep a sorted short list of trip times. We can not
// relay on the trip times to be in order because of real-time updates. This code can
// probably be optimized, and the trip search in the Raptor search does almost the same
// thing. This is no part of a routing request, but is a used frequently in some
// operation like Entur for "departure boards" (apps, widgets, screens on platforms, and
// hotel lobbies). Setting the numberOfDepartures and timeRange to a big number for a
// transit hub could result in a DOS attack, but there are probably other more effective
// ways to do it.
//
// The {@link MinMaxPriorityQueue} is marked beta, but we do not have a god alternative.
MinMaxPriorityQueue<TripTimeShort> pq = MinMaxPriorityQueue.orderedBy(Comparator.comparing((TripTimeShort tts) -> tts.serviceDay + tts.realtimeDeparture)).maximumSize(numberOfDepartures).create();
// Loop through all possible days
for (ServiceDate serviceDate : serviceDates) {
ServiceDay sd = new ServiceDay(routingService.getServiceCodes(), serviceDate, routingService.getCalendarService(), pattern.route.getAgency().getId());
Timetable tt;
if (timetableSnapshot != null) {
tt = timetableSnapshot.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] == 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.add(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.add(new TripTimeShort(freq.materialize(sidx, departureTime, true), sidx, stop, sd));
departureTime += freq.headway;
i++;
}
}
}
sidx++;
}
}
return pq;
}
use of org.opentripplanner.model.calendar.ServiceDate 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.calendar.ServiceDate in project OpenTripPlanner by opentripplanner.
the class Graph method updateTransitFeedValidity.
// Infer the time period covered by the transit feed
public void updateTransitFeedValidity(CalendarServiceData data, DataImportIssueStore issueStore) {
long now = new Date().getTime() / 1000;
final long SEC_IN_DAY = 24 * 60 * 60;
HashSet<String> agenciesWithFutureDates = new HashSet<String>();
HashSet<String> agencies = new HashSet<String>();
for (FeedScopedId sid : data.getServiceIds()) {
agencies.add(sid.getFeedId());
for (ServiceDate sd : data.getServiceDatesForServiceId(sid)) {
// Adjust for timezone, assuming there is only one per graph.
long t = sd.getAsDate(getTimeZone()).getTime() / 1000;
if (t > now) {
agenciesWithFutureDates.add(sid.getFeedId());
}
// assume feed is unreliable after midnight on last service day
long u = t + SEC_IN_DAY;
if (t < this.transitServiceStarts)
this.transitServiceStarts = t;
if (u > this.transitServiceEnds)
this.transitServiceEnds = u;
}
}
for (String agency : agencies) {
if (!agenciesWithFutureDates.contains(agency)) {
issueStore.add(new NoFutureDates(agency));
}
}
}
use of org.opentripplanner.model.calendar.ServiceDate in project OpenTripPlanner by opentripplanner.
the class GraphIndex method initalizeServiceCodesForDate.
private void initalizeServiceCodesForDate(Graph graph) {
CalendarService calendarService = graph.getCalendarService();
if (calendarService == null) {
return;
}
// CalendarService has one main implementation (CalendarServiceImpl) which contains a
// CalendarServiceData which can easily supply all of the dates. But it's impossible to
// actually see those dates without modifying the interfaces and inheritance. So we have
// to work around this abstraction and reconstruct the CalendarData.
// Note the "multiCalendarServiceImpl" which has docs saying it expects one single
// CalendarData. It seems to merge the calendar services from multiple GTFS feeds, but
// its only documentation says it's a hack.
// TODO OTP2 - This cleanup is added to the 'Final cleanup OTP2' issue #2757
// Reconstruct set of all dates where service is defined, keeping track of which services
// run on which days.
Multimap<ServiceDate, FeedScopedId> serviceIdsForServiceDate = HashMultimap.create();
for (FeedScopedId serviceId : calendarService.getServiceIds()) {
Set<ServiceDate> serviceDatesForService = calendarService.getServiceDatesForServiceId(serviceId);
for (ServiceDate serviceDate : serviceDatesForService) {
serviceIdsForServiceDate.put(serviceDate, serviceId);
}
}
for (ServiceDate serviceDate : serviceIdsForServiceDate.keySet()) {
TIntSet serviceCodesRunning = new TIntHashSet();
for (FeedScopedId serviceId : serviceIdsForServiceDate.get(serviceDate)) {
serviceCodesRunning.add(graph.getServiceCodes().get(serviceId));
}
serviceCodesRunningForDate.put(serviceDate, serviceCodesRunning);
}
}
use of org.opentripplanner.model.calendar.ServiceDate in project OpenTripPlanner by opentripplanner.
the class GtfsRealtimeFuzzyTripMatcher method match.
public TripDescriptor match(String feedId, TripDescriptor trip) {
if (trip.hasTripId()) {
// trip_id already exists
return trip;
}
if (!trip.hasRouteId() || !trip.hasDirectionId() || !trip.hasStartTime() || !trip.hasStartDate()) {
// Could not determine trip_id, returning original TripDescriptor
return trip;
}
FeedScopedId routeId = new FeedScopedId(feedId, trip.getRouteId());
int time = TimeToStringConverter.parseHH_MM_SS(trip.getStartTime());
ServiceDate date;
try {
date = ServiceDate.parseString(trip.getStartDate());
} catch (ParseException e) {
return trip;
}
Route route = routingService.getRouteForId(routeId);
if (route == null) {
return trip;
}
int direction = trip.getDirectionId();
Trip matchedTrip = getTrip(route, direction, time, date);
if (matchedTrip == null) {
// Check if the trip is carried over from previous day
date = date.previous();
time += 24 * 60 * 60;
matchedTrip = getTrip(route, direction, time, date);
}
if (matchedTrip == null) {
return trip;
}
// If everything succeeds, build a new TripDescriptor with the matched trip_id
return trip.toBuilder().setTripId(matchedTrip.getId().getId()).build();
}
Aggregations