All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opentripplanner.updater.GtfsRealtimeFuzzyTripMatcher Maven / Gradle / Ivy

package org.opentripplanner.updater;

import com.google.transit.realtime.GtfsRealtime.TripDescriptor;
import org.opentripplanner.model.FeedScopedId;
import org.opentripplanner.model.Route;
import org.opentripplanner.model.Trip;
import org.opentripplanner.model.TripPattern;
import org.opentripplanner.model.calendar.ServiceDate;
import org.opentripplanner.routing.RoutingService;
import org.opentripplanner.routing.trippattern.TripTimes;
import org.opentripplanner.util.TimeToStringConverter;

import java.text.ParseException;
import java.util.BitSet;

/**
 * This class is used for matching TripDescriptors without trip_ids to scheduled GTFS data and to
 * feed back that information into a new TripDescriptor with proper trip_id.
 *
 * The class should only be used if we know that the feed producer is unable to produce trip_ids
 * in the GTFS-RT feed.
 */
public class GtfsRealtimeFuzzyTripMatcher {

    private RoutingService routingService;

    public GtfsRealtimeFuzzyTripMatcher(RoutingService routingService) {
        this.routingService = routingService;
    }

    public TripDescriptor match(String feedId, TripDescriptor trip) {
        if (trip.hasTripId()) {
            // trip_id already exists
            return trip;
        }

        if (!trip.hasRouteId() || !trip.hasDirectionId() ||
                !trip.hasStartTime() || !trip.hasStartDate()) {
            // Could not determine trip_id, returning original TripDescriptor
            return trip;
        }

        FeedScopedId routeId = new FeedScopedId(feedId, trip.getRouteId());
        int time = TimeToStringConverter.parseHH_MM_SS(trip.getStartTime());
        ServiceDate date;
        try {
            date = ServiceDate.parseString(trip.getStartDate());
        } catch (ParseException e) {
            return trip;
        }
        Route route = routingService.getRouteForId(routeId);
        if (route == null) {
            return trip;
        }
        int direction = trip.getDirectionId();

        Trip matchedTrip = getTrip(route, direction, time, date);

        if (matchedTrip == null) {
            // Check if the trip is carried over from previous day
            date = date.previous();
            time += 24*60*60;
            matchedTrip = getTrip(route, direction, time, date);
        }

        if (matchedTrip == null) {
            return trip;
        }

        // If everything succeeds, build a new TripDescriptor with the matched trip_id
        return trip.toBuilder().setTripId(matchedTrip.getId().getId()).build();
    }

    public Trip getTrip (Route route, int direction, int startTime, ServiceDate date) {
        BitSet services = routingService.getServicesRunningForDate(date);
        for (TripPattern pattern : routingService.getPatternsForRoute().get(route)) {
            if (pattern.directionId != direction) continue;
            for (TripTimes times : pattern.scheduledTimetable.tripTimes) {
                if (times.getScheduledDepartureTime(0) == startTime &&
                        services.get(times.serviceCode)) {
                    return times.trip;
                }
            }
        }
        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy