Search in sources :

Example 1 with HopZeroTime

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
}
Also used : NegativeHopTime(org.opentripplanner.graph_builder.annotation.NegativeHopTime) HopSpeedSlow(org.opentripplanner.graph_builder.annotation.HopSpeedSlow) NegativeDwellTime(org.opentripplanner.graph_builder.annotation.NegativeDwellTime) HopZeroTime(org.opentripplanner.graph_builder.annotation.HopZeroTime) HopSpeedFast(org.opentripplanner.graph_builder.annotation.HopSpeedFast) ShapePoint(org.onebusaway.gtfs.model.ShapePoint) StopTime(org.onebusaway.gtfs.model.StopTime)

Aggregations

ShapePoint (org.onebusaway.gtfs.model.ShapePoint)1 StopTime (org.onebusaway.gtfs.model.StopTime)1 HopSpeedFast (org.opentripplanner.graph_builder.annotation.HopSpeedFast)1 HopSpeedSlow (org.opentripplanner.graph_builder.annotation.HopSpeedSlow)1 HopZeroTime (org.opentripplanner.graph_builder.annotation.HopZeroTime)1 NegativeDwellTime (org.opentripplanner.graph_builder.annotation.NegativeDwellTime)1 NegativeHopTime (org.opentripplanner.graph_builder.annotation.NegativeHopTime)1