Search in sources :

Example 16 with TransitStop

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

the class RoundBasedProfileRouter method makeSurfaces.

/**
 * analyst mode: propagate to street network
 */
private void makeSurfaces() {
    LOG.info("Propagating from transit stops to the street network...");
    List<State> lower = Lists.newArrayList();
    List<State> upper = Lists.newArrayList();
    List<State> avg = Lists.newArrayList();
    RoutingRequest rr = new RoutingRequest(TraverseMode.WALK);
    rr.batch = (true);
    rr.from = new GenericLocation(request.fromLat, request.fromLon);
    rr.setRoutingContext(graph);
    rr.longDistance = true;
    rr.dominanceFunction = new DominanceFunction.EarliestArrival();
    rr.setNumItineraries(1);
    rr.worstTime = rr.dateTime + CUTOFF_SECONDS;
    long startTime = rr.dateTime;
    State origin = new State(rr);
    // Multi-origin Dijkstra search; preinitialize the queue with states at each transit stop
    for (Collection<ProfileState> pss : retainedStates.asMap().values()) {
        TransitStop tstop = null;
        int lowerBound = Integer.MAX_VALUE;
        int upperBound = Integer.MAX_VALUE;
        for (ProfileState ps : pss) {
            if (tstop == null)
                tstop = ps.stop;
            if (ps.lowerBound < lowerBound)
                lowerBound = ps.lowerBound;
            if (ps.upperBound < upperBound)
                upperBound = ps.upperBound;
        }
        if (lowerBound == Integer.MAX_VALUE || upperBound == Integer.MAX_VALUE)
            throw new IllegalStateException("Invalid bound!");
        lower.add(new State(tstop, null, lowerBound + startTime, startTime, rr));
        upper.add(new State(tstop, null, upperBound + startTime, startTime, rr));
        // TODO extremely incorrect hack!
        avg.add(new State(tstop, null, (upperBound + lowerBound) / 2 + startTime, startTime, rr));
    }
    // get direct trips as well
    lower.add(origin);
    upper.add(origin);
    avg.add(origin);
    // create timesurfaces
    timeSurfaceRangeSet = new TimeSurface.RangeSet();
    AStar astar = new AStar();
    timeSurfaceRangeSet.min = new TimeSurface(astar.getShortestPathTree(rr, 20, null, lower), false);
    astar = new AStar();
    timeSurfaceRangeSet.max = new TimeSurface(astar.getShortestPathTree(rr, 20, null, upper), false);
    astar = new AStar();
    timeSurfaceRangeSet.avg = new TimeSurface(astar.getShortestPathTree(rr, 20, null, avg), false);
    rr.cleanup();
    LOG.info("Done with propagation.");
/* Store the results in a field in the router object. */
}
Also used : TransitStop(org.opentripplanner.routing.vertextype.TransitStop) TimeSurface(org.opentripplanner.analyst.TimeSurface) AStar(org.opentripplanner.routing.algorithm.AStar) RangeSet(org.opentripplanner.analyst.TimeSurface.RangeSet) State(org.opentripplanner.routing.core.State) GenericLocation(org.opentripplanner.common.model.GenericLocation) RoutingRequest(org.opentripplanner.routing.core.RoutingRequest) DominanceFunction(org.opentripplanner.routing.spt.DominanceFunction)

Example 17 with TransitStop

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

the class GTFSPatternHopFactory method loadStops.

private void loadStops(Graph graph) {
    for (Stop stop : _dao.getAllStops()) {
        if (context.stops.contains(stop.getId())) {
            LOG.error("Skipping stop {} because we already loaded an identical ID.", stop.getId());
            continue;
        }
        context.stops.add(stop.getId());
        int locationType = stop.getLocationType();
        // add a vertex representing the stop
        if (locationType == 1) {
            context.stationStopNodes.put(stop, new TransitStation(graph, stop));
        } else {
            TransitStop stopVertex = new TransitStop(graph, stop);
            context.stationStopNodes.put(stop, stopVertex);
            if (locationType != 2) {
                // Add a vertex representing arriving at the stop
                TransitStopArrive arrive = new TransitStopArrive(graph, stop, stopVertex);
                // FIXME no need for this context anymore, we just put references to these nodes in the stop vertices themselves.
                context.stopArriveNodes.put(stop, arrive);
                stopVertex.arriveVertex = arrive;
                // Add a vertex representing departing from the stop
                TransitStopDepart depart = new TransitStopDepart(graph, stop, stopVertex);
                // FIXME no need for this context anymore, we just put references to these nodes in the stop vertices themselves.
                context.stopDepartNodes.put(stop, depart);
                stopVertex.departVertex = depart;
                // Add edges from arrive to stop and stop to depart
                new PreAlightEdge(arrive, stopVertex);
                new PreBoardEdge(stopVertex, depart);
            }
        }
    }
}
Also used : PreAlightEdge(org.opentripplanner.routing.edgetype.PreAlightEdge) PreBoardEdge(org.opentripplanner.routing.edgetype.PreBoardEdge) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) Stop(org.onebusaway.gtfs.model.Stop) TransitStationStop(org.opentripplanner.routing.vertextype.TransitStationStop) TransitStopArrive(org.opentripplanner.routing.vertextype.TransitStopArrive) ShapePoint(org.onebusaway.gtfs.model.ShapePoint) TransitStation(org.opentripplanner.routing.vertextype.TransitStation) TransitStopDepart(org.opentripplanner.routing.vertextype.TransitStopDepart)

Example 18 with TransitStop

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

the class GraphIndex method clusterByProximityAndName.

/**
 * Cluster stops by proximity and name.
 * This functionality was developed for the Washington, DC area and probably will not work anywhere else in the
 * world. It depends on the exact way stops are named and the way street intersections are named in that geographic
 * region and in the GTFS data sets which represent it. Based on comments, apparently it might work for TriMet
 * as well.
 *
 * We can't use a name similarity comparison, we need exact matches. This is because many street names differ by
 * only one letter or number, e.g. 34th and 35th or Avenue A and Avenue B. Therefore normalizing the names before
 * the comparison is essential. The agency must provide either parent station information or a well thought out stop
 * naming scheme to cluster stops -- no guessing is reasonable without that information.
 */
private void clusterByProximityAndName() {
    // unique index for next parent stop
    int psIdx = 0;
    LOG.info("Clustering stops by geographic proximity and name...");
    // Each stop without a cluster will greedily claim other stops without clusters.
    for (Stop s0 : stopForId.values()) {
        // skip stops that have already been claimed by a cluster
        if (stopClusterForStop.containsKey(s0))
            continue;
        String s0normalizedName = StopNameNormalizer.normalize(s0.getName());
        StopCluster cluster = new StopCluster(String.format("C%03d", psIdx++), s0normalizedName);
        // LOG.info("stop {}", s0normalizedName);
        // No need to explicitly add s0 to the cluster. It will be found in the spatial index query below.
        Envelope env = new Envelope(new Coordinate(s0.getLon(), s0.getLat()));
        env.expandBy(SphericalDistanceLibrary.metersToLonDegrees(CLUSTER_RADIUS, s0.getLat()), SphericalDistanceLibrary.metersToDegrees(CLUSTER_RADIUS));
        for (TransitStop ts1 : stopSpatialIndex.query(env)) {
            Stop s1 = ts1.getStop();
            double geoDistance = SphericalDistanceLibrary.fastDistance(s0.getLat(), s0.getLon(), s1.getLat(), s1.getLon());
            if (geoDistance < CLUSTER_RADIUS) {
                String s1normalizedName = StopNameNormalizer.normalize(s1.getName());
                // LOG.info("       geodist {} stringdist {}", geoDistance, stringDistance);
                if (s1normalizedName.equals(s0normalizedName)) {
                    // Create a bidirectional relationship between the stop and its cluster
                    cluster.children.add(s1);
                    stopClusterForStop.put(s1, cluster);
                }
            }
        }
        cluster.computeCenter();
        stopClusterForId.put(cluster.id, cluster);
    }
}
Also used : TransitStop(org.opentripplanner.routing.vertextype.TransitStop) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) Stop(org.onebusaway.gtfs.model.Stop) Coordinate(com.vividsolutions.jts.geom.Coordinate) StopCluster(org.opentripplanner.profile.StopCluster) Envelope(com.vividsolutions.jts.geom.Envelope)

Example 19 with TransitStop

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

the class AnalystProfileRouterPrototype method route.

public TimeSurface.RangeSet route() {
    // NOT USED here, however FIXME this is not threadsafe, needs lock graph.index.clusterStopsAsNeeded();
    LOG.info("access modes: {}", request.accessModes);
    LOG.info("egress modes: {}", request.egressModes);
    LOG.info("direct modes: {}", request.directModes);
    // Establish search timeouts
    searchBeginTime = System.currentTimeMillis();
    abortTime = searchBeginTime + TIMEOUT * 1000;
    // TimeWindow could constructed in the caller, which does have access to the graph index.
    this.window = new TimeWindow(request.fromTime, request.toTime, graph.index.servicesRunning(request.date));
    fromStops = findClosestStops(TraverseMode.WALK);
    LOG.info("From patterns/stops: {}", fromStops);
    /* Initialize time range tracker to begin the search. */
    TimeRange.Tracker times = new TimeRange.Tracker();
    for (Stop stop : fromStops.keySet()) {
        times.set(stop, fromStops.get(stop));
    }
    Set<Stop> stopsUpdated = fromStops.keySet();
    for (int round = 0; round < MAX_RIDES; round++) {
        // TODO maybe even loop until no updates happen? That should happen automatically if MAX_RIDES is high enough.
        /* Get all patterns passing through stops updated in the last round, then reinitialize the updated stops set. */
        Set<TripPattern> patternsUpdated = uniquePatternsVisiting(stopsUpdated);
        LOG.info("ROUND {} : {} stops and {} patterns to explore.", round, stopsUpdated.size(), patternsUpdated.size());
        stopsUpdated = Sets.newHashSet();
        /* RAPTOR style: iterate over each pattern once. */
        for (TripPattern pattern : patternsUpdated) {
            // checkTimeout();
            TimeRange rangeBeingPropagated = null;
            List<Stop> stops = pattern.getStops();
            FrequencyEntry freq = pattern.getSingleFrequencyEntry();
            if (freq == null)
                continue;
            TripTimes tt = freq.tripTimes;
            int headway = freq.headway;
            for (int sidx = 0; sidx < stops.size(); sidx++) {
                Stop stop = stops.get(sidx);
                TimeRange existingRange = times.get(stop);
                TimeRange reBoardRange = (existingRange != null) ? existingRange.wait(headway) : null;
                if (rangeBeingPropagated == null) {
                    // We do not yet have a range worth propagating
                    if (reBoardRange != null) {
                        // this is a fresh protective copy
                        rangeBeingPropagated = reBoardRange;
                    }
                } else {
                    // We already have a range that is being propagated along the pattern.
                    // We are certain sidx >= 1 here because we have already boarded in a previous iteration.
                    TimeRange arrivalRange = rangeBeingPropagated.shift(tt.getRunningTime(sidx - 1));
                    if (times.add(stop, arrivalRange)) {
                        // The propagated time improved the best known time in some way.
                        stopsUpdated.add(stop);
                    }
                    // TODO handle case where arrival and departure are different
                    rangeBeingPropagated = arrivalRange.shift(tt.getDwellTime(sidx));
                    if (reBoardRange != null) {
                        rangeBeingPropagated.mergeIn(reBoardRange);
                    }
                }
            }
        }
        /* Transfer from updated stops to adjacent stops before beginning the next round.
               Iterate over a protective copy because we add more stops to the updated list during iteration. */
        if (!graph.hasDirectTransfers) {
            throw new RuntimeException("Requires the SimpleTransfers generated in long distance mode.");
        }
        for (Stop stop : Lists.newArrayList(stopsUpdated)) {
            Collection<Edge> outgoingEdges = graph.index.stopVertexForStop.get(stop).getOutgoing();
            for (SimpleTransfer transfer : Iterables.filter(outgoingEdges, SimpleTransfer.class)) {
                Stop targetStop = ((TransitStop) transfer.getToVertex()).getStop();
                double walkTime = transfer.getDistance() / request.walkSpeed;
                TimeRange rangeAfterTransfer = times.get(stop).shift((int) walkTime);
                if (times.add(targetStop, rangeAfterTransfer)) {
                    stopsUpdated.add(targetStop);
                }
            }
        }
    }
    LOG.info("Done with transit.");
    LOG.info("Propagating from transit stops to the street network...");
    // Grab a cached map of distances to street intersections from each transit stop
    StopTreeCache stopTreeCache = graph.index.getStopTreeCache();
    // Iterate over all stops that were reached in the transit part of the search
    for (Stop stop : times) {
        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.
        TimeRange rangeAtTransitStop = times.get(stop);
        // 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;
            }
            TimeRange propagatedRange = rangeAtTransitStop.shift(egressWalkTimeSeconds);
            TimeRange existingTimeRange = propagatedTimes.get(vertex);
            if (existingTimeRange == null) {
                propagatedTimes.put(vertex, propagatedRange);
            } else {
                existingTimeRange.mergeIn(propagatedRange);
            }
        }
    }
    LOG.info("Done with propagation.");
    TimeSurface.RangeSet result = TimeSurface.makeSurfaces(this);
    LOG.info("Done making time surfaces.");
    return result;
}
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) FrequencyEntry(org.opentripplanner.routing.trippattern.FrequencyEntry) TripPattern(org.opentripplanner.routing.edgetype.TripPattern) TripTimes(org.opentripplanner.routing.trippattern.TripTimes) SimpleTransfer(org.opentripplanner.routing.edgetype.SimpleTransfer) Edge(org.opentripplanner.routing.graph.Edge)

Example 20 with TransitStop

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

the class AlertPatch method remove.

public void remove(Graph graph) {
    Agency agency = null;
    if (feedId != null) {
        Map<String, Agency> agencies = graph.index.agenciesForFeedId.get(feedId);
        agency = this.agency != null ? agencies.get(this.agency) : null;
    }
    Route route = this.route != null ? graph.index.routeForId.get(this.route) : null;
    Stop stop = this.stop != null ? graph.index.stopForId.get(this.stop) : null;
    Trip trip = this.trip != null ? graph.index.tripForId.get(this.trip) : null;
    if (route != null || trip != null || agency != null) {
        Collection<TripPattern> tripPatterns = null;
        if (trip != null) {
            tripPatterns = new LinkedList<TripPattern>();
            TripPattern tripPattern = graph.index.patternForTrip.get(trip);
            if (tripPattern != null) {
                tripPatterns.add(tripPattern);
            }
        } else if (route != null) {
            tripPatterns = graph.index.patternsForRoute.get(route);
        } else {
            // Find patterns for the feed.
            tripPatterns = graph.index.patternsForFeedId.get(feedId);
        }
        if (tripPatterns != null) {
            for (TripPattern tripPattern : tripPatterns) {
                if (direction != null && !direction.equals(tripPattern.getDirection())) {
                    continue;
                }
                if (directionId != -1 && directionId != tripPattern.directionId) {
                    continue;
                }
                for (int i = 0; i < tripPattern.stopPattern.stops.length; i++) {
                    if (stop == null || stop.equals(tripPattern.stopPattern.stops[i])) {
                        graph.removeAlertPatch(tripPattern.boardEdges[i], this);
                        graph.removeAlertPatch(tripPattern.alightEdges[i], this);
                    }
                }
            }
        }
    } else if (stop != null) {
        TransitStop transitStop = graph.index.stopVertexForStop.get(stop);
        for (Edge edge : transitStop.getOutgoing()) {
            if (edge instanceof PreBoardEdge) {
                graph.removeAlertPatch(edge, this);
                break;
            }
        }
        for (Edge edge : transitStop.getIncoming()) {
            if (edge instanceof PreAlightEdge) {
                graph.removeAlertPatch(edge, this);
                break;
            }
        }
    }
}
Also used : Trip(org.onebusaway.gtfs.model.Trip) PreBoardEdge(org.opentripplanner.routing.edgetype.PreBoardEdge) Agency(org.onebusaway.gtfs.model.Agency) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) Stop(org.onebusaway.gtfs.model.Stop) TripPattern(org.opentripplanner.routing.edgetype.TripPattern) PreAlightEdge(org.opentripplanner.routing.edgetype.PreAlightEdge) PreAlightEdge(org.opentripplanner.routing.edgetype.PreAlightEdge) PreBoardEdge(org.opentripplanner.routing.edgetype.PreBoardEdge) Edge(org.opentripplanner.routing.graph.Edge) Route(org.onebusaway.gtfs.model.Route)

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