Search in sources :

Example 1 with TripPattern

use of org.opentripplanner.model.TripPattern in project OpenTripPlanner by opentripplanner.

the class NearbyStopFinder method findNearbyStopsConsideringPatterns.

/**
 * Find all unique nearby stops that are the closest stop on some trip pattern or flex trip.
 * Note that the result will include the origin vertex if it is an instance of StopVertex.
 * This is intentional: we don't want to return the next stop down the line for trip patterns that pass through the
 * origin vertex.
 */
public Set<StopAtDistance> findNearbyStopsConsideringPatterns(Vertex vertex, boolean reverseDirection) {
    /* Track the closest stop on each pattern passing nearby. */
    MinMap<TripPattern, StopAtDistance> closestStopForPattern = new MinMap<TripPattern, StopAtDistance>();
    /* Track the closest stop on each flex trip nearby. */
    MinMap<FlexTrip, StopAtDistance> closestStopForFlexTrip = new MinMap<>();
    /* Iterate over nearby stops via the street network or using straight-line distance, depending on the graph. */
    for (StopAtDistance stopAtDistance : findNearbyStops(vertex, reverseDirection)) {
        StopLocation ts1 = stopAtDistance.stop;
        if (ts1 instanceof Stop) {
            /* Consider this destination stop as a candidate for every trip pattern passing through it. */
            for (TripPattern pattern : graph.index.getPatternsForStop(ts1)) {
                closestStopForPattern.putMin(pattern, stopAtDistance);
            }
        }
        if (OTPFeature.FlexRouting.isOn()) {
            for (FlexTrip trip : graph.index.getFlexIndex().flexTripsByStop.get(ts1)) {
                closestStopForFlexTrip.putMin(trip, stopAtDistance);
            }
        }
    }
    /* Make a transfer from the origin stop to each destination stop that was the closest stop on any pattern. */
    Set<StopAtDistance> uniqueStops = Sets.newHashSet();
    uniqueStops.addAll(closestStopForFlexTrip.values());
    uniqueStops.addAll(closestStopForPattern.values());
    return uniqueStops;
}
Also used : FlexTrip(org.opentripplanner.ext.flex.trip.FlexTrip) MinMap(org.opentripplanner.common.MinMap) Stop(org.opentripplanner.model.Stop) StopAtDistance(org.opentripplanner.routing.graphfinder.StopAtDistance) StopLocation(org.opentripplanner.model.StopLocation) FlexStopLocation(org.opentripplanner.model.FlexStopLocation) TripPattern(org.opentripplanner.model.TripPattern)

Example 2 with TripPattern

use of org.opentripplanner.model.TripPattern in project OpenTripPlanner by opentripplanner.

the class GeometryAndBlockProcessor method run.

/**
 * Generate the edges. Assumes that there are already vertices in the graph for the stops.
 */
@SuppressWarnings("Convert2MethodRef")
public void run(Graph graph, DataImportIssueStore issueStore) {
    this.issueStore = issueStore;
    fareServiceFactory.processGtfs(transitService);
    /* Assign 0-based numeric codes to all GTFS service IDs. */
    for (FeedScopedId serviceId : transitService.getAllServiceIds()) {
        // TODO: FIX Service code collision for multiple feeds.
        graph.getServiceCodes().put(serviceId, graph.getServiceCodes().size());
    }
    LOG.info("Processing geometries and blocks on graph...");
    // Wwe have to build the hop geometries before we throw away the modified stopTimes, saving
    // only the tripTimes (which don't have enough information to build a geometry). So we keep
    // them here. In the current design, a trip pattern does not have a single geometry, but
    // one per hop, so we store them in an array.
    Map<TripPattern, LineString[]> geometriesByTripPattern = Maps.newHashMap();
    Collection<TripPattern> tripPatterns = transitService.getTripPatterns();
    /* Generate unique short IDs for all the TableTripPatterns. */
    if (!TripPattern.idsAreUniqueAndNotNull(tripPatterns)) {
        TripPattern.generateUniqueIds(tripPatterns);
    }
    /* Generate unique human-readable names for all the TableTripPatterns. */
    TripPattern.generateUniqueNames(tripPatterns, issueStore);
    /* Loop over all new TripPatterns, creating edges, setting the service codes and geometries, etc. */
    ProgressTracker progress = ProgressTracker.track("Generate TripPattern geometries", 100, tripPatterns.size());
    LOG.info(progress.startMessage());
    for (TripPattern tripPattern : tripPatterns) {
        for (Trip trip : tripPattern.getTrips()) {
            // there would be a trip pattern with no geometry yet because it failed some of these tests
            if (!geometriesByTripPattern.containsKey(tripPattern) && trip.getShapeId() != null && trip.getShapeId().getId() != null && !trip.getShapeId().getId().equals("")) {
                // save the geometry to later be applied to the hops
                geometriesByTripPattern.put(tripPattern, createGeometry(trip.getShapeId(), transitService.getStopTimesForTrip(trip)));
            }
        }
        // Keep lambda! A method-ref would causes incorrect class and line number to be logged
        progress.step(m -> LOG.info(m));
    }
    LOG.info(progress.completeMessage());
    /* Loop over all new TripPatterns setting the service codes and geometries, etc. */
    for (TripPattern tripPattern : tripPatterns) {
        LineString[] hopGeometries = geometriesByTripPattern.get(tripPattern);
        if (hopGeometries != null) {
            // Make a single unified geometry, and also store the per-hop split geometries.
            tripPattern.setHopGeometries(hopGeometries);
        }
        // TODO this could be more elegant
        tripPattern.setServiceCodes(graph.getServiceCodes());
        // Store the tripPattern in the Graph so it will be serialized and usable in routing.
        graph.tripPatternForId.put(tripPattern.getId(), tripPattern);
    }
    /* Identify interlined trips and create the necessary edges. */
    interline(tripPatterns, graph);
    // it is already done at deserialization, but standalone mode allows using graphs without serializing them.
    for (TripPattern tableTripPattern : tripPatterns) {
        tableTripPattern.scheduledTimetable.finish();
    }
    graph.putService(FareService.class, fareServiceFactory.makeFareService());
}
Also used : Trip(org.opentripplanner.model.Trip) ProgressTracker(org.opentripplanner.util.ProgressTracker) LineString(org.locationtech.jts.geom.LineString) FeedScopedId(org.opentripplanner.model.FeedScopedId) TripPattern(org.opentripplanner.model.TripPattern)

Example 3 with TripPattern

use of org.opentripplanner.model.TripPattern in project OpenTripPlanner by opentripplanner.

the class BusRouteStreetMatcher method buildGraph.

public void buildGraph(Graph graph, HashMap<Class<?>, Object> extra, DataImportIssueStore issueStore) {
    // Mapbuilder needs transit index
    graph.index();
    StreetMatcher matcher = new StreetMatcher(graph);
    log.info("Finding corresponding street edges for trip patterns...");
    // Why do we need to iterate over the routes? Why not just patterns?
    Collection<Route> allRoutes = graph.index.getAllRoutes();
    // Track progress
    ProgressTracker progress = ProgressTracker.track("Match route to street edges", 10, allRoutes.size());
    log.info(progress.startMessage());
    for (Route route : allRoutes) {
        for (TripPattern pattern : graph.index.getPatternsForRoute().get(route)) {
            if (pattern.getMode() == TransitMode.BUS) {
                /* we can only match geometry to streets on bus routes */
                log.debug("Matching {}", pattern);
                // that is why pattern.geometry is null in that case
                if (pattern.getGeometry() == null) {
                    continue;
                }
                for (int i = 0; i < pattern.numHopGeometries(); i++) {
                    LineString hopGeometry = pattern.getHopGeometry(i);
                    List<Edge> edges = matcher.match(hopGeometry);
                    if (edges == null || edges.isEmpty()) {
                        log.warn("Could not match to street network: {}", pattern);
                        continue;
                    }
                    List<Coordinate> coordinates = new ArrayList<>();
                    for (Edge e : edges) {
                        coordinates.addAll(Arrays.asList(e.getGeometry().getCoordinates()));
                    }
                    Coordinate[] coordinateArray = new Coordinate[coordinates.size()];
                    LineString ls = GeometryUtils.getGeometryFactory().createLineString(coordinates.toArray(coordinateArray));
                    // Replace the hop's geometry from GTFS with that of the equivalent OSM edges.
                    pattern.setHopGeometry(i, ls);
                }
            }
        }
        progress.step(log::info);
    }
    log.info(progress.completeMessage());
}
Also used : ProgressTracker(org.opentripplanner.util.ProgressTracker) ArrayList(java.util.ArrayList) TripPattern(org.opentripplanner.model.TripPattern) LineString(org.locationtech.jts.geom.LineString) Coordinate(org.locationtech.jts.geom.Coordinate) Edge(org.opentripplanner.routing.graph.Edge) Route(org.opentripplanner.model.Route)

Example 4 with TripPattern

use of org.opentripplanner.model.TripPattern in project OpenTripPlanner by opentripplanner.

the class SiriTimetableSnapshotSource method getTripForJourney.

/**
 * Finds the correct trip based on OTP-ServiceDate and SIRI-DepartureTime
 * @param trips
 * @param journey
 * @return
 */
private Set<Trip> getTripForJourney(Set<Trip> trips, EstimatedVehicleJourney journey) {
    List<RecordedCall> recordedCalls = (journey.getRecordedCalls() != null ? journey.getRecordedCalls().getRecordedCalls() : new ArrayList<>());
    List<EstimatedCall> estimatedCalls = journey.getEstimatedCalls().getEstimatedCalls();
    ZonedDateTime date;
    int stopNumber = 1;
    String firstStopId;
    if (recordedCalls != null && !recordedCalls.isEmpty()) {
        RecordedCall recordedCall = recordedCalls.get(0);
        date = recordedCall.getAimedDepartureTime();
        firstStopId = recordedCall.getStopPointRef().getValue();
    } else if (estimatedCalls != null && !estimatedCalls.isEmpty()) {
        EstimatedCall estimatedCall = estimatedCalls.get(0);
        if (estimatedCall.getOrder() != null) {
            stopNumber = estimatedCall.getOrder().intValue();
        } else if (estimatedCall.getVisitNumber() != null) {
            stopNumber = estimatedCall.getVisitNumber().intValue();
        }
        firstStopId = estimatedCall.getStopPointRef().getValue();
        date = estimatedCall.getAimedDepartureTime();
    } else {
        return null;
    }
    if (date == null) {
        // If no date is set - assume Realtime-data is reported for 'today'.
        date = ZonedDateTime.now();
    }
    ServiceDate serviceDate = new ServiceDate(date.getYear(), date.getMonthValue(), date.getDayOfMonth());
    int departureInSecondsSinceMidnight = calculateSecondsSinceMidnight(date);
    Set<Trip> result = new HashSet<>();
    for (Iterator<Trip> iterator = trips.iterator(); iterator.hasNext(); ) {
        Trip trip = iterator.next();
        Set<ServiceDate> serviceDatesForServiceId = routingService.getCalendarService().getServiceDatesForServiceId(trip.getServiceId());
        if (serviceDatesForServiceId.contains(serviceDate)) {
            TripPattern pattern = routingService.getPatternForTrip().get(trip);
            if (stopNumber < pattern.stopPattern.stops.length) {
                boolean firstReportedStopIsFound = false;
                Stop stop = pattern.stopPattern.stops[stopNumber - 1];
                if (firstStopId.equals(stop.getId().getId())) {
                    firstReportedStopIsFound = true;
                } else {
                    String agencyId = stop.getId().getFeedId();
                    if (stop.isPartOfStation()) {
                        Stop alternativeStop = routingService.getStopForId(new FeedScopedId(agencyId, firstStopId));
                        if (stop.isPartOfSameStationAs(alternativeStop)) {
                            firstReportedStopIsFound = true;
                        }
                    }
                }
                if (firstReportedStopIsFound) {
                    for (TripTimes times : getCurrentTimetable(pattern, serviceDate).tripTimes) {
                        if (times.getScheduledDepartureTime(stopNumber - 1) == departureInSecondsSinceMidnight) {
                            if (routingService.getCalendarService().getServiceDatesForServiceId(times.trip.getServiceId()).contains(serviceDate)) {
                                result.add(times.trip);
                            }
                        }
                    }
                }
            }
        }
    }
    if (result.size() >= 1) {
        return result;
    } else {
        return null;
    }
}
Also used : Trip(org.opentripplanner.model.Trip) Stop(org.opentripplanner.model.Stop) ArrayList(java.util.ArrayList) RecordedCall(uk.org.siri.siri20.RecordedCall) TripPattern(org.opentripplanner.model.TripPattern) ServiceDate(org.opentripplanner.model.calendar.ServiceDate) ZonedDateTime(java.time.ZonedDateTime) FeedScopedId(org.opentripplanner.model.FeedScopedId) TimetableHelper.createUpdatedTripTimes(org.opentripplanner.ext.siri.TimetableHelper.createUpdatedTripTimes) TripTimes(org.opentripplanner.routing.trippattern.TripTimes) EstimatedCall(uk.org.siri.siri20.EstimatedCall) HashSet(java.util.HashSet)

Example 5 with TripPattern

use of org.opentripplanner.model.TripPattern in project OpenTripPlanner by opentripplanner.

the class SiriTimetableSnapshotSource method addTripToGraphAndBuffer.

/**
 * Add a (new) trip to the graph and the buffer
 *
 * @return true if successful
 */
private boolean addTripToGraphAndBuffer(final String feedId, final Graph graph, final Trip trip, final List<StopTime> stopTimes, final List<Stop> stops, TripTimes updatedTripTimes, final ServiceDate serviceDate) {
    // Preconditions
    Preconditions.checkNotNull(stops);
    Preconditions.checkArgument(stopTimes.size() == stops.size(), "number of stop should match the number of stop time updates");
    // Create StopPattern
    final StopPattern stopPattern = new StopPattern(stopTimes);
    // Get cached trip pattern or create one if it doesn't exist yet
    final TripPattern pattern = tripPatternCache.getOrCreateTripPattern(stopPattern, trip, graph, serviceDate);
    // Add service code to bitset of pattern if needed (using copy on write)
    final int serviceCode = graph.getServiceCodes().get(trip.getServiceId());
    if (!pattern.getServices().get(serviceCode)) {
        final BitSet services = (BitSet) pattern.getServices().clone();
        services.set(serviceCode);
        pattern.setServices(services);
    }
    /*
         * Update pattern with triptimes so get correct dwell times and lower bound on running times.
         * New patterns only affects a single trip, previously added tripTimes is no longer valid, and is therefore removed
         */
    pattern.scheduledTimetable.tripTimes.clear();
    pattern.scheduledTimetable.addTripTimes(updatedTripTimes);
    pattern.scheduledTimetable.finish();
    // Remove trip times to avoid real time trip times being visible for ignoreRealtimeInformation queries
    pattern.scheduledTimetable.tripTimes.clear();
    // Add to buffer as-is to include it in the 'lastAddedTripPattern'
    buffer.update(pattern, updatedTripTimes, serviceDate);
    // TODO - SIRI: Add pattern to index?
    // Add new trip times to the buffer
    final boolean success = buffer.update(pattern, updatedTripTimes, serviceDate);
    return success;
}
Also used : StopPattern(org.opentripplanner.model.StopPattern) BitSet(java.util.BitSet) TripPattern(org.opentripplanner.model.TripPattern)

Aggregations

TripPattern (org.opentripplanner.model.TripPattern)61 Trip (org.opentripplanner.model.Trip)26 FeedScopedId (org.opentripplanner.model.FeedScopedId)23 Stop (org.opentripplanner.model.Stop)23 ArrayList (java.util.ArrayList)19 TripTimes (org.opentripplanner.routing.trippattern.TripTimes)19 Timetable (org.opentripplanner.model.Timetable)13 ServiceDate (org.opentripplanner.model.calendar.ServiceDate)13 Route (org.opentripplanner.model.Route)12 Test (org.junit.Test)11 HashSet (java.util.HashSet)8 RoutingService (org.opentripplanner.routing.RoutingService)8 List (java.util.List)7 StopPattern (org.opentripplanner.model.StopPattern)7 TimetableSnapshot (org.opentripplanner.model.TimetableSnapshot)7 GET (javax.ws.rs.GET)6 Path (javax.ws.rs.Path)6 StopTime (org.opentripplanner.model.StopTime)5 TripUpdate (com.google.transit.realtime.GtfsRealtime.TripUpdate)4 StopTimeUpdate (com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeUpdate)4