use of org.opentripplanner.graph_builder.annotation.HopZeroTime in project OpenTripPlanner by opentripplanner.
the class GTFSPatternHopFactory method filterStopTimes.
/**
* Scan through the given list, looking for clearly incorrect series of stoptimes and unsetting
* them. This includes duplicate times (0-time hops), as well as negative, fast or slow hops.
* Unsetting the arrival/departure time of clearly incorrect stoptimes will cause them to be
* interpolated in the next step. Annotations are also added to the graph to reveal the problems
* to the user.
*
* @param stopTimes the stoptimes to be filtered (from a single trip)
* @param graph the graph where annotations will be registered
*/
private void filterStopTimes(List<StopTime> stopTimes, Graph graph) {
if (stopTimes.size() < 2)
return;
StopTime st0 = stopTimes.get(0);
/* Set departure time if it is missing */
if (!st0.isDepartureTimeSet() && st0.isArrivalTimeSet()) {
st0.setDepartureTime(st0.getArrivalTime());
}
/* If the feed does not specify any timepoints, we want to mark all times that are present as timepoints. */
boolean hasTimepoints = false;
for (StopTime stopTime : stopTimes) {
if (stopTime.getTimepoint() == 1) {
hasTimepoints = true;
break;
}
}
// TODO verify that the first (and last?) stop should always be considered a timepoint.
if (!hasTimepoints)
st0.setTimepoint(1);
/* Indicates that stop times in this trip are being shifted forward one day. */
boolean midnightCrossed = false;
for (int i = 1; i < stopTimes.size(); i++) {
boolean st1bogus = false;
StopTime st1 = stopTimes.get(i);
/* If the feed did not specify any timepoints, mark all times that are present as timepoints. */
if (!hasTimepoints && (st1.isDepartureTimeSet() || st1.isArrivalTimeSet())) {
st1.setTimepoint(1);
}
if (midnightCrossed) {
if (st1.isDepartureTimeSet())
st1.setDepartureTime(st1.getDepartureTime() + 24 * SECONDS_IN_HOUR);
if (st1.isArrivalTimeSet())
st1.setArrivalTime(st1.getArrivalTime() + 24 * SECONDS_IN_HOUR);
}
// TODO: doc: what if arrival time is missing?
if (!st1.isDepartureTimeSet() && st1.isArrivalTimeSet()) {
st1.setDepartureTime(st1.getArrivalTime());
}
// All non-timepoint stoptimes in a series will have identical arrival and departure values of MISSING_VALUE.
if (!(st1.isArrivalTimeSet() && st1.isDepartureTimeSet())) {
continue;
}
int dwellTime = st0.getDepartureTime() - st0.getArrivalTime();
if (dwellTime < 0) {
LOG.warn(graph.addBuilderAnnotation(new NegativeDwellTime(st0)));
if (st0.getArrivalTime() > 23 * SECONDS_IN_HOUR && st0.getDepartureTime() < 1 * SECONDS_IN_HOUR) {
midnightCrossed = true;
st0.setDepartureTime(st0.getDepartureTime() + 24 * SECONDS_IN_HOUR);
} else {
st0.setDepartureTime(st0.getArrivalTime());
}
}
int runningTime = st1.getArrivalTime() - st0.getDepartureTime();
if (runningTime < 0) {
LOG.warn(graph.addBuilderAnnotation(new NegativeHopTime(new StopTime(st0), new StopTime(st1))));
// negative hops are usually caused by incorrect coding of midnight crossings
midnightCrossed = true;
if (st0.getDepartureTime() > 23 * SECONDS_IN_HOUR && st1.getArrivalTime() < 1 * SECONDS_IN_HOUR) {
st1.setArrivalTime(st1.getArrivalTime() + 24 * SECONDS_IN_HOUR);
} else {
st1.setArrivalTime(st0.getDepartureTime());
}
}
double hopDistance = SphericalDistanceLibrary.fastDistance(st0.getStop().getLat(), st0.getStop().getLon(), st1.getStop().getLat(), st1.getStop().getLon());
double hopSpeed = hopDistance / runningTime;
// sanity-check the hop
if (st0.getArrivalTime() == st1.getArrivalTime() || st0.getDepartureTime() == st1.getDepartureTime()) {
LOG.trace("{} {}", st0, st1);
// series of identical stop times at different stops
LOG.trace(graph.addBuilderAnnotation(new HopZeroTime((float) hopDistance, st1.getTrip(), st1.getStopSequence())));
// clear stoptimes that are obviously wrong, causing them to later be interpolated
/* FIXME (lines commented out because they break routability in multi-feed NYC for some reason -AMB) */
// st1.clearArrivalTime();
// st1.clearDepartureTime();
st1bogus = true;
} else if (hopSpeed > 45) {
// 45 m/sec ~= 100 miles/hr
// elapsed time of 0 will give speed of +inf
LOG.trace(graph.addBuilderAnnotation(new HopSpeedFast((float) hopSpeed, (float) hopDistance, st0.getTrip(), st0.getStopSequence())));
} else if (hopSpeed < 0.1) {
// 0.1 m/sec ~= 0.2 miles/hr
LOG.trace(graph.addBuilderAnnotation(new HopSpeedSlow((float) hopSpeed, (float) hopDistance, st0.getTrip(), st0.getStopSequence())));
}
// st0 should reflect the last stoptime that was not clearly incorrect
if (!st1bogus)
st0 = st1;
}
// END for loop over stop times
}
Aggregations