Search in sources :

Example 26 with IntersectionVertex

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

the class TestOpenStreetMapGraphBuilder method testBuildGraphDetailed.

/**
 * Detailed testing of OSM graph building using a very small chunk of NYC (SOHO-ish).
 * @throws Exception
 */
@Test
public void testBuildGraphDetailed() throws Exception {
    Graph gg = new Graph();
    OpenStreetMapModule loader = new OpenStreetMapModule();
    loader.setDefaultWayPropertySetSource(new DefaultWayPropertySetSource());
    FileBasedOpenStreetMapProviderImpl provider = new FileBasedOpenStreetMapProviderImpl();
    File file = new File(URLDecoder.decode(getClass().getResource("NYC_small.osm.gz").getFile(), "UTF-8"));
    provider.setPath(file);
    loader.setProvider(provider);
    loader.buildGraph(gg, extra);
    // These vertices are labeled in the OSM file as having traffic lights.
    IntersectionVertex iv1 = (IntersectionVertex) gg.getVertex("osm:node:1919595918");
    IntersectionVertex iv2 = (IntersectionVertex) gg.getVertex("osm:node:42442273");
    IntersectionVertex iv3 = (IntersectionVertex) gg.getVertex("osm:node:1919595927");
    IntersectionVertex iv4 = (IntersectionVertex) gg.getVertex("osm:node:42452026");
    assertTrue(iv1.trafficLight);
    assertTrue(iv2.trafficLight);
    assertTrue(iv3.trafficLight);
    assertTrue(iv4.trafficLight);
    // These are not.
    IntersectionVertex iv5 = (IntersectionVertex) gg.getVertex("osm:node:42435485");
    IntersectionVertex iv6 = (IntersectionVertex) gg.getVertex("osm:node:42439335");
    IntersectionVertex iv7 = (IntersectionVertex) gg.getVertex("osm:node:42436761");
    IntersectionVertex iv8 = (IntersectionVertex) gg.getVertex("osm:node:42442291");
    assertFalse(iv5.trafficLight);
    assertFalse(iv6.trafficLight);
    assertFalse(iv7.trafficLight);
    assertFalse(iv8.trafficLight);
    Set<P2<Integer>> edgeEndpoints = new HashSet<P2<Integer>>();
    for (StreetEdge se : gg.getStreetEdges()) {
        P2<Integer> endpoints = new P2<Integer>(se.getFromVertex().getIndex(), se.getToVertex().getIndex());
        // Check that we don't get any duplicate edges on this small graph.
        if (edgeEndpoints.contains(endpoints)) {
            assertFalse(true);
        }
        edgeEndpoints.add(endpoints);
    }
}
Also used : P2(org.opentripplanner.common.model.P2) Graph(org.opentripplanner.routing.graph.Graph) FileBasedOpenStreetMapProviderImpl(org.opentripplanner.openstreetmap.impl.FileBasedOpenStreetMapProviderImpl) IntersectionVertex(org.opentripplanner.routing.vertextype.IntersectionVertex) StreetEdge(org.opentripplanner.routing.edgetype.StreetEdge) File(java.io.File) Test(org.junit.Test)

Example 27 with IntersectionVertex

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

the class StreetEdge method doTraverse.

/**
 * return a StateEditor rather than a State so that we can make parking/mode switch modifications for kiss-and-ride.
 */
private StateEditor doTraverse(State s0, RoutingRequest options, TraverseMode traverseMode) {
    boolean walkingBike = options.walkingBike;
    boolean backWalkingBike = s0.isBackWalkingBike();
    TraverseMode backMode = s0.getBackMode();
    Edge backEdge = s0.getBackEdge();
    if (backEdge != null) {
        // TODO profiling indicates that this is a hot spot.
        if (this.isReverseOf(backEdge) || backEdge.isReverseOf(this)) {
            return null;
        }
    }
    // Ensure we are actually walking, when walking a bike
    backWalkingBike &= TraverseMode.WALK.equals(backMode);
    walkingBike &= TraverseMode.WALK.equals(traverseMode);
    /* Check whether this street allows the current mode. If not and we are biking, attempt to walk the bike. */
    if (!canTraverse(options, traverseMode)) {
        if (traverseMode == TraverseMode.BICYCLE) {
            return doTraverse(s0, options.bikeWalkingOptions, TraverseMode.WALK);
        }
        return null;
    }
    // Automobiles have variable speeds depending on the edge type
    double speed = calculateSpeed(options, traverseMode, s0.getTimeInMillis());
    double time = getDistance() / speed;
    double weight;
    // TODO(flamholz): factor out this bike, wheelchair and walking specific logic to somewhere central.
    if (options.wheelchairAccessible) {
        weight = getSlopeSpeedEffectiveLength() / speed;
    } else if (traverseMode.equals(TraverseMode.BICYCLE)) {
        time = getSlopeSpeedEffectiveLength() / speed;
        switch(options.optimize) {
            case SAFE:
                weight = bicycleSafetyFactor * getDistance() / speed;
                break;
            case GREENWAYS:
                weight = bicycleSafetyFactor * getDistance() / speed;
                if (bicycleSafetyFactor <= GREENWAY_SAFETY_FACTOR) {
                    // greenways are treated as even safer than they really are
                    weight *= 0.66;
                }
                break;
            case FLAT:
                /* see notes in StreetVertex on speed overhead */
                weight = getDistance() / speed + getSlopeWorkCostEffectiveLength();
                break;
            case QUICK:
                weight = getSlopeSpeedEffectiveLength() / speed;
                break;
            case TRIANGLE:
                double quick = getSlopeSpeedEffectiveLength();
                double safety = bicycleSafetyFactor * getDistance();
                // TODO This computation is not coherent with the one for FLAT
                double slope = getSlopeWorkCostEffectiveLength();
                weight = quick * options.triangleTimeFactor + slope * options.triangleSlopeFactor + safety * options.triangleSafetyFactor;
                weight /= speed;
                break;
            default:
                weight = getDistance() / speed;
        }
    } else {
        if (walkingBike) {
            // take slopes into account when walking bikes
            time = getSlopeSpeedEffectiveLength() / speed;
        }
        weight = time;
        if (traverseMode.equals(TraverseMode.WALK)) {
            // take slopes into account when walking
            // FIXME: this causes steep stairs to be avoided. see #1297.
            double costs = ElevationUtils.getWalkCostsForSlope(getDistance(), getMaxSlope());
            // as the cost walkspeed is assumed to be for 4.8km/h (= 1.333 m/sec) we need to adjust
            // for the walkspeed set by the user
            double elevationUtilsSpeed = 4.0 / 3.0;
            weight = costs * (elevationUtilsSpeed / speed);
            // treat cost as time, as in the current model it actually is the same (this can be checked for maxSlope == 0)
            time = weight;
        /*
                // debug code
                if(weight > 100){
                    double timeflat = length / speed;
                    System.out.format("line length: %.1f m, slope: %.3f ---> slope costs: %.1f , weight: %.1f , time (flat):  %.1f %n", length, elevationProfile.getMaxSlope(), costs, weight, timeflat);
                }
                */
        }
    }
    if (isStairs()) {
        weight *= options.stairsReluctance;
    } else {
        // TODO: this is being applied even when biking or driving.
        weight *= options.walkReluctance;
    }
    StateEditor s1 = s0.edit(this);
    s1.setBackMode(traverseMode);
    s1.setBackWalkingBike(walkingBike);
    /* Handle no through traffic areas. */
    if (this.isNoThruTraffic()) {
        // Record transition into no-through-traffic area.
        if (backEdge instanceof StreetEdge && !((StreetEdge) backEdge).isNoThruTraffic()) {
            s1.setEnteredNoThroughTrafficArea();
        }
        // If we transitioned into a no-through-traffic area at some point, check if we are exiting it.
        if (s1.hasEnteredNoThroughTrafficArea()) {
            // on thru _Vertices_. This could certainly be improved somehow.
            for (StreetEdge se : Iterables.filter(s1.getVertex().getOutgoing(), StreetEdge.class)) {
                if (!se.isNoThruTraffic()) {
                    // This vertex has at least one through-traffic edge. We can't dominate it with a no-thru state.
                    return null;
                }
            }
        }
    }
    /* Compute turn cost. */
    StreetEdge backPSE;
    if (backEdge != null && backEdge instanceof StreetEdge) {
        backPSE = (StreetEdge) backEdge;
        RoutingRequest backOptions = backWalkingBike ? s0.getOptions().bikeWalkingOptions : s0.getOptions();
        double backSpeed = backPSE.calculateSpeed(backOptions, backMode, s0.getTimeInMillis());
        // Units are seconds.
        final double realTurnCost;
        // Apply turn restrictions
        if (options.arriveBy && !canTurnOnto(backPSE, s0, backMode)) {
            return null;
        } else if (!options.arriveBy && !backPSE.canTurnOnto(this, s0, traverseMode)) {
            return null;
        }
        /*
             * This is a subtle piece of code. Turn costs are evaluated differently during
             * forward and reverse traversal. During forward traversal of an edge, the turn
             * *into* that edge is used, while during reverse traversal, the turn *out of*
             * the edge is used.
             *
             * However, over a set of edges, the turn costs must add up the same (for
             * general correctness and specifically for reverse optimization). This means
             * that during reverse traversal, we must also use the speed for the mode of
             * the backEdge, rather than of the current edge.
             */
        if (options.arriveBy && tov instanceof IntersectionVertex) {
            // arrive-by search
            IntersectionVertex traversedVertex = ((IntersectionVertex) tov);
            realTurnCost = backOptions.getIntersectionTraversalCostModel().computeTraversalCost(traversedVertex, this, backPSE, backMode, backOptions, (float) speed, (float) backSpeed);
        } else if (!options.arriveBy && fromv instanceof IntersectionVertex) {
            // depart-after search
            IntersectionVertex traversedVertex = ((IntersectionVertex) fromv);
            realTurnCost = options.getIntersectionTraversalCostModel().computeTraversalCost(traversedVertex, backPSE, this, traverseMode, options, (float) backSpeed, (float) speed);
        } else {
            // In case this is a temporary edge not connected to an IntersectionVertex
            LOG.debug("Not computing turn cost for edge {}", this);
            realTurnCost = 0;
        }
        if (!traverseMode.isDriving()) {
            // just a tie-breaker
            s1.incrementWalkDistance(realTurnCost / 100);
        }
        long turnTime = (long) Math.ceil(realTurnCost);
        time += turnTime;
        weight += options.turnReluctance * realTurnCost;
    }
    if (walkingBike || TraverseMode.BICYCLE.equals(traverseMode)) {
        if (!(backWalkingBike || TraverseMode.BICYCLE.equals(backMode))) {
            s1.incrementTimeInSeconds(options.bikeSwitchTime);
            s1.incrementWeight(options.bikeSwitchCost);
        }
    }
    if (!traverseMode.isDriving()) {
        s1.incrementWalkDistance(getDistance());
    }
    /* On the pre-kiss/pre-park leg, limit both walking and driving, either soft or hard. */
    int roundedTime = (int) Math.ceil(time);
    if (options.kissAndRide || options.parkAndRide) {
        if (options.arriveBy) {
            if (!s0.isCarParked())
                s1.incrementPreTransitTime(roundedTime);
        } else {
            if (!s0.isEverBoarded())
                s1.incrementPreTransitTime(roundedTime);
        }
        if (s1.isMaxPreTransitTimeExceeded(options)) {
            if (options.softPreTransitLimiting) {
                weight += calculateOverageWeight(s0.getPreTransitTime(), s1.getPreTransitTime(), options.maxPreTransitTime, options.preTransitPenalty, options.preTransitOverageRate);
            } else
                return null;
        }
    }
    /* Apply a strategy for avoiding walking too far, either soft (weight increases) or hard limiting (pruning). */
    if (s1.weHaveWalkedTooFar(options)) {
        // if we're using a soft walk-limit
        if (options.softWalkLimiting) {
            // just slap a penalty for the overage onto s1
            weight += calculateOverageWeight(s0.getWalkDistance(), s1.getWalkDistance(), options.getMaxWalkDistance(), options.softWalkPenalty, options.softWalkOverageRate);
        } else {
            // else, it's a hard limit; bail
            LOG.debug("Too much walking. Bailing.");
            return null;
        }
    }
    s1.incrementTimeInSeconds(roundedTime);
    s1.incrementWeight(weight);
    return s1;
}
Also used : IntersectionVertex(org.opentripplanner.routing.vertextype.IntersectionVertex) Edge(org.opentripplanner.routing.graph.Edge)

Example 28 with IntersectionVertex

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

the class AreaEdgeList method addVertex.

/**
 * Safely add a vertex to this area. This creates edges to all other vertices unless those edges would cross one of the original edges.
 */
public void addVertex(IntersectionVertex newVertex, Graph graph) {
    GeometryFactory geometryFactory = GeometryUtils.getGeometryFactory();
    if (edges.size() == 0) {
        throw new RuntimeException("Can't add a vertex to an empty area");
    }
    @SuppressWarnings("unchecked") HashSet<IntersectionVertex> verticesCopy = (HashSet<IntersectionVertex>) vertices.clone();
    VERTEX: for (IntersectionVertex v : verticesCopy) {
        LineString newGeometry = geometryFactory.createLineString(new Coordinate[] { newVertex.getCoordinate(), v.getCoordinate() });
        // fall into any holes
        if (!originalEdges.union(originalEdges.getBoundary()).contains(newGeometry)) {
            continue VERTEX;
        }
        // check to see if this splits multiple NamedAreas. This code is rather similar to
        // code in OSMGBI, but the data structures are different
        createSegments(newVertex, v, areas, graph);
    }
    vertices.add(newVertex);
}
Also used : GeometryFactory(com.vividsolutions.jts.geom.GeometryFactory) LineString(com.vividsolutions.jts.geom.LineString) MultiLineString(com.vividsolutions.jts.geom.MultiLineString) Coordinate(com.vividsolutions.jts.geom.Coordinate) IntersectionVertex(org.opentripplanner.routing.vertextype.IntersectionVertex) HashSet(java.util.HashSet)

Example 29 with IntersectionVertex

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

the class TestTriangle method testTriangle.

public void testTriangle() {
    Coordinate c1 = new Coordinate(-122.575033, 45.456773);
    Coordinate c2 = new Coordinate(-122.576668, 45.451426);
    StreetVertex v1 = new IntersectionVertex(null, "v1", c1.x, c1.y, (NonLocalizedString) null);
    StreetVertex v2 = new IntersectionVertex(null, "v2", c2.x, c2.y, (NonLocalizedString) null);
    GeometryFactory factory = new GeometryFactory();
    LineString geometry = factory.createLineString(new Coordinate[] { c1, c2 });
    double length = 650.0;
    StreetWithElevationEdge testStreet = new StreetWithElevationEdge(v1, v2, geometry, "Test Lane", length, StreetTraversalPermission.ALL, false);
    // a safe street
    testStreet.setBicycleSafetyFactor(0.74f);
    Coordinate[] profile = new Coordinate[] { // slope = 0.1
    new Coordinate(0, 0), new Coordinate(length / 2, length / 20.0), // slope = -0.1
    new Coordinate(length, 0) };
    PackedCoordinateSequence elev = new PackedCoordinateSequence.Double(profile);
    testStreet.setElevationProfile(elev, false);
    SlopeCosts costs = ElevationUtils.getSlopeCosts(elev, true);
    double trueLength = costs.lengthMultiplier * length;
    double slopeWorkLength = testStreet.getSlopeWorkCostEffectiveLength();
    double slopeSpeedLength = testStreet.getSlopeSpeedEffectiveLength();
    RoutingRequest options = new RoutingRequest(TraverseMode.BICYCLE);
    options.optimize = OptimizeType.TRIANGLE;
    options.bikeSpeed = 6.0;
    options.walkReluctance = 1;
    options.setTriangleSafetyFactor(0);
    options.setTriangleSlopeFactor(0);
    options.setTriangleTimeFactor(1);
    State startState = new State(v1, options);
    State result = testStreet.traverse(startState);
    double timeWeight = result.getWeight();
    double expectedTimeWeight = slopeSpeedLength / options.getSpeed(TraverseMode.BICYCLE);
    assertTrue(Math.abs(expectedTimeWeight - timeWeight) < 0.00001);
    options.setTriangleSafetyFactor(0);
    options.setTriangleSlopeFactor(1);
    options.setTriangleTimeFactor(0);
    startState = new State(v1, options);
    result = testStreet.traverse(startState);
    double slopeWeight = result.getWeight();
    double expectedSlopeWeight = slopeWorkLength / options.getSpeed(TraverseMode.BICYCLE);
    assertTrue(Math.abs(expectedSlopeWeight - slopeWeight) < 0.00001);
    assertTrue(length * 1.5 / options.getSpeed(TraverseMode.BICYCLE) < slopeWeight);
    assertTrue(length * 1.5 * 10 / options.getSpeed(TraverseMode.BICYCLE) > slopeWeight);
    options.setTriangleSafetyFactor(1);
    options.setTriangleSlopeFactor(0);
    options.setTriangleTimeFactor(0);
    startState = new State(v1, options);
    result = testStreet.traverse(startState);
    double safetyWeight = result.getWeight();
    double slopeSafety = costs.slopeSafetyCost;
    double expectedSafetyWeight = (trueLength * 0.74 + slopeSafety) / options.getSpeed(TraverseMode.BICYCLE);
    assertTrue(Math.abs(expectedSafetyWeight - safetyWeight) < 0.00001);
    final double ONE_THIRD = 1 / 3.0;
    options.setTriangleSafetyFactor(ONE_THIRD);
    options.setTriangleSlopeFactor(ONE_THIRD);
    options.setTriangleTimeFactor(ONE_THIRD);
    startState = new State(v1, options);
    result = testStreet.traverse(startState);
    double averageWeight = result.getWeight();
    assertTrue(Math.abs(safetyWeight * ONE_THIRD + slopeWeight * ONE_THIRD + timeWeight * ONE_THIRD - averageWeight) < 0.00000001);
}
Also used : GeometryFactory(com.vividsolutions.jts.geom.GeometryFactory) SlopeCosts(org.opentripplanner.routing.util.SlopeCosts) Coordinate(com.vividsolutions.jts.geom.Coordinate) LineString(com.vividsolutions.jts.geom.LineString) State(org.opentripplanner.routing.core.State) IntersectionVertex(org.opentripplanner.routing.vertextype.IntersectionVertex) RoutingRequest(org.opentripplanner.routing.core.RoutingRequest) StreetVertex(org.opentripplanner.routing.vertextype.StreetVertex) PackedCoordinateSequence(org.opentripplanner.common.geometry.PackedCoordinateSequence)

Example 30 with IntersectionVertex

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

the class SimpleTraversalCostModelTest method testCalculateTurnAngle.

@Test
public void testCalculateTurnAngle() {
    // Graph for a fictional grid city with turn restrictions
    IntersectionVertex v1 = vertex("maple_1st", new Coordinate(2.0, 2.0), false);
    IntersectionVertex v2 = vertex("maple_2nd", new Coordinate(2.0, 1.0), false);
    StreetEdge e1 = edge(v1, v2, 1.0, false);
    // Edge has same first and last angle.
    assertEquals(90, e1.getInAngle());
    assertEquals(90, e1.getOutAngle());
    // 2 new ones
    IntersectionVertex v3 = vertex("test2", new Coordinate(1.0, 1.0), false);
    // Second edge
    StreetEdge e2 = edge(v2, v3, 1.0, false);
    assertEquals(0, e2.getInAngle());
    assertEquals(0, e2.getOutAngle());
    // Difference should be about 90.
    int diff = (e1.getOutAngle() - e2.getInAngle());
    assertEquals(90, diff);
    int turnAngle = costModel.calculateTurnAngle(e1, e2, options);
    assertEquals(270, turnAngle);
}
Also used : Coordinate(com.vividsolutions.jts.geom.Coordinate) IntersectionVertex(org.opentripplanner.routing.vertextype.IntersectionVertex) StreetEdge(org.opentripplanner.routing.edgetype.StreetEdge) Test(org.junit.Test)

Aggregations

IntersectionVertex (org.opentripplanner.routing.vertextype.IntersectionVertex)38 StreetEdge (org.opentripplanner.routing.edgetype.StreetEdge)23 Graph (org.opentripplanner.routing.graph.Graph)17 Coordinate (com.vividsolutions.jts.geom.Coordinate)16 StreetVertex (org.opentripplanner.routing.vertextype.StreetVertex)14 Vertex (org.opentripplanner.routing.graph.Vertex)12 LineString (com.vividsolutions.jts.geom.LineString)10 Test (org.junit.Test)10 Edge (org.opentripplanner.routing.graph.Edge)10 GeometryFactory (com.vividsolutions.jts.geom.GeometryFactory)8 HashSet (java.util.HashSet)8 FreeEdge (org.opentripplanner.routing.edgetype.FreeEdge)8 MultiLineString (com.vividsolutions.jts.geom.MultiLineString)5 ArrayList (java.util.ArrayList)5 Point (com.vividsolutions.jts.geom.Point)4 P2 (org.opentripplanner.common.model.P2)4 TransitStop (org.opentripplanner.routing.vertextype.TransitStop)4 RoutingRequest (org.opentripplanner.routing.core.RoutingRequest)3 State (org.opentripplanner.routing.core.State)3 AreaEdge (org.opentripplanner.routing.edgetype.AreaEdge)3