diff --git a/src/main/java/org/opentripplanner/index/IndexAPI.java b/src/main/java/org/opentripplanner/index/IndexAPI.java index bae8aacd156..2487c86f0c5 100644 --- a/src/main/java/org/opentripplanner/index/IndexAPI.java +++ b/src/main/java/org/opentripplanner/index/IndexAPI.java @@ -266,7 +266,7 @@ public Response getStoptimesForStop (@PathParam("stopId") String stopIdString, @QueryParam("omitCanceled") boolean omitCanceled) { Stop stop = index.stopForId.get(GtfsLibrary.convertIdFromString(stopIdString)); if (stop == null) return Response.status(Status.NOT_FOUND).entity(MSG_404).build(); - return Response.status(Status.OK).entity(index.stopTimesForStop(stop, startTime, timeRange, numberOfDepartures, omitNonPickups, omitCanceled )).build(); + return Response.status(Status.OK).entity(index.stopTimesForStop(stop, startTime, timeRange, numberOfDepartures, omitNonPickups, omitCanceled, true)).build(); } /** @@ -288,7 +288,7 @@ public Response getStoptimesForStopAndDate (@PathParam("stopId") String stopIdSt return Response.status(Status.BAD_REQUEST).entity(MSG_400).build(); } - List ret = index.getStopTimesForStop(stop, sd, omitNonPickups, false); + List ret = index.getStopTimesForStop(stop, sd, omitNonPickups, false, true); return Response.status(Status.OK).entity(ret).build(); } diff --git a/src/main/java/org/opentripplanner/index/IndexGraphQLSchema.java b/src/main/java/org/opentripplanner/index/IndexGraphQLSchema.java index d3605e388a5..f449967d49d 100644 --- a/src/main/java/org/opentripplanner/index/IndexGraphQLSchema.java +++ b/src/main/java/org/opentripplanner/index/IndexGraphQLSchema.java @@ -1446,6 +1446,12 @@ public IndexGraphQLSchema(GraphIndex index) { .type(Scalars.GraphQLBoolean) .defaultValue(false) .build()) + .argument(GraphQLArgument.newArgument() + .name("omitDeviated") + .description("If false, returns also trips that have been deviated to this stop") + .type(Scalars.GraphQLBoolean) + .defaultValue(true) + .build()) .dataFetcher(environment -> { ServiceDate date; try { // TODO: Add our own scalar types for at least serviceDate and AgencyAndId @@ -1456,15 +1462,16 @@ public IndexGraphQLSchema(GraphIndex index) { Stop stop = environment.getSource(); boolean omitNonPickups = environment.getArgument("omitNonPickups"); boolean omitCanceled = environment.getArgument("omitCanceled"); + boolean omitDeviated = environment.getArgument("omitDeviated"); if (stop.getLocationType() == 1) { // Merge all stops if this is a station return index.stopsForParentStation .get(stop.getId()) .stream() - .flatMap(singleStop -> index.getStopTimesForStop(singleStop, date, omitNonPickups, omitCanceled).stream()) + .flatMap(singleStop -> index.getStopTimesForStop(singleStop, date, omitNonPickups, omitCanceled, omitDeviated).stream()) .collect(Collectors.toList()); } - return index.getStopTimesForStop(stop, date, omitNonPickups, omitCanceled); + return index.getStopTimesForStop(stop, date, omitNonPickups, omitCanceled, omitDeviated); }) .build()) .field(GraphQLFieldDefinition.newFieldDefinition() @@ -1500,6 +1507,12 @@ public IndexGraphQLSchema(GraphIndex index) { .type(Scalars.GraphQLBoolean) .defaultValue(true) .build()) + .argument(GraphQLArgument.newArgument() + .name("omitDeviated") + .description("If false, returns also trips that have been deviated to this stop") + .type(Scalars.GraphQLBoolean) + .defaultValue(true) + .build()) .dataFetcher(environment -> { Stop stop = environment.getSource(); if (stop.getLocationType() == 1) { @@ -1513,7 +1526,8 @@ public IndexGraphQLSchema(GraphIndex index) { environment.getArgument("timeRange"), environment.getArgument("numberOfDepartures"), environment.getArgument("omitNonPickups"), - environment.getArgument("omitCanceled")) + environment.getArgument("omitCanceled"), + environment.getArgument("omitDeviated")) .stream() ) .collect(Collectors.toList()); @@ -1523,7 +1537,8 @@ public IndexGraphQLSchema(GraphIndex index) { environment.getArgument("timeRange"), environment.getArgument("numberOfDepartures"), environment.getArgument("omitNonPickups"), - environment.getArgument("omitCanceled")); + environment.getArgument("omitCanceled"), + environment.getArgument("omitDeviated")); }) .build()) @@ -1560,6 +1575,12 @@ public IndexGraphQLSchema(GraphIndex index) { .type(Scalars.GraphQLBoolean) .defaultValue(true) .build()) + .argument(GraphQLArgument.newArgument() + .name("omitDeviated") + .description("If false, returns also trips that have been deviated to this stop") + .type(Scalars.GraphQLBoolean) + .defaultValue(true) + .build()) .dataFetcher(environment -> { Stop stop = environment.getSource(); Stream stream; @@ -1573,7 +1594,8 @@ public IndexGraphQLSchema(GraphIndex index) { environment.getArgument("timeRange"), environment.getArgument("numberOfDepartures"), environment.getArgument("omitNonPickups"), - environment.getArgument("omitCanceled")) + environment.getArgument("omitCanceled"), + environment.getArgument("omitDeviated")) .stream() ); } else { @@ -1583,7 +1605,8 @@ public IndexGraphQLSchema(GraphIndex index) { environment.getArgument("timeRange"), environment.getArgument("numberOfDepartures"), environment.getArgument("omitNonPickups"), - environment.getArgument("omitCanceled") + environment.getArgument("omitCanceled"), + environment.getArgument("omitDeviated") ).stream(); } return stream.flatMap(stoptimesWithPattern -> stoptimesWithPattern.times.stream()) @@ -1718,6 +1741,12 @@ public IndexGraphQLSchema(GraphIndex index) { .dataFetcher( environment -> ((TripTimeShort) environment.getSource()).stopSequence) .build()) + .field(GraphQLFieldDefinition.newFieldDefinition() + .name("deviationStop") + .description("The stop where this stop time has been deviated to. \n`null` if the trip has not been deviated to another stop.") + .type(stopType) + .dataFetcher(environment -> index.stopForId.get(((TripTimeShort)environment.getSource()).deviationStop)) + .build()) .build(); tripType = GraphQLObjectType.newObject() diff --git a/src/main/java/org/opentripplanner/index/model/TripTimeShort.java b/src/main/java/org/opentripplanner/index/model/TripTimeShort.java index c60f1776123..eefbb7ff7ba 100644 --- a/src/main/java/org/opentripplanner/index/model/TripTimeShort.java +++ b/src/main/java/org/opentripplanner/index/model/TripTimeShort.java @@ -36,6 +36,7 @@ public class TripTimeShort { public double serviceAreaRadius; public String serviceArea; public int stopSequence; + public FeedScopedId deviationStop; /** * This is stop-specific, so the index i is a stop index, not a hop index. @@ -61,6 +62,7 @@ public TripTimeShort(TripTimes tt, int i, Stop stop) { serviceAreaRadius = tt.getServiceAreaRadius(i); serviceArea = tt.getServiceArea(i); stopSequence = tt.getStopSequence(i); + deviationStop = tt.getDeviationStop(i); } public TripTimeShort(TripTimes tt, int i, Stop stop, ServiceDay sd) { diff --git a/src/main/java/org/opentripplanner/model/StopPattern.java b/src/main/java/org/opentripplanner/model/StopPattern.java index f8a0e6ef987..3752e7f1940 100644 --- a/src/main/java/org/opentripplanner/model/StopPattern.java +++ b/src/main/java/org/opentripplanner/model/StopPattern.java @@ -2,7 +2,9 @@ import java.io.Serializable; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.function.Function; import com.google.common.hash.HashCode; @@ -54,6 +56,8 @@ public class StopPattern implements Serializable { public final int[] pickups; public final int[] dropoffs; + public final List[] alternateStops; + /** GTFS-Flex specific fields; will be null unless GTFS-Flex dataset is in use. */ private StopPatternFlexFields flexFields; @@ -95,17 +99,19 @@ public String toString() { * @param stopTimes List of StopTimes; assumes that stopTimes are already sorted by time. * @param deduplicator Deduplicator. If null, do not deduplicate arrays. */ - public StopPattern (List stopTimes, Deduplicator deduplicator) { + public StopPattern (List stopTimes, Map> alternateStops, Deduplicator deduplicator) { this.size = stopTimes.size(); if (size == 0) { this.stops = new Stop[size]; this.pickups = new int[0]; this.dropoffs = new int[0]; + this.alternateStops = new List[0]; return; } stops = new Stop[size]; int[] pickups = new int[size]; int[] dropoffs = new int[size]; + this.alternateStops = new List[size]; for (int i = 0; i < size; ++i) { StopTime stopTime = stopTimes.get(i); stops[i] = stopTime.getStop(); @@ -113,6 +119,7 @@ public StopPattern (List stopTimes, Deduplicator deduplicator) { // pick/drop messages could be stored in individual trips pickups[i] = stopTime.getPickupType(); dropoffs[i] = stopTime.getDropOffType(); + this.alternateStops[i] = alternateStops.getOrDefault(new FeedScopedId(stopTime.getStop().getId().getAgencyId(), stopTime.getStop().getParentStation()), Collections.emptyList()); } /* * TriMet GTFS has many trips that differ only in the pick/drop status of their initial and @@ -139,7 +146,7 @@ public StopPattern (List stopTimes, Deduplicator deduplicator) { * @param stopTimes List of StopTimes; assumes that stopTimes are already sorted by time. */ public StopPattern (List stopTimes) { - this(stopTimes, null); + this(stopTimes, Collections.emptyMap(), null); } /** diff --git a/src/main/java/org/opentripplanner/routing/edgetype/Timetable.java b/src/main/java/org/opentripplanner/routing/edgetype/Timetable.java index 938ea38e0ba..4561e8fbaeb 100644 --- a/src/main/java/org/opentripplanner/routing/edgetype/Timetable.java +++ b/src/main/java/org/opentripplanner/routing/edgetype/Timetable.java @@ -550,6 +550,7 @@ public TripTimes createUpdatedTripTimes(TripUpdate tripUpdate, TimeZone timeZone Integer delay = null; Integer firstDelay = null; boolean hasMatched = false; + FeedScopedId deviationStop = null; for (int i = 0; i < numStops; i++) { boolean match = false; if (update != null) { @@ -557,6 +558,16 @@ public TripTimes createUpdatedTripTimes(TripUpdate tripUpdate, TimeZone timeZone match = update.getStopSequence() == newTimes.getStopSequence(i); } else if (update.hasStopId()) { match = pattern.getStop(i).getId().getId().equals(update.getStopId()); + //Check if the trip has been deviated to another stop within the same station + if (!match && pattern.stopPattern.alternateStops[i] != null) { + for (Stop alternateStop : pattern.stopPattern.alternateStops[i]) { + if (alternateStop.getId().getId().equals(update.getStopId())) { + deviationStop = alternateStop.getId(); + match = true; + break; + } + } + } } } @@ -565,6 +576,9 @@ public TripTimes createUpdatedTripTimes(TripUpdate tripUpdate, TimeZone timeZone StopTimeUpdate.ScheduleRelationship scheduleRelationship = update.hasScheduleRelationship() ? update.getScheduleRelationship() : StopTimeUpdate.ScheduleRelationship.SCHEDULED; + if (deviationStop != null) { + newTimes.updateDeviationStop(i, deviationStop); + } if (scheduleRelationship == StopTimeUpdate.ScheduleRelationship.NO_DATA) { newTimes.updateArrivalDelay(i, 0); diff --git a/src/main/java/org/opentripplanner/routing/edgetype/factory/PatternHopFactory.java b/src/main/java/org/opentripplanner/routing/edgetype/factory/PatternHopFactory.java index fec36acca40..7d0b91e6128 100644 --- a/src/main/java/org/opentripplanner/routing/edgetype/factory/PatternHopFactory.java +++ b/src/main/java/org/opentripplanner/routing/edgetype/factory/PatternHopFactory.java @@ -6,6 +6,7 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.ListMultimap; import com.google.common.collect.Multimap; +import org.apache.commons.math3.util.Pair; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.CoordinateSequence; import org.locationtech.jts.geom.Geometry; @@ -82,16 +83,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; // Filtering out (removing) stoptimes from a trip forces us to either have two copies of that list, // or do all the steps within one loop over trips. It would be clearer if there were multiple loops over the trips. @@ -377,8 +371,11 @@ public void run(Graph graph) { boolean hasFlexService = stopTimes.stream().anyMatch(this::stopTimeHasFlex); + Map> alternateStops = transitService.getAllStops().stream() + .filter(stop -> stop.getLocationType() == 1) + .collect(Collectors.toMap(Stop::getId, transitService::getStopsForStation)); /* Get the existing TripPattern for this filtered StopPattern, or create one. */ - StopPattern stopPattern = new StopPattern(stopTimes, graph.deduplicator); + StopPattern stopPattern = new StopPattern(stopTimes, alternateStops, graph.deduplicator); if (hasFlexService) { stopPattern.setFlexFields(new StopPatternFlexFields(stopTimes, flexAreasById, graph.deduplicator)); } diff --git a/src/main/java/org/opentripplanner/routing/graph/GraphIndex.java b/src/main/java/org/opentripplanner/routing/graph/GraphIndex.java index 3cfa8ef52f5..6e3145de6fc 100644 --- a/src/main/java/org/opentripplanner/routing/graph/GraphIndex.java +++ b/src/main/java/org/opentripplanner/routing/graph/GraphIndex.java @@ -733,8 +733,29 @@ public Set routesForStop(Stop stop) { * Fetch upcoming vehicle departures from a stop. * Fetches two departures for each pattern during the next 24 hours as default */ - public Collection stopTimesForStop(Stop stop, boolean omitNonPickups, boolean omitCanceled) { - return stopTimesForStop(stop, System.currentTimeMillis()/1000, 24 * 60 * 60, 2, omitNonPickups, omitCanceled); + public Collection stopTimesForStop(Stop stop, boolean omitNonPickups, boolean omitCanceled, boolean omitDeviated) { + return stopTimesForStop(stop, System.currentTimeMillis()/1000, 24 * 60 * 60, 2, omitNonPickups, omitCanceled, omitDeviated); + } + + /** + * Returns a list of patterns that go through the stop + * This includes patterns that do not go throught the stop in the static schedule, but have been deviated to it with trip updates + * @param stop Stop + * @return List of patterns + */ + private Collection getPatternsForStop(Stop stop) { + return patternsForStop.get(stop).stream() + .flatMap(tripPattern -> { + int stopIndex = tripPattern.getStops().indexOf(stop); + + if (stopIndex == -1) { + return Stream.empty(); + } + + return Stream.concat(Stream.of(tripPattern.stopPattern.stops[stopIndex]), tripPattern.stopPattern.alternateStops[stopIndex].stream()); + }) + .flatMap(s -> patternsForStop.get(s).stream()) + .collect(Collectors.toSet()); } /** @@ -749,13 +770,14 @@ public Collection stopTimesForStop(Stop stop, boolean omitNo * @param timeRange Searches forward for timeRange seconds from startTime * @param numberOfDepartures Number of departures to fetch per pattern * @param omitNonPickups If true, do not include vehicles that will not pick up passengers. + * @param omitDeviated Whether trips that have been deviated to this stop should be included * @return */ - public List stopTimesForStop(final Stop stop, final long startTime, final int timeRange, final int numberOfDepartures, boolean omitNonPickups, boolean omitCanceled) { + public List stopTimesForStop(final Stop stop, final long startTime, final int timeRange, final int numberOfDepartures, boolean omitNonPickups, boolean omitCanceled, boolean omitDeviated) { final List ret = new ArrayList<>(); - for (final TripPattern pattern : patternsForStop.get(stop)) { + for (final TripPattern pattern : (omitDeviated ? patternsForStop.get(stop) : getPatternsForStop(stop))) { final List stopTimesForStop = stopTimesForPattern(stop, pattern, startTime, timeRange, numberOfDepartures, omitNonPickups, omitCanceled); @@ -831,15 +853,18 @@ protected boolean lessThan(final TripTimeShort t1, final TripTimeShort t2) { int stopIndex = 0; // loop through all stops of pattern - for (final Stop currStop : pattern.stopPattern.stops) { - if (currStop.equals(stop)) { + for (int i = 0; i < pattern.stopPattern.size; i++) { + Set stops = new HashSet<>(); + stops.add(pattern.stopPattern.stops[i]); + stops.addAll(pattern.stopPattern.alternateStops[i]); + if (stops.contains(stop)) { if(omitNonPickups && pattern.stopPattern.pickups[stopIndex] == pattern.stopPattern.PICKDROP_NONE) continue; for (final TripTimes triptimes : tt.tripTimes) { if (!sd.serviceRunning(triptimes.serviceCode)) continue; int stopDepartureTime = triptimes.getDepartureTime(stopIndex); if (!(omitCanceled && triptimes.isCanceledDeparture(stopIndex)) && stopDepartureTime >= starttimeSecondsSinceMidnight && stopDepartureTime < starttimeSecondsSinceMidnight + timeRange) { - ret.insertWithOverflow(new TripTimeShort(triptimes, stopIndex, currStop, sd)); + ret.insertWithOverflow(new TripTimeShort(triptimes, stopIndex, stop, sd)); } } @@ -852,7 +877,7 @@ protected boolean lessThan(final TripTimeShort t1, final TripTimeShort t2) { - freq.tripTimes.getDepartureTime(0); while (departureTime <= lastDeparture && ret.size() < numberOfDepartures) { ret.insertWithOverflow(new TripTimeShort(freq.materialize(stopIndex, departureTime, true), - stopIndex, currStop, sd)); + stopIndex, stop, sd)); departureTime += freq.headway; } } @@ -878,15 +903,16 @@ protected boolean lessThan(final TripTimeShort t1, final TripTimeShort t2) { * @param stop Stop object to perform the search for * @param serviceDate Return all departures for the specified date * @param omitCanceled + * @param omitDeviated Whether trips that have been deviated to this stop should be included * @return */ - public List getStopTimesForStop(Stop stop, ServiceDate serviceDate, boolean omitNonPickups, boolean omitCanceled) { + public List getStopTimesForStop(Stop stop, ServiceDate serviceDate, boolean omitNonPickups, boolean omitCanceled, boolean omitDeviated) { List ret = new ArrayList<>(); TimetableSnapshot snapshot = null; if (graph.timetableSnapshotSource != null) { snapshot = graph.timetableSnapshotSource.getTimetableSnapshot(); } - Collection patterns = patternsForStop.get(stop); + Collection patterns = omitDeviated ? patternsForStop.get(stop) : getPatternsForStop(stop); for (TripPattern pattern : patterns) { StopTimesInPattern stopTimes = new StopTimesInPattern(pattern); Timetable tt; @@ -897,8 +923,11 @@ public List getStopTimesForStop(Stop stop, ServiceDate servi } ServiceDay sd = new ServiceDay(graph, serviceDate, calendarService, pattern.route.getAgency().getId()); int sidx = 0; - for (Stop currStop : pattern.stopPattern.stops) { - if (currStop.equals(stop)) { + for (int i = 0; i < pattern.stopPattern.size; i++) { + Set stops = new HashSet<>(); + stops.add(pattern.stopPattern.stops[i]); + stops.addAll(pattern.stopPattern.alternateStops[i]); + if (stops.contains(stop)) { if(omitNonPickups && pattern.stopPattern.pickups[sidx] == pattern.stopPattern.PICKDROP_NONE) continue; for (TripTimes t : tt.tripTimes) { if (!sd.serviceRunning(t.serviceCode)) continue; diff --git a/src/main/java/org/opentripplanner/routing/trippattern/TripTimes.java b/src/main/java/org/opentripplanner/routing/trippattern/TripTimes.java index 1197094c11a..f5091920f85 100644 --- a/src/main/java/org/opentripplanner/routing/trippattern/TripTimes.java +++ b/src/main/java/org/opentripplanner/routing/trippattern/TripTimes.java @@ -1,12 +1,19 @@ package org.opentripplanner.routing.trippattern; +import java.io.Serializable; +import java.util.Arrays; +import java.util.BitSet; +import java.util.List; + import com.google.common.hash.HashCode; import com.google.common.hash.HashFunction; import com.google.common.hash.Hasher; -import org.opentripplanner.common.MavenVersion; -import org.opentripplanner.gtfs.BikeAccess; + +import org.opentripplanner.model.FeedScopedId; import org.opentripplanner.model.StopTime; import org.opentripplanner.model.Trip; +import org.opentripplanner.common.MavenVersion; +import org.opentripplanner.gtfs.BikeAccess; import org.opentripplanner.routing.core.RoutingRequest; import org.opentripplanner.routing.core.ServiceDay; import org.opentripplanner.routing.core.State; @@ -15,10 +22,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.Serializable; -import java.util.Arrays; -import java.util.BitSet; -import java.util.List; /** * A TripTimes represents the arrival and departure times for a single trip in an Timetable. It is carried @@ -84,6 +87,8 @@ public class TripTimes implements Serializable, Comparable, Cloneable */ int[] departureTimes; + FeedScopedId[] deviationStops; + BitSet canceledArrivalTimes; BitSet canceledDepartureTimes; @@ -203,6 +208,7 @@ public TripTimes(final Trip trip, final List stopTimes, final Deduplic // We cannot point to the scheduled times because they are shifted, and updated times are not. this.arrivalTimes = null; this.departureTimes = null; + this.deviationStops = null; this.timepoints = deduplicator.deduplicateBitSet(timepoints); this.continuousPickup = deduplicator.deduplicateIntArray(continuousPickup); this.continuousDropOff = deduplicator.deduplicateIntArray(continuousDropOff); @@ -433,6 +439,10 @@ public String getServiceArea(final int stop) { return serviceArea[stop]; } + public FeedScopedId getDeviationStop(final int stopIndex) { + return deviationStops[stopIndex]; + } + /** Used in debugging / dumping times. */ public static String formatSeconds(int s) { int m = s / 60; @@ -525,6 +535,14 @@ public void updateArrivalDelay(final int stop, final int delay) { arrivalTimes[stop] = scheduledArrivalTimes[stop] + timeShift + delay; } + public void updateDeviationStop(final int stopIndex, FeedScopedId deviationStop) { + if (deviationStops == null) { + deviationStops = new FeedScopedId[scheduledArrivalTimes.length]; + } + + deviationStops[stopIndex] = deviationStop; + } + /** * If they don't already exist, create arrays for updated arrival and departure times * that are just time-shifted copies of the zero-based scheduled departure times. diff --git a/src/main/java/org/opentripplanner/updater/stoptime/TimetableSnapshotSource.java b/src/main/java/org/opentripplanner/updater/stoptime/TimetableSnapshotSource.java index 627e6791b57..1965598497c 100644 --- a/src/main/java/org/opentripplanner/updater/stoptime/TimetableSnapshotSource.java +++ b/src/main/java/org/opentripplanner/updater/stoptime/TimetableSnapshotSource.java @@ -1,10 +1,21 @@ package org.opentripplanner.updater.stoptime; +import java.text.ParseException; +import java.util.*; +import java.util.concurrent.locks.ReentrantLock; + import com.google.common.base.Preconditions; import com.google.transit.realtime.GtfsRealtime.TripDescriptor; import com.google.transit.realtime.GtfsRealtime.TripUpdate; import com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeUpdate; -import org.opentripplanner.model.*; + +import org.opentripplanner.model.Agency; +import org.opentripplanner.model.FeedScopedId; +import org.opentripplanner.model.Route; +import org.opentripplanner.model.Stop; +import org.opentripplanner.model.StopPattern; +import org.opentripplanner.model.StopTime; +import org.opentripplanner.model.Trip; import org.opentripplanner.model.calendar.ServiceDate; import org.opentripplanner.routing.edgetype.Timetable; import org.opentripplanner.routing.edgetype.TimetableSnapshot; @@ -18,9 +29,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.text.ParseException; -import java.util.*; -import java.util.concurrent.locks.ReentrantLock; /** * This class should be used to create snapshots of lookup tables of realtime data. This is @@ -683,7 +691,7 @@ private boolean addTripToGraphAndBuffer(final String feedId, final Graph graph, // TODO: filter/interpolate stop times like in PatternHopFactory? // Create StopPattern - final StopPattern stopPattern = new StopPattern(stopTimes, graph.deduplicator); + final StopPattern stopPattern = new StopPattern(stopTimes, /*TODO: alternate stops for added trips*/ Collections.emptyMap(), graph.deduplicator); // Get cached trip pattern or create one if it doesn't exist yet final TripPattern pattern = tripPatternCache.getOrCreateTripPattern(stopPattern, trip.getRoute(), graph);