Search in sources :

Example 1 with TripPatternForDate

use of org.opentripplanner.routing.algorithm.raptor.transit.TripPatternForDate in project OpenTripPlanner by opentripplanner.

the class TripPatternForDateMapper method map.

/**
 * This method is THREAD SAFE.
 *
 * @param timetable   The timetable to be mapped to TripPatternForDate - READ ONLY
 * @param serviceDate The date to map the TripPatternForDate for - READ ONLY
 * @return TripPatternForDate for this timetable and serviceDate
 */
public TripPatternForDate map(Timetable timetable, ServiceDate serviceDate) {
    TIntSet serviceCodesRunning = serviceCodesRunningForDate.get(serviceDate);
    TripPattern oldTripPattern = timetable.pattern;
    List<TripTimes> times = new ArrayList<>();
    // The TripTimes are not sorted by departure time in the source timetable because
    // OTP1 performs a simple/ linear search. Raptor results depend on trips being
    // sorted. We reuse the same timetables many times on different days, so cache the
    // sorted versions to avoid repeated compute-intensive sorting. Anecdotally this
    // reduces mapping time by more than half, but it is still rather slow. NL Mapping
    // takes 32 seconds sorting every timetable, 9 seconds with cached sorting, and 6
    // seconds with no timetable sorting at all.
    List<TripTimes> sortedTripTimes = sortedTripTimesForTimetable.computeIfAbsent(timetable, TransitLayerMapper::getSortedTripTimes);
    for (TripTimes tripTimes : sortedTripTimes) {
        if (!serviceCodesRunning.contains(tripTimes.serviceCode)) {
            continue;
        }
        if (tripTimes.getRealTimeState() == RealTimeState.CANCELED) {
            continue;
        }
        times.add(tripTimes);
    }
    if (times.isEmpty()) {
        if (timetable.serviceDate == serviceDate) {
            LOG.debug("Tried to update TripPattern {}, but no service codes are valid for date {}", timetable.pattern.getId(), serviceDate);
        }
        return null;
    }
    return new TripPatternForDate(newTripPatternForOld.get(oldTripPattern), times.toArray(TripTimes[]::new), ServiceCalendarMapper.localDateFromServiceDate(serviceDate));
}
Also used : TIntSet(gnu.trove.set.TIntSet) ArrayList(java.util.ArrayList) TripTimes(org.opentripplanner.routing.trippattern.TripTimes) TripPattern(org.opentripplanner.model.TripPattern) TripPatternForDate(org.opentripplanner.routing.algorithm.raptor.transit.TripPatternForDate)

Example 2 with TripPatternForDate

use of org.opentripplanner.routing.algorithm.raptor.transit.TripPatternForDate 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 3 with TripPatternForDate

use of org.opentripplanner.routing.algorithm.raptor.transit.TripPatternForDate in project OpenTripPlanner by opentripplanner.

the class RaptorRoutingRequestTransitDataCreatorTest method testMergeTripPatterns.

@Test
public void testMergeTripPatterns() {
    TripTimes[] times = new TripTimes[] { null };
    LocalDate first = LocalDate.of(2019, 3, 30);
    LocalDate second = LocalDate.of(2019, 3, 31);
    LocalDate third = LocalDate.of(2019, 4, 1);
    ZonedDateTime startOfTime = DateMapper.asStartOfService(second, ZoneId.of("Europe/London"));
    // Total available trip patterns
    TripPatternWithRaptorStopIndexes tripPattern1 = new TripPatternWithId(new FeedScopedId("", "1"), null, null);
    TripPatternWithRaptorStopIndexes tripPattern2 = new TripPatternWithId(new FeedScopedId("", "2"), null, null);
    TripPatternWithRaptorStopIndexes tripPattern3 = new TripPatternWithId(new FeedScopedId("", "3"), null, null);
    List<Map<FeedScopedId, TripPatternForDate>> tripPatternsForDates = new ArrayList<>();
    // TripPatterns valid for 1st day in search range
    Map<FeedScopedId, TripPatternForDate> tripPatternForDatesById = new HashMap<>();
    tripPatternForDatesById.put(tripPattern1.getId(), new TripPatternForDate(tripPattern1, times, first));
    tripPatternForDatesById.put(tripPattern2.getId(), new TripPatternForDate(tripPattern2, times, first));
    tripPatternForDatesById.put(tripPattern3.getId(), new TripPatternForDate(tripPattern1, times, first));
    tripPatternsForDates.add(tripPatternForDatesById);
    // TripPatterns valid for 2nd day in search range
    Map<FeedScopedId, TripPatternForDate> tripPatternForDatesById2 = new HashMap<>();
    tripPatternForDatesById2.put(tripPattern2.getId(), new TripPatternForDate(tripPattern2, times, second));
    tripPatternForDatesById2.put(tripPattern3.getId(), new TripPatternForDate(tripPattern3, times, second));
    tripPatternsForDates.add(tripPatternForDatesById2);
    // TripPatterns valid for 3rd day in search range
    Map<FeedScopedId, TripPatternForDate> tripPatternForDatesById3 = new HashMap<>();
    tripPatternForDatesById3.put(tripPattern1.getId(), new TripPatternForDate(tripPattern1, times, third));
    tripPatternForDatesById3.put(tripPattern3.getId(), new TripPatternForDate(tripPattern3, times, third));
    tripPatternsForDates.add(tripPatternForDatesById3);
    // Patterns containing trip schedules for all 3 days. Trip schedules for later days are offset in time when requested.
    List<TripPatternForDates> combinedTripPatterns = RaptorRoutingRequestTransitDataCreator.merge(startOfTime, tripPatternsForDates);
    // Check the number of trip schedules available for each pattern after combining dates in the search range
    assertEquals(2, combinedTripPatterns.get(0).numberOfTripSchedules());
    assertEquals(2, combinedTripPatterns.get(1).numberOfTripSchedules());
    assertEquals(3, combinedTripPatterns.get(2).numberOfTripSchedules());
    // Verify that the per-day offsets were calculated correctly
    // DST - Clocks go forward on March 31st
    assertEquals(-82800, ((TripScheduleWithOffset) combinedTripPatterns.get(2).getTripSchedule(0)).getSecondsOffset());
    assertEquals(0, ((TripScheduleWithOffset) combinedTripPatterns.get(2).getTripSchedule(1)).getSecondsOffset());
    assertEquals(86400, ((TripScheduleWithOffset) combinedTripPatterns.get(2).getTripSchedule(2)).getSecondsOffset());
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) LocalDate(java.time.LocalDate) TripPatternForDate(org.opentripplanner.routing.algorithm.raptor.transit.TripPatternForDate) ZonedDateTime(java.time.ZonedDateTime) TripTimes(org.opentripplanner.routing.trippattern.TripTimes) FeedScopedId(org.opentripplanner.model.FeedScopedId) TripPatternWithRaptorStopIndexes(org.opentripplanner.routing.algorithm.raptor.transit.TripPatternWithRaptorStopIndexes) HashMap(java.util.HashMap) Map(java.util.Map) Test(org.junit.Test)

Example 4 with TripPatternForDate

use of org.opentripplanner.routing.algorithm.raptor.transit.TripPatternForDate 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);
}
Also used : HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) TripPattern(org.opentripplanner.model.TripPattern) ArrayList(java.util.ArrayList) LocalDate(java.time.LocalDate) TripPatternMapper.mapOldTripPatternToRaptorTripPattern(org.opentripplanner.routing.algorithm.raptor.transit.mappers.TripPatternMapper.mapOldTripPatternToRaptorTripPattern) TripPattern(org.opentripplanner.model.TripPattern) TripPatternForDate(org.opentripplanner.routing.algorithm.raptor.transit.TripPatternForDate) ServiceDate(org.opentripplanner.model.calendar.ServiceDate) ArrayList(java.util.ArrayList) List(java.util.List) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) TripPatternWithRaptorStopIndexes(org.opentripplanner.routing.algorithm.raptor.transit.TripPatternWithRaptorStopIndexes)

Example 5 with TripPatternForDate

use of org.opentripplanner.routing.algorithm.raptor.transit.TripPatternForDate in project OpenTripPlanner by opentripplanner.

the class RaptorRoutingRequestTransitDataCreator method merge.

/**
 * This method merges several list of TripPatterns for several consecutive dates into a single
 * list of TripPatternsForDates. The purpose of doing this is so that TripSchedules for several
 * dates are combined by TripPattern instead of having their own TripPattern. This is to improve
 * performance for searching, as each TripPattern is searched only once per round.
 */
static List<TripPatternForDates> merge(ZonedDateTime searchStartTime, List<Map<FeedScopedId, TripPatternForDate>> tripPatternForDateList) {
    List<TripPatternForDates> combinedList = new ArrayList<>();
    // Extract all distinct TripPatterns across the search days
    Map<FeedScopedId, TripPatternWithRaptorStopIndexes> allTripPatternsById = tripPatternForDateList.stream().flatMap(t -> t.values().stream()).map(TripPatternForDate::getTripPattern).distinct().collect(Collectors.toMap(TripPatternWithRaptorStopIndexes::getId, t -> t));
    // For each TripPattern, time expand each TripPatternForDate and merge into a single TripPatternForDates
    for (Map.Entry<FeedScopedId, TripPatternWithRaptorStopIndexes> patternEntry : allTripPatternsById.entrySet()) {
        List<TripPatternForDate> tripPatterns = new ArrayList<>();
        List<Integer> offsets = new ArrayList<>();
        for (Map<FeedScopedId, TripPatternForDate> tripPatternById : tripPatternForDateList) {
            TripPatternForDate tripPatternForDate = tripPatternById.get(patternEntry.getKey());
            if (tripPatternForDate != null) {
                tripPatterns.add(tripPatternForDate);
                offsets.add(secondsSinceStartOfTime(searchStartTime, tripPatternForDate.getLocalDate()));
            }
        }
        combinedList.add(new TripPatternForDates(patternEntry.getValue(), tripPatterns, offsets));
    }
    return combinedList;
}
Also used : FeedScopedId(org.opentripplanner.model.FeedScopedId) DateMapper.secondsSinceStartOfTime(org.opentripplanner.routing.algorithm.raptor.transit.mappers.DateMapper.secondsSinceStartOfTime) RaptorTransfer(org.opentripplanner.transit.raptor.api.transit.RaptorTransfer) ZonedDateTime(java.time.ZonedDateTime) TripPatternForDate(org.opentripplanner.routing.algorithm.raptor.transit.TripPatternForDate) Set(java.util.Set) Instant(java.time.Instant) DateMapper(org.opentripplanner.routing.algorithm.raptor.transit.mappers.DateMapper) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) TransitLayer(org.opentripplanner.routing.algorithm.raptor.transit.TransitLayer) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) Stream(java.util.stream.Stream) Collectors.toMap(java.util.stream.Collectors.toMap) TripPatternWithRaptorStopIndexes(org.opentripplanner.routing.algorithm.raptor.transit.TripPatternWithRaptorStopIndexes) LocalDate(java.time.LocalDate) Map(java.util.Map) TransitMode(org.opentripplanner.model.TransitMode) ArrayList(java.util.ArrayList) TripPatternForDate(org.opentripplanner.routing.algorithm.raptor.transit.TripPatternForDate) FeedScopedId(org.opentripplanner.model.FeedScopedId) TripPatternWithRaptorStopIndexes(org.opentripplanner.routing.algorithm.raptor.transit.TripPatternWithRaptorStopIndexes) Collectors.toMap(java.util.stream.Collectors.toMap) Map(java.util.Map)

Aggregations

TripPatternForDate (org.opentripplanner.routing.algorithm.raptor.transit.TripPatternForDate)6 LocalDate (java.time.LocalDate)4 ArrayList (java.util.ArrayList)4 TripPatternWithRaptorStopIndexes (org.opentripplanner.routing.algorithm.raptor.transit.TripPatternWithRaptorStopIndexes)4 ZonedDateTime (java.time.ZonedDateTime)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Map (java.util.Map)2 FeedScopedId (org.opentripplanner.model.FeedScopedId)2 TripPattern (org.opentripplanner.model.TripPattern)2 TransitLayer (org.opentripplanner.routing.algorithm.raptor.transit.TransitLayer)2 TripPatternMapper.mapOldTripPatternToRaptorTripPattern (org.opentripplanner.routing.algorithm.raptor.transit.mappers.TripPatternMapper.mapOldTripPatternToRaptorTripPattern)2 TripTimes (org.opentripplanner.routing.trippattern.TripTimes)2 TIntSet (gnu.trove.set.TIntSet)1 Instant (java.time.Instant)1 Set (java.util.Set)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 Collectors (java.util.stream.Collectors)1 Collectors.toList (java.util.stream.Collectors.toList)1 Collectors.toMap (java.util.stream.Collectors.toMap)1