Search in sources :

Example 36 with TransitStop

use of org.opentripplanner.routing.vertextype.TransitStop in project OpenTripPlanner by opentripplanner.

the class TransitStopsRegionsSourceImpl method getRegions.

@Override
public Iterable<Envelope> getRegions() {
    List<Envelope> regions = new ArrayList<Envelope>();
    for (Vertex gv : task.getGraph().getVertices()) {
        if (gv instanceof TransitStop) {
            Coordinate c = gv.getCoordinate();
            Envelope env = new Envelope(c);
            double meters_per_degree_lon_here = METERS_PER_DEGREE_LAT * Math.cos(Math.toRadians(c.y));
            env.expandBy(distance / meters_per_degree_lon_here, distance / METERS_PER_DEGREE_LAT);
            regions.add(env);
        }
    }
    LOG.debug("Total regions: " + regions.size());
    return regions;
}
Also used : Vertex(org.opentripplanner.routing.graph.Vertex) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) Coordinate(com.vividsolutions.jts.geom.Coordinate) ArrayList(java.util.ArrayList) Envelope(com.vividsolutions.jts.geom.Envelope)

Example 37 with TransitStop

use of org.opentripplanner.routing.vertextype.TransitStop in project OpenTripPlanner by opentripplanner.

the class GTFSPatternHopFactory method run.

/**
 * Generate the edges. Assumes that there are already vertices in the graph for the stops.
 */
public void run(Graph graph) {
    if (fareServiceFactory == null) {
        fareServiceFactory = new DefaultFareServiceFactory();
    }
    fareServiceFactory.processGtfs(_dao);
    // TODO: Why are we loading stops? The Javadoc above says this method assumes stops are aleady loaded.
    loadStops(graph);
    loadPathways(graph);
    loadFeedInfo(graph);
    loadAgencies(graph);
    // TODO: Why is there cached "data", and why are we clearing it? Due to a general lack of comments, I have no idea.
    // Perhaps it is to allow name collisions with previously loaded feeds.
    clearCachedData();
    /* Assign 0-based numeric codes to all GTFS service IDs. */
    for (AgencyAndId serviceId : _dao.getAllServiceIds()) {
        // TODO: FIX Service code collision for multiple feeds.
        graph.serviceCodes.put(serviceId, graph.serviceCodes.size());
    }
    LOG.debug("building hops from trips");
    Collection<Trip> trips = _dao.getAllTrips();
    int tripCount = 0;
    /* First, record which trips are used by one or more frequency entries.
         * These trips will be ignored for the purposes of non-frequency routing, and
         * all the frequency entries referencing the same trip can be added at once to the same
         * Timetable/TripPattern.
         */
    ListMultimap<Trip, Frequency> frequenciesForTrip = ArrayListMultimap.create();
    for (Frequency freq : _dao.getAllFrequencies()) {
        frequenciesForTrip.put(freq.getTrip(), freq);
    }
    /* Then loop over all trips, handling each one as a frequency-based or scheduled trip. */
    int freqCount = 0;
    int nonFreqCount = 0;
    /* The hops don't actually exist when we build their geometries, but we have to build their geometries
         * below, 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.
         *
         *  A trip pattern actually does not have a single geometry, but one per hop, so we store an array.
         *  FIXME _why_ doesn't it have a single geometry?
         */
    Map<TripPattern, LineString[]> geometriesByTripPattern = Maps.newHashMap();
    TRIP: for (Trip trip : trips) {
        if (++tripCount % 100000 == 0) {
            LOG.debug("loading trips {}/{}", tripCount, trips.size());
        }
        // TODO: move to a validator module
        if (!_calendarService.getServiceIds().contains(trip.getServiceId())) {
            LOG.warn(graph.addBuilderAnnotation(new TripUndefinedService(trip)));
            // Invalid trip, skip it, it will break later
            continue TRIP;
        }
        /* Fetch the stop times for this trip. Copy the list since it's immutable. */
        List<StopTime> stopTimes = new ArrayList<StopTime>(_dao.getStopTimesForTrip(trip));
        /* GTFS stop times frequently contain duplicate, missing, or incorrect entries. Repair them. */
        TIntList removedStopSequences = removeRepeatedStops(stopTimes);
        if (!removedStopSequences.isEmpty()) {
            LOG.warn(graph.addBuilderAnnotation(new RepeatedStops(trip, removedStopSequences)));
        }
        filterStopTimes(stopTimes, graph);
        interpolateStopTimes(stopTimes);
        /* If after filtering this trip does not contain at least 2 stoptimes, it does not serve any purpose. */
        if (stopTimes.size() < 2) {
            LOG.warn(graph.addBuilderAnnotation(new TripDegenerate(trip)));
            continue TRIP;
        }
        /* Try to get the direction id for the trip, set to -1 if not found */
        int directionId;
        try {
            directionId = Integer.parseInt(trip.getDirectionId());
        } catch (NumberFormatException e) {
            LOG.debug("Trip {} does not have direction id, defaults to -1");
            directionId = -1;
        }
        /* Get the existing TripPattern for this filtered StopPattern, or create one. */
        StopPattern stopPattern = new StopPattern(stopTimes);
        TripPattern tripPattern = findOrCreateTripPattern(stopPattern, trip.getRoute(), directionId);
        /* Create a TripTimes object for this list of stoptimes, which form one trip. */
        TripTimes tripTimes = new TripTimes(trip, stopTimes, graph.deduplicator);
        /* If this trip is referenced by one or more lines in frequencies.txt, wrap it in a FrequencyEntry. */
        List<Frequency> frequencies = frequenciesForTrip.get(trip);
        if (frequencies != null && !(frequencies.isEmpty())) {
            for (Frequency freq : frequencies) {
                tripPattern.add(new FrequencyEntry(freq, tripTimes));
                freqCount++;
            }
        // TODO replace: createGeometry(graph, trip, stopTimes, hops);
        } else /* This trip was not frequency-based. Add the TripTimes directly to the TripPattern's scheduled timetable. */
        {
            tripPattern.add(tripTimes);
            nonFreqCount++;
        }
        // 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(graph, trip, stopTimes));
        }
    }
    // end foreach TRIP
    LOG.info("Added {} frequency-based and {} single-trip timetable entries.", freqCount, nonFreqCount);
    graph.hasFrequencyService = graph.hasFrequencyService || freqCount > 0;
    graph.hasScheduledService = graph.hasScheduledService || nonFreqCount > 0;
    /* Generate unique human-readable names for all the TableTripPatterns. */
    TripPattern.generateUniqueNames(tripPatterns.values());
    /* Generate unique short IDs for all the TableTripPatterns. */
    TripPattern.generateUniqueIds(tripPatterns.values());
    /* Loop over all new TripPatterns, creating edges, setting the service codes and geometries, etc. */
    for (TripPattern tripPattern : tripPatterns.values()) {
        tripPattern.makePatternVerticesAndEdges(graph, context.stationStopNodes);
        // Add the geometries to the hop edges.
        LineString[] geom = geometriesByTripPattern.get(tripPattern);
        if (geom != null) {
            for (int i = 0; i < tripPattern.hopEdges.length; i++) {
                tripPattern.hopEdges[i].setGeometry(geom[i]);
            }
            // Make a geometry for the whole TripPattern from all its constituent hops.
            // This happens only if geometry is found in geometriesByTripPattern,
            // because that means that geometry was created from shapes instead "as crow flies"
            tripPattern.makeGeometry();
        }
        // TODO this could be more elegant
        tripPattern.setServiceCodes(graph.serviceCodes);
        /* Iterate over all stops in this pattern recording mode information. */
        TraverseMode mode = GtfsLibrary.getTraverseMode(tripPattern.route);
        for (TransitStop tstop : tripPattern.stopVertices) {
            tstop.addMode(mode);
            if (mode == TraverseMode.SUBWAY) {
                tstop.setStreetToStopTime(subwayAccessTime);
            }
            graph.addTransitMode(mode);
        }
    }
    /* Identify interlined trips and create the necessary edges. */
    interline(tripPatterns.values(), graph);
    /* Interpret the transfers explicitly defined in transfers.txt. */
    loadTransfers(graph);
    /* Store parent stops in graph, even if not linked. These are needed for clustering*/
    for (TransitStationStop stop : context.stationStopNodes.values()) {
        if (stop instanceof TransitStation) {
            TransitStation parentStopVertex = (TransitStation) stop;
            graph.parentStopById.put(parentStopVertex.getStopId(), parentStopVertex.getStop());
        }
    }
    // it is already done at deserialization, but standalone mode allows using graphs without serializing them.
    for (TripPattern tableTripPattern : tripPatterns.values()) {
        tableTripPattern.scheduledTimetable.finish();
    }
    // eh?
    clearCachedData();
    graph.putService(FareService.class, fareServiceFactory.makeFareService());
    graph.putService(OnBoardDepartService.class, new OnBoardDepartServiceImpl());
}
Also used : AgencyAndId(org.onebusaway.gtfs.model.AgencyAndId) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) FrequencyEntry(org.opentripplanner.routing.trippattern.FrequencyEntry) TripTimes(org.opentripplanner.routing.trippattern.TripTimes) TIntArrayList(gnu.trove.list.array.TIntArrayList) TIntList(gnu.trove.list.TIntList) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) TraverseMode(org.opentripplanner.routing.core.TraverseMode) DefaultFareServiceFactory(org.opentripplanner.routing.impl.DefaultFareServiceFactory) StopTime(org.onebusaway.gtfs.model.StopTime) StopPattern(org.opentripplanner.model.StopPattern) Trip(org.onebusaway.gtfs.model.Trip) TripUndefinedService(org.opentripplanner.graph_builder.annotation.TripUndefinedService) ShapePoint(org.onebusaway.gtfs.model.ShapePoint) TripPattern(org.opentripplanner.routing.edgetype.TripPattern) TransitStation(org.opentripplanner.routing.vertextype.TransitStation) TripDegenerate(org.opentripplanner.graph_builder.annotation.TripDegenerate) LineString(com.vividsolutions.jts.geom.LineString) Frequency(org.onebusaway.gtfs.model.Frequency) RepeatedStops(org.opentripplanner.graph_builder.annotation.RepeatedStops) TIntList(gnu.trove.list.TIntList) TransitStationStop(org.opentripplanner.routing.vertextype.TransitStationStop) OnBoardDepartServiceImpl(org.opentripplanner.routing.impl.OnBoardDepartServiceImpl)

Example 38 with TransitStop

use of org.opentripplanner.routing.vertextype.TransitStop in project OpenTripPlanner by opentripplanner.

the class GTFSPatternHopFactory method linkStopsToParentStations.

/**
 * Links the vertices representing parent stops to their child stops bidirectionally. This is
 * not intended to provide implicit transfers (i.e. child stop to parent station to another
 * child stop) but instead to allow beginning or ending a path (itinerary) at a parent station.
 *
 * Currently this linking is only intended for use in the long distance path service. The
 * pathparsers should ensure that it is effectively ignored in other path services, and even in
 * the long distance path service anywhere but the beginning or end of a path.
 */
public void linkStopsToParentStations(Graph graph) {
    for (Stop stop : _dao.getAllStops()) {
        String parentStation = stop.getParentStation();
        if (parentStation != null) {
            TransitStop stopVertex = (TransitStop) context.stationStopNodes.get(stop);
            String agencyId = stop.getId().getAgencyId();
            AgencyAndId parentStationId = new AgencyAndId(agencyId, parentStation);
            Stop parentStop = _dao.getStopForId(parentStationId);
            if (context.stationStopNodes.get(parentStop) instanceof TransitStation) {
                TransitStation parentStopVertex = (TransitStation) context.stationStopNodes.get(parentStop);
                new StationStopEdge(parentStopVertex, stopVertex);
                new StationStopEdge(stopVertex, parentStopVertex);
            } else {
                LOG.warn(graph.addBuilderAnnotation(new NonStationParentStation(stopVertex)));
            }
        }
    }
}
Also used : TransitStop(org.opentripplanner.routing.vertextype.TransitStop) AgencyAndId(org.onebusaway.gtfs.model.AgencyAndId) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) Stop(org.onebusaway.gtfs.model.Stop) TransitStationStop(org.opentripplanner.routing.vertextype.TransitStationStop) NonStationParentStation(org.opentripplanner.graph_builder.annotation.NonStationParentStation) LineString(com.vividsolutions.jts.geom.LineString) TransitStation(org.opentripplanner.routing.vertextype.TransitStation) StationStopEdge(org.opentripplanner.routing.edgetype.StationStopEdge)

Example 39 with TransitStop

use of org.opentripplanner.routing.vertextype.TransitStop in project OpenTripPlanner by opentripplanner.

the class ProfileRouter method makeSurfaces.

private void makeSurfaces() {
    LOG.info("Propagating from transit stops to the street network...");
    // A map to store the travel time to each vertex
    TimeSurface minSurface = new TimeSurface(this);
    TimeSurface avgSurface = new TimeSurface(this);
    TimeSurface maxSurface = new TimeSurface(this);
    // Grab a cached map of distances to street intersections from each transit stop
    StopTreeCache stopTreeCache = graph.index.getStopTreeCache();
    // Iterate over all nondominated rides at all clusters
    for (Entry<StopCluster, Ride> entry : retainedRides.entries()) {
        StopCluster cluster = entry.getKey();
        Ride ride = entry.getValue();
        for (Stop stop : cluster.children) {
            TransitStop tstop = graph.index.stopVertexForStop.get(stop);
            // Iterate over street intersections in the vicinity of this particular transit stop.
            // Shift the time range at this transit stop, merging it into that for all reachable street intersections.
            // FIXME stopTreeCache.getDistancesForStop(tstop);
            TObjectIntMap<Vertex> distanceToVertex = null;
            for (TObjectIntIterator<Vertex> iter = distanceToVertex.iterator(); iter.hasNext(); ) {
                iter.advance();
                Vertex vertex = iter.key();
                // distance in meters over walkspeed in meters per second --> seconds
                int egressWalkTimeSeconds = (int) (iter.value() / request.walkSpeed);
                if (egressWalkTimeSeconds > request.maxWalkTime * 60) {
                    continue;
                }
                int propagated_min = ride.dlb + egressWalkTimeSeconds;
                int propagated_max = ride.dub + egressWalkTimeSeconds;
                // FIXME HACK
                int propagated_avg = (int) (((long) propagated_min + propagated_max) / 2);
                int existing_min = minSurface.times.get(vertex);
                int existing_max = maxSurface.times.get(vertex);
                int existing_avg = avgSurface.times.get(vertex);
                // which is not necessarily wrong but it's a crude way to perform the combination
                if (existing_min == TimeSurface.UNREACHABLE || existing_min > propagated_min) {
                    minSurface.times.put(vertex, propagated_min);
                }
                if (existing_max == TimeSurface.UNREACHABLE || existing_max > propagated_max) {
                    maxSurface.times.put(vertex, propagated_max);
                }
                if (existing_avg == TimeSurface.UNREACHABLE || existing_avg > propagated_avg) {
                    avgSurface.times.put(vertex, propagated_avg);
                }
            }
        }
    }
    LOG.info("Done with propagation.");
    /* Store the results in a field in the router object. */
    timeSurfaceRangeSet = new TimeSurface.RangeSet();
    timeSurfaceRangeSet.min = minSurface;
    timeSurfaceRangeSet.max = maxSurface;
    timeSurfaceRangeSet.avg = avgSurface;
}
Also used : Vertex(org.opentripplanner.routing.graph.Vertex) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) Stop(org.onebusaway.gtfs.model.Stop) TimeSurface(org.opentripplanner.analyst.TimeSurface)

Example 40 with TransitStop

use of org.opentripplanner.routing.vertextype.TransitStop in project OpenTripPlanner by opentripplanner.

the class RaptorWorkerData method findStopsNear.

/**
 * find stops from a given SPT, including temporary stops. If useTimes is true, use times from the SPT, otherwise use distances
 */
public TIntIntMap findStopsNear(ShortestPathTree spt, Graph graph, boolean useTimes, float walkSpeed) {
    TIntIntMap accessTimes = new TIntIntHashMap();
    for (TransitStop tstop : graph.index.stopVertexForStop.values()) {
        State s = spt.getState(tstop);
        if (s != null) {
            // note that we calculate the time based on the walk speed here rather than
            // based on the time. this matches what we do in the stop tree cache.
            int stopIndex = indexForStop.get(tstop.getIndex());
            if (stopIndex != -1) {
                if (useTimes)
                    accessTimes.put(stopIndex, (int) s.getElapsedTimeSeconds());
                else
                    accessTimes.put(stopIndex, (int) (s.getWalkDistance() / walkSpeed));
            }
        }
    }
    // and handle the additional stops
    for (TObjectIntIterator<AddTripPattern.TemporaryStop> it = addedStops.iterator(); it.hasNext(); ) {
        it.advance();
        AddTripPattern.TemporaryStop tstop = it.key();
        if (tstop.sample == null) {
            continue;
        }
        double dist = Double.POSITIVE_INFINITY;
        if (tstop.sample.v0 != null) {
            State s0 = spt.getState(tstop.sample.v0);
            if (s0 != null) {
                dist = s0.getWalkDistance() + tstop.sample.d0;
            }
        }
        if (tstop.sample.v1 != null) {
            State s1 = spt.getState(tstop.sample.v1);
            if (s1 != null) {
                double d1 = s1.getWalkDistance() + tstop.sample.d1;
                dist = Double.isInfinite(dist) ? d1 : Math.min(d1, dist);
            }
        }
        if (Double.isInfinite(dist))
            continue;
        // NB using the index in the worker data not the index in the graph!
        accessTimes.put(it.value(), (int) (dist / walkSpeed));
    }
    return accessTimes;
}
Also used : AddTripPattern(org.opentripplanner.analyst.scenario.AddTripPattern) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) State(org.opentripplanner.routing.core.State) TIntIntHashMap(gnu.trove.map.hash.TIntIntHashMap) TIntIntMap(gnu.trove.map.TIntIntMap)

Aggregations

TransitStop (org.opentripplanner.routing.vertextype.TransitStop)49 Stop (org.onebusaway.gtfs.model.Stop)20 Vertex (org.opentripplanner.routing.graph.Vertex)18 Edge (org.opentripplanner.routing.graph.Edge)15 AgencyAndId (org.onebusaway.gtfs.model.AgencyAndId)13 RoutingRequest (org.opentripplanner.routing.core.RoutingRequest)12 Coordinate (com.vividsolutions.jts.geom.Coordinate)11 TripPattern (org.opentripplanner.routing.edgetype.TripPattern)11 Graph (org.opentripplanner.routing.graph.Graph)10 Envelope (com.vividsolutions.jts.geom.Envelope)8 LineString (com.vividsolutions.jts.geom.LineString)8 ArrayList (java.util.ArrayList)8 State (org.opentripplanner.routing.core.State)8 StreetEdge (org.opentripplanner.routing.edgetype.StreetEdge)8 Agency (org.onebusaway.gtfs.model.Agency)7 Trip (org.onebusaway.gtfs.model.Trip)7 SimpleTransfer (org.opentripplanner.routing.edgetype.SimpleTransfer)7 ShortestPathTree (org.opentripplanner.routing.spt.ShortestPathTree)7 IntersectionVertex (org.opentripplanner.routing.vertextype.IntersectionVertex)7 Route (org.onebusaway.gtfs.model.Route)6