Search in sources :

Example 96 with Stop

use of org.onebusaway.gtfs.model.Stop in project OpenTripPlanner by opentripplanner.

the class GTFSPatternHopFactory method createParentStationTransfers.

/**
 * Create bidirectional, "free" edges (zero-time, low-cost edges) between stops and their
 * parent stations. This is used to produce implicit transfers between all stops that are
 * part of the same parent station. It was introduced as a workaround to allow in-station
 * transfers for underground/grade-separated transportation systems like the NYC subway (where
 * it's important to provide in-station transfers for fare computation).
 *
 * This step used to be automatically applied whenever transfers.txt was used to create
 * transfers (rather than or in addition to transfers through the street netowrk),
 * but has been separated out since it is really a separate process.
 */
public void createParentStationTransfers() {
    for (Stop stop : _dao.getAllStops()) {
        String parentStation = stop.getParentStation();
        if (parentStation != null) {
            Vertex stopVertex = context.stationStopNodes.get(stop);
            String agencyId = stop.getId().getAgencyId();
            AgencyAndId parentStationId = new AgencyAndId(agencyId, parentStation);
            Stop parentStop = _dao.getStopForId(parentStationId);
            Vertex parentStopVertex = context.stationStopNodes.get(parentStop);
            new FreeEdge(parentStopVertex, stopVertex);
            new FreeEdge(stopVertex, parentStopVertex);
            // Stops with location_type=2 (entrances as defined in the pathways.txt
            // proposal) have no arrive/depart vertices, hence the null checks.
            Vertex stopArriveVertex = context.stopArriveNodes.get(stop);
            Vertex parentStopArriveVertex = context.stopArriveNodes.get(parentStop);
            if (stopArriveVertex != null && parentStopArriveVertex != null) {
                new FreeEdge(parentStopArriveVertex, stopArriveVertex);
                new FreeEdge(stopArriveVertex, parentStopArriveVertex);
            }
            Vertex stopDepartVertex = context.stopDepartNodes.get(stop);
            Vertex parentStopDepartVertex = context.stopDepartNodes.get(parentStop);
            if (stopDepartVertex != null && parentStopDepartVertex != null) {
                new FreeEdge(parentStopDepartVertex, stopDepartVertex);
                new FreeEdge(stopDepartVertex, parentStopDepartVertex);
            }
        // TODO: provide a cost for these edges when stations and
        // stops have different locations
        }
    }
}
Also used : Vertex(org.opentripplanner.routing.graph.Vertex) AgencyAndId(org.onebusaway.gtfs.model.AgencyAndId) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) Stop(org.onebusaway.gtfs.model.Stop) TransitStationStop(org.opentripplanner.routing.vertextype.TransitStationStop) LineString(com.vividsolutions.jts.geom.LineString) FreeEdge(org.opentripplanner.routing.edgetype.FreeEdge)

Example 97 with Stop

use of org.onebusaway.gtfs.model.Stop in project OpenTripPlanner by opentripplanner.

the class GTFSPatternHopFactory method createGeometry.

/**
 * Creates a set of geometries for a single trip, considering the GTFS shapes.txt,
 * The geometry is broken down into one geometry per inter-stop segment ("hop"). We also need a shape for the entire
 * trip and tripPattern, but given the complexity of the existing code for generating hop geometries, we will create
 * the full-trip geometry by simply concatenating the hop geometries.
 *
 * This geometry will in fact be used for an entire set of trips in a trip pattern. Technically one of the trips
 * with exactly the same sequence of stops could follow a different route on the streets, but that's very uncommon.
 */
private LineString[] createGeometry(Graph graph, Trip trip, List<StopTime> stopTimes) {
    AgencyAndId shapeId = trip.getShapeId();
    // One less geometry than stoptime as array indexes represetn hops not stops (fencepost problem).
    LineString[] geoms = new LineString[stopTimes.size() - 1];
    // Detect presence or absence of shape_dist_traveled on a per-trip basis
    StopTime st0 = stopTimes.get(0);
    boolean hasShapeDist = st0.isShapeDistTraveledSet();
    if (hasShapeDist) {
        // this trip has shape_dist in stop_times
        for (int i = 0; i < stopTimes.size() - 1; ++i) {
            st0 = stopTimes.get(i);
            StopTime st1 = stopTimes.get(i + 1);
            geoms[i] = getHopGeometryViaShapeDistTraveled(graph, shapeId, st0, st1);
        }
        return geoms;
    }
    LineString shape = getLineStringForShapeId(shapeId);
    if (shape == null) {
        // create straight line segments between stops for each hop
        for (int i = 0; i < stopTimes.size() - 1; ++i) {
            st0 = stopTimes.get(i);
            StopTime st1 = stopTimes.get(i + 1);
            LineString geometry = createSimpleGeometry(st0.getStop(), st1.getStop());
            geoms[i] = geometry;
        }
        return geoms;
    }
    // This trip does not have shape_dist in stop_times, but does have an associated shape.
    ArrayList<IndexedLineSegment> segments = new ArrayList<IndexedLineSegment>();
    for (int i = 0; i < shape.getNumPoints() - 1; ++i) {
        segments.add(new IndexedLineSegment(i, shape.getCoordinateN(i), shape.getCoordinateN(i + 1)));
    }
    // Find possible segment matches for each stop.
    List<List<IndexedLineSegment>> possibleSegmentsForStop = new ArrayList<List<IndexedLineSegment>>();
    int minSegmentIndex = 0;
    for (int i = 0; i < stopTimes.size(); ++i) {
        Stop stop = stopTimes.get(i).getStop();
        Coordinate coord = new Coordinate(stop.getLon(), stop.getLat());
        List<IndexedLineSegment> stopSegments = new ArrayList<IndexedLineSegment>();
        double bestDistance = Double.MAX_VALUE;
        IndexedLineSegment bestSegment = null;
        int maxSegmentIndex = -1;
        int index = -1;
        int minSegmentIndexForThisStop = -1;
        for (IndexedLineSegment segment : segments) {
            index++;
            if (segment.index < minSegmentIndex) {
                continue;
            }
            double distance = segment.distance(coord);
            if (distance < maxStopToShapeSnapDistance) {
                stopSegments.add(segment);
                maxSegmentIndex = index;
                if (minSegmentIndexForThisStop == -1)
                    minSegmentIndexForThisStop = index;
            } else if (distance < bestDistance) {
                bestDistance = distance;
                bestSegment = segment;
                if (maxSegmentIndex != -1) {
                    maxSegmentIndex = index;
                }
            }
        }
        if (stopSegments.size() == 0) {
            // no segments within 150m
            // fall back to nearest segment
            stopSegments.add(bestSegment);
            minSegmentIndex = bestSegment.index;
        } else {
            minSegmentIndex = minSegmentIndexForThisStop;
            Collections.sort(stopSegments, new IndexedLineSegmentComparator(coord));
        }
        for (int j = i - 1; j >= 0; j--) {
            for (Iterator<IndexedLineSegment> it = possibleSegmentsForStop.get(j).iterator(); it.hasNext(); ) {
                IndexedLineSegment segment = it.next();
                if (segment.index > maxSegmentIndex) {
                    it.remove();
                }
            }
        }
        possibleSegmentsForStop.add(stopSegments);
    }
    List<LinearLocation> locations = getStopLocations(possibleSegmentsForStop, stopTimes, 0, -1);
    if (locations == null) {
        for (int i = 0; i < stopTimes.size() - 1; ++i) {
            st0 = stopTimes.get(i);
            StopTime st1 = stopTimes.get(i + 1);
            LineString geometry = createSimpleGeometry(st0.getStop(), st1.getStop());
            geoms[i] = geometry;
            // this warning is not strictly correct, but will do
            LOG.warn(graph.addBuilderAnnotation(new BogusShapeGeometryCaught(shapeId, st0, st1)));
        }
        return geoms;
    }
    Iterator<LinearLocation> locationIt = locations.iterator();
    LinearLocation endLocation = locationIt.next();
    double distanceSoFar = 0;
    int last = 0;
    for (int i = 0; i < stopTimes.size() - 1; ++i) {
        LinearLocation startLocation = endLocation;
        endLocation = locationIt.next();
        // it does not matter at all if this is accurate so long as it is consistent
        for (int j = last; j < startLocation.getSegmentIndex(); ++j) {
            Coordinate from = shape.getCoordinateN(j);
            Coordinate to = shape.getCoordinateN(j + 1);
            double xd = from.x - to.x;
            double yd = from.y - to.y;
            distanceSoFar += FastMath.sqrt(xd * xd + yd * yd);
        }
        last = startLocation.getSegmentIndex();
        double startIndex = distanceSoFar + startLocation.getSegmentFraction() * startLocation.getSegmentLength(shape);
        // advance distanceSoFar up to start of segment containing endLocation
        for (int j = last; j < endLocation.getSegmentIndex(); ++j) {
            Coordinate from = shape.getCoordinateN(j);
            Coordinate to = shape.getCoordinateN(j + 1);
            double xd = from.x - to.x;
            double yd = from.y - to.y;
            distanceSoFar += FastMath.sqrt(xd * xd + yd * yd);
        }
        last = startLocation.getSegmentIndex();
        double endIndex = distanceSoFar + endLocation.getSegmentFraction() * endLocation.getSegmentLength(shape);
        ShapeSegmentKey key = new ShapeSegmentKey(shapeId, startIndex, endIndex);
        LineString geometry = _geometriesByShapeSegmentKey.get(key);
        if (geometry == null) {
            LocationIndexedLine locationIndexed = new LocationIndexedLine(shape);
            geometry = (LineString) locationIndexed.extractLine(startLocation, endLocation);
            // Pack the resulting line string
            CoordinateSequence sequence = new PackedCoordinateSequence.Double(geometry.getCoordinates(), 2);
            geometry = _geometryFactory.createLineString(sequence);
        }
        geoms[i] = geometry;
    }
    return geoms;
}
Also used : CoordinateSequence(com.vividsolutions.jts.geom.CoordinateSequence) PackedCoordinateSequence(org.opentripplanner.common.geometry.PackedCoordinateSequence) AgencyAndId(org.onebusaway.gtfs.model.AgencyAndId) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) Stop(org.onebusaway.gtfs.model.Stop) TransitStationStop(org.opentripplanner.routing.vertextype.TransitStationStop) LinearLocation(com.vividsolutions.jts.linearref.LinearLocation) TIntArrayList(gnu.trove.list.array.TIntArrayList) ArrayList(java.util.ArrayList) BogusShapeGeometryCaught(org.opentripplanner.graph_builder.annotation.BogusShapeGeometryCaught) TIntArrayList(gnu.trove.list.array.TIntArrayList) TIntList(gnu.trove.list.TIntList) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) StopTime(org.onebusaway.gtfs.model.StopTime) LocationIndexedLine(com.vividsolutions.jts.linearref.LocationIndexedLine) ShapePoint(org.onebusaway.gtfs.model.ShapePoint) LineString(com.vividsolutions.jts.geom.LineString) Coordinate(com.vividsolutions.jts.geom.Coordinate)

Example 98 with Stop

use of org.onebusaway.gtfs.model.Stop 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 99 with Stop

use of org.onebusaway.gtfs.model.Stop in project OpenTripPlanner by opentripplanner.

the class GTFSPatternHopFactory method getStopLocations.

/**
 * Find a consistent, increasing list of LinearLocations along a shape for a set of stops.
 * Handles loops routes.
 * @return
 */
private List<LinearLocation> getStopLocations(List<List<IndexedLineSegment>> possibleSegmentsForStop, List<StopTime> stopTimes, int index, int prevSegmentIndex) {
    if (index == stopTimes.size()) {
        return new LinkedList<LinearLocation>();
    }
    StopTime st = stopTimes.get(index);
    Stop stop = st.getStop();
    Coordinate stopCoord = new Coordinate(stop.getLon(), stop.getLat());
    for (IndexedLineSegment segment : possibleSegmentsForStop.get(index)) {
        if (segment.index < prevSegmentIndex) {
            // can't go backwards along line
            continue;
        }
        List<LinearLocation> locations = getStopLocations(possibleSegmentsForStop, stopTimes, index + 1, segment.index);
        if (locations != null) {
            LinearLocation location = new LinearLocation(0, segment.index, segment.fraction(stopCoord));
            locations.add(0, location);
            // we found one!
            return locations;
        }
    }
    return null;
}
Also used : TransitStop(org.opentripplanner.routing.vertextype.TransitStop) Stop(org.onebusaway.gtfs.model.Stop) TransitStationStop(org.opentripplanner.routing.vertextype.TransitStationStop) Coordinate(com.vividsolutions.jts.geom.Coordinate) LinearLocation(com.vividsolutions.jts.linearref.LinearLocation) LinkedList(java.util.LinkedList) StopTime(org.onebusaway.gtfs.model.StopTime)

Example 100 with Stop

use of org.onebusaway.gtfs.model.Stop in project OpenTripPlanner by opentripplanner.

the class GTFSPatternHopFactory method loadTransfers.

private void loadTransfers(Graph graph) {
    Collection<Transfer> transfers = _dao.getAllTransfers();
    TransferTable transferTable = graph.getTransferTable();
    for (Transfer sourceTransfer : transfers) {
        // we thus expand transfers that use parent stations to all the member stops.
        for (Transfer t : expandTransfer(sourceTransfer)) {
            Stop fromStop = t.getFromStop();
            Stop toStop = t.getToStop();
            Route fromRoute = t.getFromRoute();
            Route toRoute = t.getToRoute();
            Trip fromTrip = t.getFromTrip();
            Trip toTrip = t.getToTrip();
            Vertex fromVertex = context.stopArriveNodes.get(fromStop);
            Vertex toVertex = context.stopDepartNodes.get(toStop);
            switch(t.getTransferType()) {
                case 1:
                    // timed (synchronized) transfer
                    // Handle with edges that bypass the street network.
                    // from and to vertex here are stop_arrive and stop_depart vertices
                    // only add edge when it doesn't exist already
                    boolean hasTimedTransferEdge = false;
                    for (Edge outgoingEdge : fromVertex.getOutgoing()) {
                        if (outgoingEdge instanceof TimedTransferEdge) {
                            if (outgoingEdge.getToVertex() == toVertex) {
                                hasTimedTransferEdge = true;
                                break;
                            }
                        }
                    }
                    if (!hasTimedTransferEdge) {
                        new TimedTransferEdge(fromVertex, toVertex);
                    }
                    // add to transfer table to handle specificity
                    transferTable.addTransferTime(fromStop, toStop, fromRoute, toRoute, fromTrip, toTrip, StopTransfer.TIMED_TRANSFER);
                    break;
                case 2:
                    // min transfer time
                    transferTable.addTransferTime(fromStop, toStop, fromRoute, toRoute, fromTrip, toTrip, t.getMinTransferTime());
                    break;
                case 3:
                    // forbidden transfer
                    transferTable.addTransferTime(fromStop, toStop, fromRoute, toRoute, fromTrip, toTrip, StopTransfer.FORBIDDEN_TRANSFER);
                    break;
                case 0:
                default:
                    // preferred transfer
                    transferTable.addTransferTime(fromStop, toStop, fromRoute, toRoute, fromTrip, toTrip, StopTransfer.PREFERRED_TRANSFER);
                    break;
            }
        }
    }
}
Also used : Vertex(org.opentripplanner.routing.graph.Vertex) Trip(org.onebusaway.gtfs.model.Trip) TimedTransferEdge(org.opentripplanner.routing.edgetype.TimedTransferEdge) TransferTable(org.opentripplanner.routing.core.TransferTable) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) Stop(org.onebusaway.gtfs.model.Stop) TransitStationStop(org.opentripplanner.routing.vertextype.TransitStationStop) StopTransfer(org.opentripplanner.routing.core.StopTransfer) Transfer(org.onebusaway.gtfs.model.Transfer) PathwayEdge(org.opentripplanner.routing.edgetype.PathwayEdge) TransferEdge(org.opentripplanner.routing.edgetype.TransferEdge) PreBoardEdge(org.opentripplanner.routing.edgetype.PreBoardEdge) FreeEdge(org.opentripplanner.routing.edgetype.FreeEdge) PreAlightEdge(org.opentripplanner.routing.edgetype.PreAlightEdge) TimedTransferEdge(org.opentripplanner.routing.edgetype.TimedTransferEdge) Edge(org.opentripplanner.routing.graph.Edge) StationStopEdge(org.opentripplanner.routing.edgetype.StationStopEdge) Route(org.onebusaway.gtfs.model.Route)

Aggregations

Stop (org.onebusaway.gtfs.model.Stop)160 AgencyAndId (org.onebusaway.gtfs.model.AgencyAndId)75 TransitStop (org.opentripplanner.routing.vertextype.TransitStop)49 Trip (org.onebusaway.gtfs.model.Trip)40 Test (org.junit.Test)39 ArrayList (java.util.ArrayList)33 StopTime (org.onebusaway.gtfs.model.StopTime)33 Route (org.onebusaway.gtfs.model.Route)28 TripPattern (org.opentripplanner.routing.edgetype.TripPattern)23 Agency (org.onebusaway.gtfs.model.Agency)19 Vertex (org.opentripplanner.routing.graph.Vertex)18 HashMap (java.util.HashMap)14 TripTimes (org.opentripplanner.routing.trippattern.TripTimes)13 GtfsMutableRelationalDao (org.onebusaway.gtfs.services.GtfsMutableRelationalDao)11 LineString (com.vividsolutions.jts.geom.LineString)10 List (java.util.List)10 GET (javax.ws.rs.GET)10 ShapePoint (org.onebusaway.gtfs.model.ShapePoint)10 GraphPath (org.opentripplanner.routing.spt.GraphPath)10 Coordinate (com.vividsolutions.jts.geom.Coordinate)9