Search in sources :

Example 1 with BogusShapeGeometryCaught

use of org.opentripplanner.graph_builder.annotation.BogusShapeGeometryCaught in project OpenTripPlanner by opentripplanner.

the class GTFSPatternHopFactory method getSegmentGeometry.

private LineString getSegmentGeometry(Graph graph, AgencyAndId shapeId, LocationIndexedLine locationIndexedLine, LinearLocation startIndex, LinearLocation endIndex, double startDistance, double endDistance, StopTime st0, StopTime st1) {
    ShapeSegmentKey key = new ShapeSegmentKey(shapeId, startDistance, endDistance);
    LineString geometry = _geometriesByShapeSegmentKey.get(key);
    if (geometry == null) {
        geometry = (LineString) locationIndexedLine.extractLine(startIndex, endIndex);
        // Pack the resulting line string
        CoordinateSequence sequence = new PackedCoordinateSequence.Double(geometry.getCoordinates(), 2);
        geometry = _geometryFactory.createLineString(sequence);
        if (!isValid(geometry, st0.getStop(), st1.getStop())) {
            LOG.warn(graph.addBuilderAnnotation(new BogusShapeGeometryCaught(shapeId, st0, st1)));
            // fall back to trivial geometry
            geometry = createSimpleGeometry(st0.getStop(), st1.getStop());
        }
        _geometriesByShapeSegmentKey.put(key, (LineString) geometry);
    }
    return geometry;
}
Also used : CoordinateSequence(com.vividsolutions.jts.geom.CoordinateSequence) PackedCoordinateSequence(org.opentripplanner.common.geometry.PackedCoordinateSequence) BogusShapeGeometryCaught(org.opentripplanner.graph_builder.annotation.BogusShapeGeometryCaught) LineString(com.vividsolutions.jts.geom.LineString)

Example 2 with BogusShapeGeometryCaught

use of org.opentripplanner.graph_builder.annotation.BogusShapeGeometryCaught 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)

Aggregations

CoordinateSequence (com.vividsolutions.jts.geom.CoordinateSequence)2 LineString (com.vividsolutions.jts.geom.LineString)2 PackedCoordinateSequence (org.opentripplanner.common.geometry.PackedCoordinateSequence)2 BogusShapeGeometryCaught (org.opentripplanner.graph_builder.annotation.BogusShapeGeometryCaught)2 Coordinate (com.vividsolutions.jts.geom.Coordinate)1 LinearLocation (com.vividsolutions.jts.linearref.LinearLocation)1 LocationIndexedLine (com.vividsolutions.jts.linearref.LocationIndexedLine)1 TIntList (gnu.trove.list.TIntList)1 TIntArrayList (gnu.trove.list.array.TIntArrayList)1 ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 AgencyAndId (org.onebusaway.gtfs.model.AgencyAndId)1 ShapePoint (org.onebusaway.gtfs.model.ShapePoint)1 Stop (org.onebusaway.gtfs.model.Stop)1 StopTime (org.onebusaway.gtfs.model.StopTime)1 TransitStationStop (org.opentripplanner.routing.vertextype.TransitStationStop)1 TransitStop (org.opentripplanner.routing.vertextype.TransitStop)1