Search in sources :

Example 11 with Timetable

use of org.opentripplanner.model.Timetable in project OpenTripPlanner by opentripplanner.

the class GeometryAndBlockProcessor method interline.

/**
 * Identify interlined trips (where a physical vehicle continues on to another logical trip)
 * and update the TripPatterns accordingly.
 */
private void interline(Collection<TripPattern> tripPatterns, Graph graph) {
    /* Record which Pattern each interlined TripTimes belongs to. */
    Map<TripTimes, TripPattern> patternForTripTimes = Maps.newHashMap();
    /* TripTimes grouped by the block ID and service ID of their trips. Must be a ListMultimap to allow sorting. */
    ListMultimap<BlockIdAndServiceId, TripTimes> tripTimesForBlock = ArrayListMultimap.create();
    LOG.info("Finding interlining trips based on block IDs.");
    for (TripPattern pattern : tripPatterns) {
        Timetable timetable = pattern.scheduledTimetable;
        /* TODO: Block semantics seem undefined for frequency trips, so skip them? */
        for (TripTimes tripTimes : timetable.tripTimes) {
            Trip trip = tripTimes.trip;
            if (!Strings.isNullOrEmpty(trip.getBlockId())) {
                tripTimesForBlock.put(new BlockIdAndServiceId(trip), tripTimes);
                // For space efficiency, only record times that are part of a block.
                patternForTripTimes.put(tripTimes, pattern);
            }
        }
    }
    // Associate pairs of TripPatterns with lists of trips that continue from one pattern to the other.
    Multimap<P2<TripPattern>, P2<Trip>> interlines = ArrayListMultimap.create();
    // linking them. Has no effect on single-trip blocks.
    SERVICE_BLOCK: for (BlockIdAndServiceId block : tripTimesForBlock.keySet()) {
        List<TripTimes> blockTripTimes = tripTimesForBlock.get(block);
        Collections.sort(blockTripTimes);
        TripTimes prev = null;
        for (TripTimes curr : blockTripTimes) {
            if (prev != null) {
                if (prev.getDepartureTime(prev.getNumStops() - 1) > curr.getArrivalTime(0)) {
                    LOG.error("Trip times within block {} are not increasing on service {} after trip {}.", block.blockId, block.serviceId, prev.trip.getId());
                    continue SERVICE_BLOCK;
                }
                TripPattern prevPattern = patternForTripTimes.get(prev);
                TripPattern currPattern = patternForTripTimes.get(curr);
                Stop fromStop = prevPattern.getStop(prevPattern.getStops().size() - 1);
                Stop toStop = currPattern.getStop(0);
                double teleportationDistance = SphericalDistanceLibrary.fastDistance(fromStop.getLat(), fromStop.getLon(), toStop.getLat(), toStop.getLon());
                if (teleportationDistance > maxInterlineDistance) {
                // FIXME Trimet data contains a lot of these -- in their data, two trips sharing a block ID just
                // means that they are served by the same vehicle, not that interlining is automatically allowed.
                // see #1654
                // LOG.error(graph.addBuilderAnnotation(new InterliningTeleport(prev.trip, block.blockId, (int)teleportationDistance)));
                // Only skip this particular interline edge; there may be other valid ones in the block.
                } else {
                    interlines.put(new P2<>(prevPattern, currPattern), new P2<>(prev.trip, curr.trip));
                }
            }
            prev = curr;
        }
    }
    // TODO: verify whether we need to be keeping track of patterns at all here, or could just accumulate trip-trip relationships.
    for (P2<TripPattern> patterns : interlines.keySet()) {
        for (P2<Trip> trips : interlines.get(patterns)) {
            graph.interlinedTrips.put(trips.first, trips.second);
        }
    }
    LOG.info("Done finding interlining trips.");
}
Also used : Timetable(org.opentripplanner.model.Timetable) Trip(org.opentripplanner.model.Trip) P2(org.opentripplanner.common.model.P2) Stop(org.opentripplanner.model.Stop) TripPattern(org.opentripplanner.model.TripPattern) TripTimes(org.opentripplanner.routing.trippattern.TripTimes) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List)

Example 12 with Timetable

use of org.opentripplanner.model.Timetable in project OpenTripPlanner by opentripplanner.

the class IndexAPI method getStoptimesForTrip.

@GET
@Path("/trips/{tripId}/stoptimes")
public List<TripTimeShort> getStoptimesForTrip(@PathParam("tripId") String tripId) {
    RoutingService routingService = createRoutingService();
    Trip trip = getTrip(routingService, tripId);
    TripPattern pattern = getTripPattern(routingService, trip);
    // Note, we need the updated timetable not the scheduled one (which contains no real-time updates).
    Timetable table = routingService.getTimetableForTripPattern(pattern);
    return TripTimeShort.fromTripTimes(table, trip);
}
Also used : Timetable(org.opentripplanner.model.Timetable) Trip(org.opentripplanner.model.Trip) ApiTrip(org.opentripplanner.api.model.ApiTrip) RoutingService(org.opentripplanner.routing.RoutingService) TripPattern(org.opentripplanner.model.TripPattern) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET)

Example 13 with Timetable

use of org.opentripplanner.model.Timetable 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;
}
Also used : TripTimeShort(org.opentripplanner.model.TripTimeShort) Timetable(org.opentripplanner.model.Timetable) ServiceDate(org.opentripplanner.model.calendar.ServiceDate) ServiceDay(org.opentripplanner.routing.core.ServiceDay) Stop(org.opentripplanner.model.Stop) TripTimes(org.opentripplanner.routing.trippattern.TripTimes) FrequencyEntry(org.opentripplanner.routing.trippattern.FrequencyEntry)

Example 14 with Timetable

use of org.opentripplanner.model.Timetable in project OpenTripPlanner by opentripplanner.

the class StopTimesHelper method stopTimesForStop.

/**
 * 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
 */
public static List<StopTimesInPattern> stopTimesForStop(RoutingService routingService, Stop stop, ServiceDate serviceDate, boolean omitNonPickups) {
    List<StopTimesInPattern> ret = new ArrayList<>();
    Collection<TripPattern> patternsForStop = routingService.getPatternsForStop(stop, true);
    for (TripPattern pattern : patternsForStop) {
        StopTimesInPattern stopTimes = new StopTimesInPattern(pattern);
        Timetable tt;
        TimetableSnapshot timetableSnapshot = routingService.getTimetableSnapshot();
        if (timetableSnapshot != null) {
            tt = timetableSnapshot.resolve(pattern, serviceDate);
        } else {
            tt = pattern.scheduledTimetable;
        }
        ServiceDay sd = new ServiceDay(routingService.getServiceCodes(), serviceDate, routingService.getCalendarService(), pattern.route.getAgency().getId());
        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;
                    stopTimes.times.add(new TripTimeShort(t, sidx, stop, sd));
                }
            }
            sidx++;
        }
        ret.add(stopTimes);
    }
    return ret;
}
Also used : Timetable(org.opentripplanner.model.Timetable) TripTimeShort(org.opentripplanner.model.TripTimeShort) ServiceDay(org.opentripplanner.routing.core.ServiceDay) Stop(org.opentripplanner.model.Stop) ArrayList(java.util.ArrayList) TripTimes(org.opentripplanner.routing.trippattern.TripTimes) TimetableSnapshot(org.opentripplanner.model.TimetableSnapshot) TripPattern(org.opentripplanner.model.TripPattern) StopTimesInPattern(org.opentripplanner.model.StopTimesInPattern)

Example 15 with Timetable

use of org.opentripplanner.model.Timetable 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;
}
Also used : Timetable(org.opentripplanner.model.Timetable) TripTimes(org.opentripplanner.routing.trippattern.TripTimes) TripPattern(org.opentripplanner.model.TripPattern)

Aggregations

Timetable (org.opentripplanner.model.Timetable)16 TripPattern (org.opentripplanner.model.TripPattern)13 TripTimes (org.opentripplanner.routing.trippattern.TripTimes)12 TimetableSnapshot (org.opentripplanner.model.TimetableSnapshot)6 Trip (org.opentripplanner.model.Trip)6 FeedScopedId (org.opentripplanner.model.FeedScopedId)5 Stop (org.opentripplanner.model.Stop)5 Test (org.junit.Test)4 TimetableHelper.createUpdatedTripTimes (org.opentripplanner.ext.siri.TimetableHelper.createUpdatedTripTimes)4 ServiceDate (org.opentripplanner.model.calendar.ServiceDate)4 TripUpdate (com.google.transit.realtime.GtfsRealtime.TripUpdate)3 StopTimeUpdate (com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeUpdate)3 ArrayList (java.util.ArrayList)3 ServiceDay (org.opentripplanner.routing.core.ServiceDay)3 Calendar (java.util.Calendar)2 GtfsContextBuilder.contextBuilder (org.opentripplanner.gtfs.GtfsContextBuilder.contextBuilder)2 TripTimeShort (org.opentripplanner.model.TripTimeShort)2 TripDescriptor (com.google.transit.realtime.GtfsRealtime.TripDescriptor)1 StopTimeEvent (com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeEvent)1 LocalDate (java.time.LocalDate)1