Search in sources :

Example 1 with P2

use of org.opentripplanner.common.model.P2 in project OpenTripPlanner by opentripplanner.

the class GeometryUtils method splitGeometryAtPoint.

/**
 * Splits the input geometry into two LineStrings at the given point.
 */
public static P2<LineString> splitGeometryAtPoint(Geometry geometry, Coordinate nearestPoint) {
    // An index in JTS can actually refer to any point along the line. It is NOT an array index.
    LocationIndexedLine line = new LocationIndexedLine(geometry);
    LinearLocation l = line.indexOf(nearestPoint);
    LineString beginning = (LineString) line.extractLine(line.getStartIndex(), l);
    LineString ending = (LineString) line.extractLine(l, line.getEndIndex());
    return new P2<LineString>(beginning, ending);
}
Also used : P2(org.opentripplanner.common.model.P2) LocationIndexedLine(com.vividsolutions.jts.linearref.LocationIndexedLine) LinearLocation(com.vividsolutions.jts.linearref.LinearLocation)

Example 2 with P2

use of org.opentripplanner.common.model.P2 in project OpenTripPlanner by opentripplanner.

the class GTFSPatternHopFactory method interline.

/**
 * Identify interlined trips (where a physical vehicle continues on to another logical trip)
 * and update the TripPatterns accordingly. This must be called after all the pattern edges and vertices
 * are already created, because it creates interline dwell edges between existing pattern arrive/depart vertices.
 */
private void interline(Collection<TripPattern> tripPatterns, Graph graph) {
    /* Record which Pattern each interlined TripTimes belongs to. */
    Map<TripTimes, TripPattern> patternForTripTimes = Maps.newHashMap();
    /* TripTimes grouped by the block ID and service ID of their trips. Must be a ListMultimap to allow sorting. */
    ListMultimap<BlockIdAndServiceId, TripTimes> tripTimesForBlock = ArrayListMultimap.create();
    LOG.info("Finding interlining trips based on block IDs.");
    for (TripPattern pattern : tripPatterns) {
        Timetable timetable = pattern.scheduledTimetable;
        /* TODO: Block semantics seem undefined for frequency trips, so skip them? */
        for (TripTimes tripTimes : timetable.tripTimes) {
            Trip trip = tripTimes.trip;
            if (!Strings.isNullOrEmpty(trip.getBlockId())) {
                tripTimesForBlock.put(new BlockIdAndServiceId(trip), tripTimes);
                // For space efficiency, only record times that are part of a block.
                patternForTripTimes.put(tripTimes, pattern);
            }
        }
    }
    /* Associate pairs of TripPatterns with lists of trips that continue from one pattern to the other. */
    Multimap<P2<TripPattern>, P2<Trip>> interlines = ArrayListMultimap.create();
    /*
          Sort trips within each block by first departure time, then iterate over trips in this block and service,
          linking them. Has no effect on single-trip blocks.
         */
    SERVICE_BLOCK: for (BlockIdAndServiceId block : tripTimesForBlock.keySet()) {
        List<TripTimes> blockTripTimes = tripTimesForBlock.get(block);
        Collections.sort(blockTripTimes);
        TripTimes prev = null;
        for (TripTimes curr : blockTripTimes) {
            if (prev != null) {
                if (prev.getDepartureTime(prev.getNumStops() - 1) > curr.getArrivalTime(0)) {
                    LOG.error("Trip times within block {} are not increasing on service {} after trip {}.", block.blockId, block.serviceId, prev.trip.getId());
                    continue SERVICE_BLOCK;
                }
                TripPattern prevPattern = patternForTripTimes.get(prev);
                TripPattern currPattern = patternForTripTimes.get(curr);
                Stop fromStop = prevPattern.getStop(prevPattern.getStops().size() - 1);
                Stop toStop = currPattern.getStop(0);
                double teleportationDistance = SphericalDistanceLibrary.fastDistance(fromStop.getLat(), fromStop.getLon(), toStop.getLat(), toStop.getLon());
                if (teleportationDistance > maxInterlineDistance) {
                // FIXME Trimet data contains a lot of these -- in their data, two trips sharing a block ID just
                // means that they are served by the same vehicle, not that interlining is automatically allowed.
                // see #1654
                // LOG.error(graph.addBuilderAnnotation(new InterliningTeleport(prev.trip, block.blockId, (int)teleportationDistance)));
                // Only skip this particular interline edge; there may be other valid ones in the block.
                } else {
                    interlines.put(new P2<TripPattern>(prevPattern, currPattern), new P2<Trip>(prev.trip, curr.trip));
                }
            }
            prev = curr;
        }
    }
    /*
          Create the PatternInterlineDwell edges linking together TripPatterns.
          All the pattern vertices and edges must already have been created.
         */
    for (P2<TripPattern> patterns : interlines.keySet()) {
        TripPattern prevPattern = patterns.first;
        TripPattern nextPattern = patterns.second;
        // This is a single (uni-directional) edge which may be traversed forward and backward.
        PatternInterlineDwell edge = new PatternInterlineDwell(prevPattern, nextPattern);
        for (P2<Trip> trips : interlines.get(patterns)) {
            edge.add(trips.first, trips.second);
        }
    }
    LOG.info("Done finding interlining trips and creating the corresponding edges.");
}
Also used : Timetable(org.opentripplanner.routing.edgetype.Timetable) Trip(org.onebusaway.gtfs.model.Trip) P2(org.opentripplanner.common.model.P2) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) Stop(org.onebusaway.gtfs.model.Stop) TransitStationStop(org.opentripplanner.routing.vertextype.TransitStationStop) PatternInterlineDwell(org.opentripplanner.routing.edgetype.PatternInterlineDwell) TripPattern(org.opentripplanner.routing.edgetype.TripPattern) 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)

Example 3 with P2

use of org.opentripplanner.common.model.P2 in project OpenTripPlanner by opentripplanner.

the class GraphIndex method initializeProfileTransfers.

/**
 * Initialize transfer data needed for profile routing.
 * Find the best transfers between each pair of patterns that pass near one another.
 */
public void initializeProfileTransfers() {
    transfersFromStopCluster = HashMultimap.create();
    // meters
    final double TRANSFER_RADIUS = 500.0;
    Map<P2<TripPattern>, ProfileTransfer.GoodTransferList> transfers = Maps.newHashMap();
    LOG.info("Finding transfers between clusters...");
    for (StopCluster sc0 : stopClusterForId.values()) {
        Set<TripPattern> tripPatterns0 = patternsForStopCluster(sc0);
        // Accounts for area-like (rather than point-like) nature of clusters
        Map<StopCluster, Double> nearbyStopClusters = findNearbyStopClusters(sc0, TRANSFER_RADIUS);
        for (StopCluster sc1 : nearbyStopClusters.keySet()) {
            double distance = nearbyStopClusters.get(sc1);
            Set<TripPattern> tripPatterns1 = patternsForStopCluster(sc1);
            for (TripPattern tp0 : tripPatterns0) {
                for (TripPattern tp1 : tripPatterns1) {
                    if (tp0 == tp1)
                        continue;
                    P2<TripPattern> pair = new P2<TripPattern>(tp0, tp1);
                    ProfileTransfer.GoodTransferList list = transfers.get(pair);
                    if (list == null) {
                        list = new ProfileTransfer.GoodTransferList();
                        transfers.put(pair, list);
                    }
                    list.add(new ProfileTransfer(tp0, tp1, sc0, sc1, (int) distance));
                }
            }
        }
    }
    /* Now filter the transfers down to eliminate long series of transfers in shared trunks. */
    LOG.info("Filtering out long series of transfers on trunks shared between patterns.");
    for (P2<TripPattern> pair : transfers.keySet()) {
        ProfileTransfer.GoodTransferList list = transfers.get(pair);
        // TODO consider using second (think of express-local transfers in NYC)
        TripPattern fromPattern = pair.first;
        Map<StopCluster, ProfileTransfer> transfersByFromCluster = Maps.newHashMap();
        for (ProfileTransfer transfer : list.good) {
            transfersByFromCluster.put(transfer.sc1, transfer);
        }
        List<ProfileTransfer> retainedTransfers = Lists.newArrayList();
        // true whenever a transfer existed for the last stop in the stop pattern
        boolean inSeries = false;
        for (Stop stop : fromPattern.stopPattern.stops) {
            StopCluster cluster = this.stopClusterForStop.get(stop);
            // LOG.info("stop {} cluster {}", stop, cluster.id);
            ProfileTransfer transfer = transfersByFromCluster.get(cluster);
            if (transfer == null) {
                inSeries = false;
                continue;
            }
            if (inSeries)
                continue;
            // Keep this transfer: it's not preceded by another stop with a transfer in this stop pattern
            retainedTransfers.add(transfer);
            inSeries = true;
        }
        // LOG.info("patterns {}, {} transfers", pair, retainedTransfers.size());
        for (ProfileTransfer tr : retainedTransfers) {
            transfersFromStopCluster.put(tr.sc1, tr);
        // LOG.info("   {}", tr);
        }
    }
    /*
         * for (Stop stop : transfersForStop.keys()) { System.out.println("STOP " + stop); for
         * (Transfer transfer : transfersForStop.get(stop)) { System.out.println("    " +
         * transfer.toString()); } }
         */
    LOG.info("Done finding transfers.");
}
Also used : P2(org.opentripplanner.common.model.P2) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) Stop(org.onebusaway.gtfs.model.Stop) StopCluster(org.opentripplanner.profile.StopCluster) TripPattern(org.opentripplanner.routing.edgetype.TripPattern) ProfileTransfer(org.opentripplanner.profile.ProfileTransfer)

Example 4 with P2

use of org.opentripplanner.common.model.P2 in project OpenTripPlanner by opentripplanner.

the class GraphPathToTripPlanConverter method generateWalkSteps.

/**
 * Converts a list of street edges to a list of turn-by-turn directions.
 *
 * @param previous a non-transit leg that immediately precedes this one (bike-walking, say), or null
 *
 * @return
 */
public static List<WalkStep> generateWalkSteps(Graph graph, State[] states, WalkStep previous, Locale requestedLocale) {
    List<WalkStep> steps = new ArrayList<WalkStep>();
    WalkStep step = null;
    // distance used for appending elevation profiles
    double lastAngle = 0, distance = 0;
    // track whether we are in a roundabout, and if so the exit number
    int roundaboutExit = 0;
    String roundaboutPreviousStreet = null;
    State onBikeRentalState = null, offBikeRentalState = null;
    // Check if this leg is a SimpleTransfer; if so, rebuild state array based on stored transfer edges
    if (states.length == 2 && states[1].getBackEdge() instanceof SimpleTransfer) {
        SimpleTransfer transferEdge = ((SimpleTransfer) states[1].getBackEdge());
        List<Edge> transferEdges = transferEdge.getEdges();
        if (transferEdges != null) {
            // Create a new initial state. Some parameters may have change along the way, copy them from the first state
            StateEditor se = new StateEditor(states[0].getOptions(), transferEdges.get(0).getFromVertex());
            se.setNonTransitOptionsFromState(states[0]);
            State s = se.makeState();
            ArrayList<State> transferStates = new ArrayList<>();
            transferStates.add(s);
            for (Edge e : transferEdges) {
                s = e.traverse(s);
                transferStates.add(s);
            }
            states = transferStates.toArray(new State[transferStates.size()]);
        }
    }
    for (int i = 0; i < states.length - 1; i++) {
        State backState = states[i];
        State forwardState = states[i + 1];
        Edge edge = forwardState.getBackEdge();
        if (edge instanceof RentABikeOnEdge)
            onBikeRentalState = forwardState;
        if (edge instanceof RentABikeOffEdge)
            offBikeRentalState = forwardState;
        boolean createdNewStep = false, disableZagRemovalForThisStep = false;
        if (edge instanceof FreeEdge) {
            continue;
        }
        if (forwardState.getBackMode() == null || !forwardState.getBackMode().isOnStreetNonTransit()) {
            // ignore STLs and the like
            continue;
        }
        Geometry geom = edge.getGeometry();
        if (geom == null) {
            continue;
        }
        // before or will come after
        if (edge instanceof ElevatorAlightEdge) {
            // don't care what came before or comes after
            step = createWalkStep(graph, forwardState, requestedLocale);
            createdNewStep = true;
            disableZagRemovalForThisStep = true;
            // tell the user where to get off the elevator using the exit notation, so the
            // i18n interface will say 'Elevator to <exit>'
            // what happens is that the webapp sees name == null and ignores that, and it sees
            // exit != null and uses to <exit>
            // the floor name is the AlightEdge name
            // reset to avoid confusion with 'Elevator on floor 1 to floor 1'
            step.streetName = ((ElevatorAlightEdge) edge).getName(requestedLocale);
            step.relativeDirection = RelativeDirection.ELEVATOR;
            steps.add(step);
            continue;
        }
        String streetName = edge.getName(requestedLocale);
        int idx = streetName.indexOf('(');
        String streetNameNoParens;
        if (idx > 0)
            streetNameNoParens = streetName.substring(0, idx - 1);
        else
            streetNameNoParens = streetName;
        if (step == null) {
            // first step
            step = createWalkStep(graph, forwardState, requestedLocale);
            createdNewStep = true;
            steps.add(step);
            double thisAngle = DirectionUtils.getFirstAngle(geom);
            if (previous == null) {
                step.setAbsoluteDirection(thisAngle);
                step.relativeDirection = RelativeDirection.DEPART;
            } else {
                step.setDirections(previous.angle, thisAngle, false);
            }
            // new step, set distance to length of first edge
            distance = edge.getDistance();
        } else if (((step.streetName != null && !step.streetNameNoParens().equals(streetNameNoParens)) && (!step.bogusName || !edge.hasBogusName())) || // went on to or off of a roundabout
        edge.isRoundabout() != (roundaboutExit > 0) || isLink(edge) && !isLink(backState.getBackEdge())) {
            // Street name has changed, or we've gone on to or off of a roundabout.
            if (roundaboutExit > 0) {
                // if we were just on a roundabout,
                // make note of which exit was taken in the existing step
                // ordinal numbers from
                step.exit = Integer.toString(roundaboutExit);
                if (streetNameNoParens.equals(roundaboutPreviousStreet)) {
                    step.stayOn = true;
                }
                roundaboutExit = 0;
            }
            /* start a new step */
            step = createWalkStep(graph, forwardState, requestedLocale);
            createdNewStep = true;
            steps.add(step);
            if (edge.isRoundabout()) {
                // indicate that we are now on a roundabout
                // and use one-based exit numbering
                roundaboutExit = 1;
                roundaboutPreviousStreet = backState.getBackEdge().getName(requestedLocale);
                idx = roundaboutPreviousStreet.indexOf('(');
                if (idx > 0)
                    roundaboutPreviousStreet = roundaboutPreviousStreet.substring(0, idx - 1);
            }
            double thisAngle = DirectionUtils.getFirstAngle(geom);
            step.setDirections(lastAngle, thisAngle, edge.isRoundabout());
            // new step, set distance to length of first edge
            distance = edge.getDistance();
        } else {
            /* street name has not changed */
            double thisAngle = DirectionUtils.getFirstAngle(geom);
            RelativeDirection direction = WalkStep.getRelativeDirection(lastAngle, thisAngle, edge.isRoundabout());
            boolean optionsBefore = backState.multipleOptionsBefore();
            if (edge.isRoundabout()) {
                // we are on a roundabout, and have already traversed at least one edge of it.
                if (optionsBefore) {
                    // increment exit count if we passed one.
                    roundaboutExit += 1;
                }
            }
            if (edge.isRoundabout() || direction == RelativeDirection.CONTINUE) {
            // we are continuing almost straight, or continuing along a roundabout.
            // just append elevation info onto the existing step.
            } else {
                // we are not on a roundabout, and not continuing straight through.
                // figure out if there were other plausible turn options at the last
                // intersection
                // to see if we should generate a "left to continue" instruction.
                boolean shouldGenerateContinue = false;
                if (edge instanceof StreetEdge) {
                    // the next edges will be PlainStreetEdges, we hope
                    double angleDiff = getAbsoluteAngleDiff(thisAngle, lastAngle);
                    for (Edge alternative : backState.getVertex().getOutgoingStreetEdges()) {
                        if (alternative.getName(requestedLocale).equals(streetName)) {
                            // are usually caused by street splits
                            continue;
                        }
                        double altAngle = DirectionUtils.getFirstAngle(alternative.getGeometry());
                        double altAngleDiff = getAbsoluteAngleDiff(altAngle, lastAngle);
                        if (angleDiff > Math.PI / 4 || altAngleDiff - angleDiff < Math.PI / 16) {
                            shouldGenerateContinue = true;
                            break;
                        }
                    }
                } else {
                    double angleDiff = getAbsoluteAngleDiff(lastAngle, thisAngle);
                    // FIXME: this code might be wrong with the removal of the edge-based graph
                    State twoStatesBack = backState.getBackState();
                    Vertex backVertex = twoStatesBack.getVertex();
                    for (Edge alternative : backVertex.getOutgoingStreetEdges()) {
                        List<Edge> alternatives = alternative.getToVertex().getOutgoingStreetEdges();
                        if (alternatives.size() == 0) {
                            // this is not an alternative
                            continue;
                        }
                        alternative = alternatives.get(0);
                        if (alternative.getName(requestedLocale).equals(streetName)) {
                            // are usually caused by street splits
                            continue;
                        }
                        double altAngle = DirectionUtils.getFirstAngle(alternative.getGeometry());
                        double altAngleDiff = getAbsoluteAngleDiff(altAngle, lastAngle);
                        if (angleDiff > Math.PI / 4 || altAngleDiff - angleDiff < Math.PI / 16) {
                            shouldGenerateContinue = true;
                            break;
                        }
                    }
                }
                if (shouldGenerateContinue) {
                    // turn to stay on same-named street
                    step = createWalkStep(graph, forwardState, requestedLocale);
                    createdNewStep = true;
                    steps.add(step);
                    step.setDirections(lastAngle, thisAngle, false);
                    step.stayOn = true;
                    // new step, set distance to length of first edge
                    distance = edge.getDistance();
                }
            }
        }
        State exitState = backState;
        Edge exitEdge = exitState.getBackEdge();
        while (exitEdge instanceof FreeEdge) {
            exitState = exitState.getBackState();
            exitEdge = exitState.getBackEdge();
        }
        if (exitState.getVertex() instanceof ExitVertex) {
            step.exit = ((ExitVertex) exitState.getVertex()).getExitName();
        }
        if (createdNewStep && !disableZagRemovalForThisStep && forwardState.getBackMode() == backState.getBackMode()) {
            // check last three steps for zag
            int last = steps.size() - 1;
            if (last >= 2) {
                WalkStep threeBack = steps.get(last - 2);
                WalkStep twoBack = steps.get(last - 1);
                WalkStep lastStep = steps.get(last);
                if (twoBack.distance < MAX_ZAG_DISTANCE && lastStep.streetNameNoParens().equals(threeBack.streetNameNoParens())) {
                    if (((lastStep.relativeDirection == RelativeDirection.RIGHT || lastStep.relativeDirection == RelativeDirection.HARD_RIGHT) && (twoBack.relativeDirection == RelativeDirection.RIGHT || twoBack.relativeDirection == RelativeDirection.HARD_RIGHT)) || ((lastStep.relativeDirection == RelativeDirection.LEFT || lastStep.relativeDirection == RelativeDirection.HARD_LEFT) && (twoBack.relativeDirection == RelativeDirection.LEFT || twoBack.relativeDirection == RelativeDirection.HARD_LEFT))) {
                        // in this case, we have two left turns or two right turns in quick
                        // succession; this is probably a U-turn.
                        steps.remove(last - 1);
                        lastStep.distance += twoBack.distance;
                        // A U-turn to the left, typical in the US.
                        if (lastStep.relativeDirection == RelativeDirection.LEFT || lastStep.relativeDirection == RelativeDirection.HARD_LEFT)
                            lastStep.relativeDirection = RelativeDirection.UTURN_LEFT;
                        else
                            lastStep.relativeDirection = RelativeDirection.UTURN_RIGHT;
                        // in this case, we're definitely staying on the same street
                        // (since it's zag removal, the street names are the same)
                        lastStep.stayOn = true;
                    } else {
                        // What is a zag? TODO write meaningful documentation for this.
                        // It appears to mean simplifying out several rapid turns in succession
                        // from the description.
                        // total hack to remove zags.
                        steps.remove(last);
                        steps.remove(last - 1);
                        step = threeBack;
                        step.distance += twoBack.distance;
                        distance += step.distance;
                        if (twoBack.elevation != null) {
                            if (step.elevation == null) {
                                step.elevation = twoBack.elevation;
                            } else {
                                for (P2<Double> d : twoBack.elevation) {
                                    step.elevation.add(new P2<Double>(d.first + step.distance, d.second));
                                }
                            }
                        }
                    }
                }
            }
        } else {
            if (!createdNewStep && step.elevation != null) {
                List<P2<Double>> s = encodeElevationProfile(edge, distance, backState.getOptions().geoidElevation ? -graph.ellipsoidToGeoidDifference : 0);
                if (step.elevation != null && step.elevation.size() > 0) {
                    step.elevation.addAll(s);
                } else {
                    step.elevation = s;
                }
            }
            distance += edge.getDistance();
        }
        // increment the total length for this step
        step.distance += edge.getDistance();
        step.addAlerts(graph.streetNotesService.getNotes(forwardState), requestedLocale);
        lastAngle = DirectionUtils.getLastAngle(geom);
        step.edges.add(edge);
    }
    // add bike rental information if applicable
    if (onBikeRentalState != null && !steps.isEmpty()) {
        steps.get(steps.size() - 1).bikeRentalOnStation = new BikeRentalStationInfo((BikeRentalStationVertex) onBikeRentalState.getBackEdge().getToVertex());
    }
    if (offBikeRentalState != null && !steps.isEmpty()) {
        steps.get(0).bikeRentalOffStation = new BikeRentalStationInfo((BikeRentalStationVertex) offBikeRentalState.getBackEdge().getFromVertex());
    }
    return steps;
}
Also used : Vertex(org.opentripplanner.routing.graph.Vertex) LineString(com.vividsolutions.jts.geom.LineString) P2(org.opentripplanner.common.model.P2) BikeRentalStationInfo(org.opentripplanner.profile.BikeRentalStationInfo) Geometry(com.vividsolutions.jts.geom.Geometry) Edge(org.opentripplanner.routing.graph.Edge)

Example 5 with P2

use of org.opentripplanner.common.model.P2 in project OpenTripPlanner by opentripplanner.

the class WalkableAreaBuilder method createEdgesForRingSegment.

private void createEdgesForRingSegment(Set<Edge> edges, AreaEdgeList edgeList, Area area, Ring ring, int i, HashSet<P2<OSMNode>> alreadyAddedEdges) {
    OSMNode node = ring.nodes.get(i);
    OSMNode nextNode = ring.nodes.get((i + 1) % ring.nodes.size());
    P2<OSMNode> nodePair = new P2<OSMNode>(node, nextNode);
    if (alreadyAddedEdges.contains(nodePair)) {
        return;
    }
    alreadyAddedEdges.add(nodePair);
    IntersectionVertex startEndpoint = __handler.getVertexForOsmNode(node, area.parent);
    IntersectionVertex endEndpoint = __handler.getVertexForOsmNode(nextNode, area.parent);
    createSegments(node, nextNode, startEndpoint, endEndpoint, Arrays.asList(area), edgeList, edges);
}
Also used : P2(org.opentripplanner.common.model.P2) IntersectionVertex(org.opentripplanner.routing.vertextype.IntersectionVertex) OSMNode(org.opentripplanner.openstreetmap.model.OSMNode)

Aggregations

P2 (org.opentripplanner.common.model.P2)13 ArrayList (java.util.ArrayList)4 HashSet (java.util.HashSet)4 StreetEdge (org.opentripplanner.routing.edgetype.StreetEdge)4 IntersectionVertex (org.opentripplanner.routing.vertextype.IntersectionVertex)4 Coordinate (com.vividsolutions.jts.geom.Coordinate)3 LineString (com.vividsolutions.jts.geom.LineString)3 OSMNode (org.opentripplanner.openstreetmap.model.OSMNode)3 StreetTraversalPermission (org.opentripplanner.routing.edgetype.StreetTraversalPermission)3 Edge (org.opentripplanner.routing.graph.Edge)3 Vertex (org.opentripplanner.routing.graph.Vertex)3 LinearRing (com.vividsolutions.jts.geom.LinearRing)2 MultiLineString (com.vividsolutions.jts.geom.MultiLineString)2 Point (com.vividsolutions.jts.geom.Point)2 LinearLocation (com.vividsolutions.jts.linearref.LinearLocation)2 LocationIndexedLine (com.vividsolutions.jts.linearref.LocationIndexedLine)2 File (java.io.File)2 Stop (org.onebusaway.gtfs.model.Stop)2 AreaEdge (org.opentripplanner.routing.edgetype.AreaEdge)2 AreaEdgeList (org.opentripplanner.routing.edgetype.AreaEdgeList)2