Search in sources :

Example 6 with Timetable

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

the class TimetableSnapshotSourceTest method testHandleDelayedTrip.

@Test
public void testHandleDelayedTrip() {
    final FeedScopedId tripId = new FeedScopedId(feedId, "1.1");
    final FeedScopedId tripId2 = new FeedScopedId(feedId, "1.2");
    final Trip trip = graph.index.getTripForId().get(tripId);
    final TripPattern pattern = graph.index.getPatternForTrip().get(trip);
    final int tripIndex = pattern.scheduledTimetable.getTripIndex(tripId);
    final int tripIndex2 = pattern.scheduledTimetable.getTripIndex(tripId2);
    final TripDescriptor.Builder tripDescriptorBuilder = TripDescriptor.newBuilder();
    tripDescriptorBuilder.setTripId("1.1");
    tripDescriptorBuilder.setScheduleRelationship(TripDescriptor.ScheduleRelationship.SCHEDULED);
    final TripUpdate.Builder tripUpdateBuilder = TripUpdate.newBuilder();
    tripUpdateBuilder.setTrip(tripDescriptorBuilder);
    final StopTimeUpdate.Builder stopTimeUpdateBuilder = tripUpdateBuilder.addStopTimeUpdateBuilder();
    stopTimeUpdateBuilder.setScheduleRelationship(StopTimeUpdate.ScheduleRelationship.SCHEDULED);
    stopTimeUpdateBuilder.setStopSequence(2);
    final StopTimeEvent.Builder arrivalBuilder = stopTimeUpdateBuilder.getArrivalBuilder();
    final StopTimeEvent.Builder departureBuilder = stopTimeUpdateBuilder.getDepartureBuilder();
    arrivalBuilder.setDelay(1);
    departureBuilder.setDelay(1);
    final TripUpdate tripUpdate = tripUpdateBuilder.build();
    updater.applyTripUpdates(graph, fullDataset, Arrays.asList(tripUpdate), feedId);
    final TimetableSnapshot snapshot = updater.getTimetableSnapshot();
    final Timetable forToday = snapshot.resolve(pattern, serviceDate);
    final Timetable schedule = snapshot.resolve(pattern, null);
    assertNotSame(forToday, schedule);
    assertNotSame(forToday.getTripTimes(tripIndex), schedule.getTripTimes(tripIndex));
    assertSame(forToday.getTripTimes(tripIndex2), schedule.getTripTimes(tripIndex2));
    assertEquals(1, forToday.getTripTimes(tripIndex).getArrivalDelay(1));
    assertEquals(1, forToday.getTripTimes(tripIndex).getDepartureDelay(1));
    assertEquals(RealTimeState.SCHEDULED, schedule.getTripTimes(tripIndex).getRealTimeState());
    assertEquals(RealTimeState.UPDATED, forToday.getTripTimes(tripIndex).getRealTimeState());
    assertEquals(RealTimeState.SCHEDULED, schedule.getTripTimes(tripIndex2).getRealTimeState());
    assertEquals(RealTimeState.SCHEDULED, forToday.getTripTimes(tripIndex2).getRealTimeState());
}
Also used : Timetable(org.opentripplanner.model.Timetable) Trip(org.opentripplanner.model.Trip) TripUpdate(com.google.transit.realtime.GtfsRealtime.TripUpdate) TimetableSnapshot(org.opentripplanner.model.TimetableSnapshot) TripPattern(org.opentripplanner.model.TripPattern) StopTimeEvent(com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeEvent) TripDescriptor(com.google.transit.realtime.GtfsRealtime.TripDescriptor) FeedScopedId(org.opentripplanner.model.FeedScopedId) StopTimeUpdate(com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeUpdate) Test(org.junit.Test)

Example 7 with Timetable

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

the class TransitLayerUpdater method update.

public void update(Set<Timetable> updatedTimetables) {
    if (!graph.hasRealtimeTransitLayer()) {
        return;
    }
    // Make a shallow copy of the realtime transit layer. Only the objects that are copied will be
    // changed during this update process.
    TransitLayer realtimeTransitLayer = new TransitLayer(graph.getRealtimeTransitLayer());
    double startTime = System.currentTimeMillis();
    // Map TripPatterns for this update to Raptor TripPatterns
    final Map<org.opentripplanner.model.TripPattern, TripPatternWithRaptorStopIndexes> newTripPatternForOld = mapOldTripPatternToRaptorTripPattern(realtimeTransitLayer.getStopIndex(), updatedTimetables.stream().map(t -> t.pattern).collect(Collectors.toSet()));
    // Instantiate a TripPatternForDateMapper with the new TripPattern mappings
    TripPatternForDateMapper tripPatternForDateMapper = new TripPatternForDateMapper(serviceCodesRunningForDate, newTripPatternForOld);
    // Index updated timetables by date
    @SuppressWarnings("ConstantConditions") Multimap<LocalDate, Timetable> timetablesByDate = Multimaps.index(updatedTimetables, t -> ServiceCalendarMapper.localDateFromServiceDate(t.serviceDate));
    for (LocalDate date : timetablesByDate.keySet()) {
        Collection<Timetable> timetablesForDate = timetablesByDate.get(date);
        List<TripPatternForDate> patternsForDate = realtimeTransitLayer.getTripPatternsForDateCopy(date);
        if (patternsForDate == null) {
            continue;
        }
        Map<org.opentripplanner.model.TripPattern, TripPatternForDate> patternsForDateMap = tripPatternForDateMapCache.computeIfAbsent(date, p -> patternsForDate.stream().collect(Collectors.toMap(t -> t.getTripPattern().getPattern(), t -> t)));
        for (Timetable timetable : timetablesForDate) {
            TripPatternForDate tripPatternForDate = tripPatternForDateMapper.map(timetable, timetable.serviceDate);
            if (tripPatternForDate != null) {
                patternsForDateMap.put(timetable.pattern, tripPatternForDate);
            }
        }
        realtimeTransitLayer.replaceTripPatternsForDate(date, new ArrayList<>(patternsForDateMap.values()));
        // Switch out the reference with the updated realtimeTransitLayer. This is synchronized to
        // guarantee that the reference is set after all the fields have been updated.
        graph.setRealtimeTransitLayer(realtimeTransitLayer);
        LOG.debug("UPDATING {} tripPatterns took {} ms", updatedTimetables.size(), System.currentTimeMillis() - startTime);
    }
}
Also used : Timetable(org.opentripplanner.model.Timetable) LocalDate(java.time.LocalDate) TripPatternMapper.mapOldTripPatternToRaptorTripPattern(org.opentripplanner.routing.algorithm.raptor.transit.mappers.TripPatternMapper.mapOldTripPatternToRaptorTripPattern) TripPatternForDate(org.opentripplanner.routing.algorithm.raptor.transit.TripPatternForDate) TripPatternWithRaptorStopIndexes(org.opentripplanner.routing.algorithm.raptor.transit.TripPatternWithRaptorStopIndexes) TransitLayer(org.opentripplanner.routing.algorithm.raptor.transit.TransitLayer)

Example 8 with Timetable

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

the class TripTimesShortHelper method getTripTimesShort.

public static List<TripTimeShort> getTripTimesShort(RoutingService routingService, Trip trip, ServiceDate serviceDate) {
    final ServiceDay serviceDay = new ServiceDay(routingService.getServiceCodes(), serviceDate, routingService.getCalendarService(), trip.getRoute().getAgency().getId());
    Timetable timetable = null;
    TimetableSnapshot timetableSnapshot = routingService.getTimetableSnapshot();
    if (timetableSnapshot != null) {
        // Check if realtime-data is available for trip
        TripPattern pattern = timetableSnapshot.getLastAddedTripPattern(trip.getId(), serviceDate);
        if (pattern == null) {
            pattern = routingService.getPatternForTrip().get(trip);
        }
        timetable = timetableSnapshot.resolve(pattern, serviceDate);
    }
    if (timetable == null) {
        timetable = routingService.getPatternForTrip().get(trip).scheduledTimetable;
    }
    // This check is made here to avoid changing TripTimeShort.fromTripTimes
    TripTimes times = timetable.getTripTimes(timetable.getTripIndex(trip.getId()));
    if (!serviceDay.serviceRunning(times.serviceCode)) {
        return new ArrayList<>();
    } else {
        return TripTimeShort.fromTripTimes(timetable, trip, serviceDay);
    }
}
Also used : Timetable(org.opentripplanner.model.Timetable) ServiceDay(org.opentripplanner.routing.core.ServiceDay) ArrayList(java.util.ArrayList) TripTimes(org.opentripplanner.routing.trippattern.TripTimes) TimetableSnapshot(org.opentripplanner.model.TimetableSnapshot) TripPattern(org.opentripplanner.model.TripPattern)

Example 9 with Timetable

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

the class TimetableSnapshotSourceTest method testHandleAddedTrip.

@Test
public void testHandleAddedTrip() throws ParseException {
    // GIVEN
    // Get service date of today because old dates will be purged after applying updates
    final ServiceDate serviceDate = new ServiceDate(Calendar.getInstance());
    final String addedTripId = "added_trip";
    TripUpdate tripUpdate;
    {
        final TripDescriptor.Builder tripDescriptorBuilder = TripDescriptor.newBuilder();
        tripDescriptorBuilder.setTripId(addedTripId);
        tripDescriptorBuilder.setScheduleRelationship(TripDescriptor.ScheduleRelationship.ADDED);
        tripDescriptorBuilder.setStartDate(serviceDate.asCompactString());
        final Calendar calendar = serviceDate.getAsCalendar(graph.getTimeZone());
        final long midnightSecondsSinceEpoch = calendar.getTimeInMillis() / 1000;
        final TripUpdate.Builder tripUpdateBuilder = TripUpdate.newBuilder();
        tripUpdateBuilder.setTrip(tripDescriptorBuilder);
        {
            // Stop A
            final StopTimeUpdate.Builder stopTimeUpdateBuilder = tripUpdateBuilder.addStopTimeUpdateBuilder();
            stopTimeUpdateBuilder.setScheduleRelationship(StopTimeUpdate.ScheduleRelationship.SCHEDULED);
            stopTimeUpdateBuilder.setStopId("A");
            {
                // Arrival
                final StopTimeEvent.Builder arrivalBuilder = stopTimeUpdateBuilder.getArrivalBuilder();
                arrivalBuilder.setTime(midnightSecondsSinceEpoch + (8 * 3600) + (30 * 60));
                arrivalBuilder.setDelay(0);
            }
            {
                // Departure
                final StopTimeEvent.Builder departureBuilder = stopTimeUpdateBuilder.getDepartureBuilder();
                departureBuilder.setTime(midnightSecondsSinceEpoch + (8 * 3600) + (30 * 60));
                departureBuilder.setDelay(0);
            }
        }
        {
            // Stop C
            final StopTimeUpdate.Builder stopTimeUpdateBuilder = tripUpdateBuilder.addStopTimeUpdateBuilder();
            stopTimeUpdateBuilder.setScheduleRelationship(StopTimeUpdate.ScheduleRelationship.SCHEDULED);
            stopTimeUpdateBuilder.setStopId("C");
            {
                // Arrival
                final StopTimeEvent.Builder arrivalBuilder = stopTimeUpdateBuilder.getArrivalBuilder();
                arrivalBuilder.setTime(midnightSecondsSinceEpoch + (8 * 3600) + (40 * 60));
                arrivalBuilder.setDelay(0);
            }
            {
                // Departure
                final StopTimeEvent.Builder departureBuilder = stopTimeUpdateBuilder.getDepartureBuilder();
                departureBuilder.setTime(midnightSecondsSinceEpoch + (8 * 3600) + (45 * 60));
                departureBuilder.setDelay(0);
            }
        }
        {
            // Stop E
            final StopTimeUpdate.Builder stopTimeUpdateBuilder = tripUpdateBuilder.addStopTimeUpdateBuilder();
            stopTimeUpdateBuilder.setScheduleRelationship(StopTimeUpdate.ScheduleRelationship.SCHEDULED);
            stopTimeUpdateBuilder.setStopId("E");
            {
                // Arrival
                final StopTimeEvent.Builder arrivalBuilder = stopTimeUpdateBuilder.getArrivalBuilder();
                arrivalBuilder.setTime(midnightSecondsSinceEpoch + (8 * 3600) + (55 * 60));
                arrivalBuilder.setDelay(0);
            }
            {
                // Departure
                final StopTimeEvent.Builder departureBuilder = stopTimeUpdateBuilder.getDepartureBuilder();
                departureBuilder.setTime(midnightSecondsSinceEpoch + (8 * 3600) + (55 * 60));
                departureBuilder.setDelay(0);
            }
        }
        tripUpdate = tripUpdateBuilder.build();
    }
    // WHEN
    updater.applyTripUpdates(graph, fullDataset, Arrays.asList(tripUpdate), feedId);
    // THEN
    // Find new pattern in graph starting from stop A
    Stop stopA = graph.index.getStopForId(new FeedScopedId(feedId, "A"));
    // Get trip pattern of last (most recently added) outgoing edge
    // FIXME create a new test to see that add-trip realtime updates work
    TripPattern tripPattern = null;
    assertNotNull("Added trip pattern should be found", tripPattern);
    final TimetableSnapshot snapshot = updater.getTimetableSnapshot();
    final Timetable forToday = snapshot.resolve(tripPattern, serviceDate);
    final Timetable schedule = snapshot.resolve(tripPattern, null);
    assertNotSame(forToday, schedule);
    final int forTodayAddedTripIndex = forToday.getTripIndex(addedTripId);
    assertTrue("Added trip should be found in time table for service date", forTodayAddedTripIndex > -1);
    assertEquals(RealTimeState.ADDED, forToday.getTripTimes(forTodayAddedTripIndex).getRealTimeState());
    final int scheduleTripIndex = schedule.getTripIndex(addedTripId);
    assertEquals("Added trip should not be found in scheduled time table", -1, scheduleTripIndex);
}
Also used : Timetable(org.opentripplanner.model.Timetable) TripUpdate(com.google.transit.realtime.GtfsRealtime.TripUpdate) Stop(org.opentripplanner.model.Stop) GtfsContextBuilder.contextBuilder(org.opentripplanner.gtfs.GtfsContextBuilder.contextBuilder) Calendar(java.util.Calendar) TimetableSnapshot(org.opentripplanner.model.TimetableSnapshot) TripPattern(org.opentripplanner.model.TripPattern) ServiceDate(org.opentripplanner.model.calendar.ServiceDate) StopTimeUpdate(com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeUpdate) FeedScopedId(org.opentripplanner.model.FeedScopedId) Test(org.junit.Test)

Example 10 with Timetable

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

the class SiriTimetableSnapshotSource method handleModifiedTrip.

private boolean handleModifiedTrip(Graph graph, String feedId, EstimatedVehicleJourney estimatedVehicleJourney) {
    // Check if EstimatedVehicleJourney is reported as NOT monitored
    if (estimatedVehicleJourney.isMonitored() != null && !estimatedVehicleJourney.isMonitored()) {
        // Ignore the notMonitored-flag if the journey is NOT monitored because it has been cancelled
        if (estimatedVehicleJourney.isCancellation() != null && !estimatedVehicleJourney.isCancellation()) {
            return false;
        }
    }
    // Values used in logging
    String operatorRef = (estimatedVehicleJourney.getOperatorRef() != null ? estimatedVehicleJourney.getOperatorRef().getValue() : null);
    String vehicleModes = "" + estimatedVehicleJourney.getVehicleModes();
    String lineRef = estimatedVehicleJourney.getLineRef().getValue();
    String vehicleRef = (estimatedVehicleJourney.getVehicleRef() != null ? estimatedVehicleJourney.getVehicleRef().getValue() : null);
    ServiceDate serviceDate = getServiceDateForEstimatedVehicleJourney(estimatedVehicleJourney);
    if (serviceDate == null) {
        return false;
    }
    Set<TripTimes> times = new HashSet<>();
    Set<TripPattern> patterns = new HashSet<>();
    Trip tripMatchedByServiceJourneyId = siriFuzzyTripMatcher.findTripByDatedVehicleJourneyRef(estimatedVehicleJourney);
    if (tripMatchedByServiceJourneyId != null) {
        /*
              Found exact match
             */
        TripPattern exactPattern = routingService.getPatternForTrip().get(tripMatchedByServiceJourneyId);
        if (exactPattern != null) {
            Timetable currentTimetable = getCurrentTimetable(exactPattern, serviceDate);
            TripTimes exactUpdatedTripTimes = createUpdatedTripTimes(graph, currentTimetable, estimatedVehicleJourney, timeZone, tripMatchedByServiceJourneyId.getId());
            if (exactUpdatedTripTimes != null) {
                times.add(exactUpdatedTripTimes);
                patterns.add(exactPattern);
            } else {
                LOG.info("Failed to update TripTimes for trip found by exact match {}", tripMatchedByServiceJourneyId.getId());
                return false;
            }
        }
    } else {
        /*
                No exact match found - search for trips based on arrival-times/stop-patterns
             */
        Set<Trip> trips = siriFuzzyTripMatcher.match(estimatedVehicleJourney);
        if (trips == null || trips.isEmpty()) {
            LOG.debug("No trips found for EstimatedVehicleJourney. [operator={}, vehicleModes={}, lineRef={}, vehicleRef={}]", operatorRef, vehicleModes, lineRef, vehicleRef);
            return false;
        }
        // Find the trips that best corresponds to EstimatedVehicleJourney
        Set<Trip> matchingTrips = getTripForJourney(trips, estimatedVehicleJourney);
        if (matchingTrips == null || matchingTrips.isEmpty()) {
            LOG.debug("Found no matching trip for SIRI ET (serviceDate, departureTime). [operator={}, vehicleModes={}, lineRef={}, vehicleJourneyRef={}]", operatorRef, vehicleModes, lineRef, vehicleRef);
            return false;
        }
        for (Trip matchingTrip : matchingTrips) {
            TripPattern pattern = getPatternForTrip(matchingTrip, estimatedVehicleJourney);
            if (pattern != null) {
                Timetable currentTimetable = getCurrentTimetable(pattern, serviceDate);
                TripTimes updatedTripTimes = createUpdatedTripTimes(graph, currentTimetable, estimatedVehicleJourney, timeZone, matchingTrip.getId());
                if (updatedTripTimes != null) {
                    patterns.add(pattern);
                    times.add(updatedTripTimes);
                }
            }
        }
    }
    if (patterns.isEmpty()) {
        LOG.debug("Found no matching pattern for SIRI ET (firstStopId, lastStopId, numberOfStops). [operator={}, vehicleModes={}, lineRef={}, vehicleRef={}]", operatorRef, vehicleModes, lineRef, vehicleRef);
        return false;
    }
    if (times.isEmpty()) {
        return false;
    }
    boolean result = false;
    for (TripTimes tripTimes : times) {
        Trip trip = tripTimes.trip;
        for (TripPattern pattern : patterns) {
            if (tripTimes.getNumStops() == pattern.stopPattern.stops.length) {
                if (!tripTimes.isCanceled()) {
                    /*
                          UPDATED and MODIFIED tripTimes should be handled the same way to always allow latest realtime-update
                          to replace previous update regardless of realtimestate
                         */
                    cancelScheduledTrip(feedId, trip.getId().getId(), serviceDate);
                    // Check whether trip id has been used for previously ADDED/MODIFIED trip message and cancel
                    // previously created trip
                    cancelPreviouslyAddedTrip(feedId, trip.getId().getId(), serviceDate);
                    // Calculate modified stop-pattern
                    Timetable currentTimetable = getCurrentTimetable(pattern, serviceDate);
                    List<Stop> modifiedStops = createModifiedStops(currentTimetable, estimatedVehicleJourney, routingService);
                    List<StopTime> modifiedStopTimes = createModifiedStopTimes(currentTimetable, tripTimes, estimatedVehicleJourney, trip, routingService);
                    if (modifiedStops != null && modifiedStops.isEmpty()) {
                        tripTimes.cancel();
                    } else {
                        // Add new trip
                        result = result | addTripToGraphAndBuffer(feedId, graph, trip, modifiedStopTimes, modifiedStops, tripTimes, serviceDate);
                    }
                } else {
                    result = result | buffer.update(pattern, tripTimes, serviceDate);
                }
                LOG.debug("Applied realtime data for trip {}", trip.getId().getId());
            } else {
                LOG.debug("Ignoring update since number of stops do not match");
            }
        }
    }
    return result;
}
Also used : Timetable(org.opentripplanner.model.Timetable) Trip(org.opentripplanner.model.Trip) Stop(org.opentripplanner.model.Stop) TripPattern(org.opentripplanner.model.TripPattern) ServiceDate(org.opentripplanner.model.calendar.ServiceDate) TimetableHelper.createUpdatedTripTimes(org.opentripplanner.ext.siri.TimetableHelper.createUpdatedTripTimes) TripTimes(org.opentripplanner.routing.trippattern.TripTimes) HashSet(java.util.HashSet) StopTime(org.opentripplanner.model.StopTime)

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