Search in sources :

Example 1 with QueryGraph

use of com.graphhopper.routing.querygraph.QueryGraph in project graphhopper by graphhopper.

the class IsochroneResource method doGet.

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response doGet(@Context UriInfo uriInfo, @QueryParam("profile") String profileName, @QueryParam("buckets") @Range(min = 1, max = 20) @DefaultValue("1") IntParam nBuckets, @QueryParam("reverse_flow") @DefaultValue("false") boolean reverseFlow, @QueryParam("point") @NotNull GHPointParam point, @QueryParam("time_limit") @DefaultValue("600") LongParam timeLimitInSeconds, @QueryParam("distance_limit") @DefaultValue("-1") LongParam distanceLimitInMeter, @QueryParam("weight_limit") @DefaultValue("-1") LongParam weightLimit, @QueryParam("type") @DefaultValue("json") ResponseType respType, @QueryParam("tolerance") @DefaultValue("0") double toleranceInMeter, @QueryParam("full_geometry") @DefaultValue("false") boolean fullGeometry) {
    StopWatch sw = new StopWatch().start();
    PMap hintsMap = new PMap();
    RouteResource.initHints(hintsMap, uriInfo.getQueryParameters());
    hintsMap.putObject(Parameters.CH.DISABLE, true);
    hintsMap.putObject(Parameters.Landmark.DISABLE, true);
    if (Helper.isEmpty(profileName)) {
        profileName = profileResolver.resolveProfile(hintsMap).getName();
        removeLegacyParameters(hintsMap);
    }
    errorIfLegacyParameters(hintsMap);
    Profile profile = graphHopper.getProfile(profileName);
    if (profile == null)
        throw new IllegalArgumentException("The requested profile '" + profileName + "' does not exist");
    LocationIndex locationIndex = graphHopper.getLocationIndex();
    Graph graph = graphHopper.getGraphHopperStorage();
    Weighting weighting = graphHopper.createWeighting(profile, hintsMap);
    BooleanEncodedValue inSubnetworkEnc = graphHopper.getEncodingManager().getBooleanEncodedValue(Subnetwork.key(profileName));
    if (hintsMap.has(Parameters.Routing.BLOCK_AREA)) {
        GraphEdgeIdFinder.BlockArea blockArea = GraphEdgeIdFinder.createBlockArea(graph, locationIndex, Collections.singletonList(point.get()), hintsMap, new FiniteWeightFilter(weighting));
        weighting = new BlockAreaWeighting(weighting, blockArea);
    }
    Snap snap = locationIndex.findClosest(point.get().lat, point.get().lon, new DefaultSnapFilter(weighting, inSubnetworkEnc));
    if (!snap.isValid())
        throw new IllegalArgumentException("Point not found:" + point);
    QueryGraph queryGraph = QueryGraph.create(graph, snap);
    TraversalMode traversalMode = profile.isTurnCosts() ? EDGE_BASED : NODE_BASED;
    ShortestPathTree shortestPathTree = new ShortestPathTree(queryGraph, queryGraph.wrapWeighting(weighting), reverseFlow, traversalMode);
    double limit;
    if (weightLimit.get() > 0) {
        limit = weightLimit.get();
        shortestPathTree.setWeightLimit(limit + Math.max(limit * 0.14, 2_000));
    } else if (distanceLimitInMeter.get() > 0) {
        limit = distanceLimitInMeter.get();
        shortestPathTree.setDistanceLimit(limit + Math.max(limit * 0.14, 2_000));
    } else {
        limit = timeLimitInSeconds.get() * 1000;
        shortestPathTree.setTimeLimit(limit + Math.max(limit * 0.14, 200_000));
    }
    ArrayList<Double> zs = new ArrayList<>();
    double delta = limit / nBuckets.get();
    for (int i = 0; i < nBuckets.get(); i++) {
        zs.add((i + 1) * delta);
    }
    ToDoubleFunction<ShortestPathTree.IsoLabel> fz;
    if (weightLimit.get() > 0) {
        fz = l -> l.weight;
    } else if (distanceLimitInMeter.get() > 0) {
        fz = l -> l.distance;
    } else {
        fz = l -> l.time;
    }
    Triangulator.Result result = triangulator.triangulate(snap, queryGraph, shortestPathTree, fz, degreesFromMeters(toleranceInMeter));
    ContourBuilder contourBuilder = new ContourBuilder(result.triangulation);
    ArrayList<Geometry> isochrones = new ArrayList<>();
    for (Double z : zs) {
        logger.info("Building contour z={}", z);
        MultiPolygon isochrone = contourBuilder.computeIsoline(z, result.seedEdges);
        if (fullGeometry) {
            isochrones.add(isochrone);
        } else {
            Polygon maxPolygon = heuristicallyFindMainConnectedComponent(isochrone, isochrone.getFactory().createPoint(new Coordinate(point.get().lon, point.get().lat)));
            isochrones.add(isochrone.getFactory().createPolygon(((LinearRing) maxPolygon.getExteriorRing())));
        }
    }
    ArrayList<JsonFeature> features = new ArrayList<>();
    for (Geometry isochrone : isochrones) {
        JsonFeature feature = new JsonFeature();
        HashMap<String, Object> properties = new HashMap<>();
        properties.put("bucket", features.size());
        if (respType == geojson) {
            properties.put("copyrights", ResponsePathSerializer.COPYRIGHTS);
        }
        feature.setProperties(properties);
        feature.setGeometry(isochrone);
        features.add(feature);
    }
    ObjectNode json = JsonNodeFactory.instance.objectNode();
    sw.stop();
    ObjectNode finalJson = null;
    if (respType == geojson) {
        json.put("type", "FeatureCollection");
        json.putPOJO("features", features);
        finalJson = json;
    } else {
        json.putPOJO("polygons", features);
        final ObjectNode info = json.putObject("info");
        info.putPOJO("copyrights", ResponsePathSerializer.COPYRIGHTS);
        info.put("took", Math.round((float) sw.getMillis()));
        finalJson = json;
    }
    logger.info("took: " + sw.getSeconds() + ", visited nodes:" + shortestPathTree.getVisitedNodes());
    return Response.ok(finalJson).header("X-GH-Took", "" + sw.getSeconds() * 1000).build();
}
Also used : ProfileResolver(com.graphhopper.routing.ProfileResolver) LoggerFactory(org.slf4j.LoggerFactory) Subnetwork(com.graphhopper.routing.ev.Subnetwork) HashMap(java.util.HashMap) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) ArrayList(java.util.ArrayList) Range(org.hibernate.validator.constraints.Range) Inject(javax.inject.Inject) MediaType(javax.ws.rs.core.MediaType) ShortestPathTree(com.graphhopper.isochrone.algorithm.ShortestPathTree) BlockAreaWeighting(com.graphhopper.routing.weighting.BlockAreaWeighting) IntParam(io.dropwizard.jersey.params.IntParam) Profile(com.graphhopper.config.Profile) TraversalMode(com.graphhopper.routing.util.TraversalMode) Graph(com.graphhopper.storage.Graph) NODE_BASED(com.graphhopper.routing.util.TraversalMode.NODE_BASED) GraphHopper(com.graphhopper.GraphHopper) org.locationtech.jts.geom(org.locationtech.jts.geom) com.graphhopper.util(com.graphhopper.util) Logger(org.slf4j.Logger) Context(javax.ws.rs.core.Context) ResponsePathSerializer(com.graphhopper.jackson.ResponsePathSerializer) LocationIndex(com.graphhopper.storage.index.LocationIndex) RouteResource.errorIfLegacyParameters(com.graphhopper.resources.RouteResource.errorIfLegacyParameters) LongParam(io.dropwizard.jersey.params.LongParam) BooleanEncodedValue(com.graphhopper.routing.ev.BooleanEncodedValue) NotNull(javax.validation.constraints.NotNull) ResponseType.geojson(com.graphhopper.resources.IsochroneResource.ResponseType.geojson) QueryGraph(com.graphhopper.routing.querygraph.QueryGraph) GHPointParam(com.graphhopper.http.GHPointParam) GraphEdgeIdFinder(com.graphhopper.storage.GraphEdgeIdFinder) Triangulator(com.graphhopper.isochrone.algorithm.Triangulator) ContourBuilder(com.graphhopper.isochrone.algorithm.ContourBuilder) javax.ws.rs(javax.ws.rs) Response(javax.ws.rs.core.Response) JsonNodeFactory(com.fasterxml.jackson.databind.node.JsonNodeFactory) Weighting(com.graphhopper.routing.weighting.Weighting) ToDoubleFunction(java.util.function.ToDoubleFunction) FiniteWeightFilter(com.graphhopper.routing.util.FiniteWeightFilter) DefaultSnapFilter(com.graphhopper.routing.util.DefaultSnapFilter) Snap(com.graphhopper.storage.index.Snap) UriInfo(javax.ws.rs.core.UriInfo) EDGE_BASED(com.graphhopper.routing.util.TraversalMode.EDGE_BASED) Collections(java.util.Collections) RouteResource.removeLegacyParameters(com.graphhopper.resources.RouteResource.removeLegacyParameters) GraphEdgeIdFinder(com.graphhopper.storage.GraphEdgeIdFinder) Triangulator(com.graphhopper.isochrone.algorithm.Triangulator) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) BlockAreaWeighting(com.graphhopper.routing.weighting.BlockAreaWeighting) TraversalMode(com.graphhopper.routing.util.TraversalMode) Snap(com.graphhopper.storage.index.Snap) Profile(com.graphhopper.config.Profile) FiniteWeightFilter(com.graphhopper.routing.util.FiniteWeightFilter) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) DefaultSnapFilter(com.graphhopper.routing.util.DefaultSnapFilter) LocationIndex(com.graphhopper.storage.index.LocationIndex) Graph(com.graphhopper.storage.Graph) QueryGraph(com.graphhopper.routing.querygraph.QueryGraph) BlockAreaWeighting(com.graphhopper.routing.weighting.BlockAreaWeighting) Weighting(com.graphhopper.routing.weighting.Weighting) BooleanEncodedValue(com.graphhopper.routing.ev.BooleanEncodedValue) ContourBuilder(com.graphhopper.isochrone.algorithm.ContourBuilder) ShortestPathTree(com.graphhopper.isochrone.algorithm.ShortestPathTree) QueryGraph(com.graphhopper.routing.querygraph.QueryGraph)

Example 2 with QueryGraph

use of com.graphhopper.routing.querygraph.QueryGraph in project graphhopper by graphhopper.

the class DirectedBidirectionalDijkstraTest method directedRouting_noUTurnAtVirtualEdge.

@Test
public void directedRouting_noUTurnAtVirtualEdge() {
    // what happens if we force to leave the snapped (virtual) node in eastern direction, even though we would
    // like to go to node 0 just west from us ? we have to make sure there is no u-turn at node 1 (from the
    // virtual edge onto edge 1-0). the query graph does this for us!
    // x
    // 0 -- 1 -> 2
    // |         |
    // 5 <- 4 <- 3
    GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1));
    GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1));
    GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1));
    GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1));
    GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 5).setDistance(1));
    GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 0).setDistance(1));
    NodeAccess na = graph.getNodeAccess();
    na.setNode(0, 1, 0);
    na.setNode(1, 1, 1);
    na.setNode(2, 1, 2);
    na.setNode(3, 0, 2);
    na.setNode(4, 0, 1);
    na.setNode(5, 0, 0);
    LocationIndexTree locationIndex = new LocationIndexTree(graph, graph.getDirectory());
    locationIndex.prepareIndex();
    Snap snap = locationIndex.findClosest(1.1, 0.5, EdgeFilter.ALL_EDGES);
    QueryGraph queryGraph = QueryGraph.create(graph, snap);
    assertEquals(Snap.Position.EDGE, snap.getSnappedPosition(), "wanted to get EDGE");
    assertEquals(6, snap.getClosestNode());
    // check what edges there are on the query graph directly, there should not be a direct connection from 1 to 0
    // anymore, but only the virtual edge from 1 to 6 (this is how the u-turn is prevented).
    assertEquals(new HashSet<>(Arrays.asList(0, 2)), GHUtility.getNeighbors(graph.createEdgeExplorer().setBaseNode(1)));
    assertEquals(new HashSet<>(Arrays.asList(6, 2)), GHUtility.getNeighbors(queryGraph.createEdgeExplorer().setBaseNode(1)));
    EdgeIteratorState virtualEdge = GHUtility.getEdge(queryGraph, 6, 1);
    int outEdge = virtualEdge.getEdge();
    BidirRoutingAlgorithm algo = createAlgo(queryGraph, weighting);
    Path path = algo.calcPath(6, 0, outEdge, ANY_EDGE);
    assertEquals(nodes(6, 1, 2, 3, 4, 5, 0), path.calcNodes());
    assertEquals(5 + virtualEdge.getDistance(), path.getDistance(), 1.e-3);
}
Also used : EdgeIteratorState(com.graphhopper.util.EdgeIteratorState) Snap(com.graphhopper.storage.index.Snap) QueryGraph(com.graphhopper.routing.querygraph.QueryGraph) LocationIndexTree(com.graphhopper.storage.index.LocationIndexTree) RepeatedTest(org.junit.jupiter.api.RepeatedTest) Test(org.junit.jupiter.api.Test)

Example 3 with QueryGraph

use of com.graphhopper.routing.querygraph.QueryGraph in project graphhopper by graphhopper.

the class RoundTripRoutingTest method testCalcRoundTrip.

@Test
public void testCalcRoundTrip() {
    Graph g = createTestGraph();
    LocationIndex locationIndex = new LocationIndexTree(g, new RAMDirectory()).prepareIndex();
    Snap snap4 = locationIndex.findClosest(0.05, 0.25, EdgeFilter.ALL_EDGES);
    assertEquals(4, snap4.getClosestNode());
    Snap snap5 = locationIndex.findClosest(0.00, 0.05, EdgeFilter.ALL_EDGES);
    assertEquals(5, snap5.getClosestNode());
    Snap snap6 = locationIndex.findClosest(0.00, 0.10, EdgeFilter.ALL_EDGES);
    assertEquals(6, snap6.getClosestNode());
    QueryGraph qGraph = QueryGraph.create(g, Arrays.asList(snap4, snap5));
    FlexiblePathCalculator pathCalculator = new FlexiblePathCalculator(qGraph, new RoutingAlgorithmFactorySimple(), fastestWeighting, new AlgorithmOptions().setAlgorithm(DIJKSTRA_BI).setTraversalMode(tMode));
    List<Path> paths = RoundTripRouting.calcPaths(Arrays.asList(snap5, snap4, snap5), pathCalculator).paths;
    assertEquals(2, paths.size());
    assertEquals(IntArrayList.from(5, 6, 3), paths.get(0).calcNodes());
    assertEquals(IntArrayList.from(3, 2, 9, 1, 5), paths.get(1).calcNodes());
    qGraph = QueryGraph.create(g, Arrays.asList(snap4, snap6));
    pathCalculator = new FlexiblePathCalculator(qGraph, new RoutingAlgorithmFactorySimple(), fastestWeighting, new AlgorithmOptions().setAlgorithm(DIJKSTRA_BI).setTraversalMode(tMode));
    paths = RoundTripRouting.calcPaths(Arrays.asList(snap6, snap4, snap6), pathCalculator).paths;
    assertEquals(2, paths.size());
    assertEquals(IntArrayList.from(6, 3), paths.get(0).calcNodes());
    assertEquals(IntArrayList.from(3, 4, 8, 7, 6), paths.get(1).calcNodes());
}
Also used : QueryGraph(com.graphhopper.routing.querygraph.QueryGraph) Graph(com.graphhopper.storage.Graph) LocationIndex(com.graphhopper.storage.index.LocationIndex) Snap(com.graphhopper.storage.index.Snap) RAMDirectory(com.graphhopper.storage.RAMDirectory) QueryGraph(com.graphhopper.routing.querygraph.QueryGraph) LocationIndexTree(com.graphhopper.storage.index.LocationIndexTree) Test(org.junit.jupiter.api.Test)

Example 4 with QueryGraph

use of com.graphhopper.routing.querygraph.QueryGraph in project graphhopper by graphhopper.

the class RoundTripRoutingTest method testLookupAndCalcPaths_simpleSquareGraph.

@Test
public void testLookupAndCalcPaths_simpleSquareGraph() {
    Graph g = createSquareGraph();
    // start at node 0 and head south, make sure the round trip is long enough to reach most southern node 6
    GHPoint start = new GHPoint(1, -1);
    double heading = 180.0;
    int numPoints = 2;
    double roundTripDistance = 670000;
    PMap hints = new PMap();
    hints.putObject(Parameters.Algorithms.RoundTrip.POINTS, numPoints);
    hints.putObject(Parameters.Algorithms.RoundTrip.DISTANCE, roundTripDistance);
    LocationIndex locationIndex = new LocationIndexTree(g, new RAMDirectory()).prepareIndex();
    List<Snap> stagePoints = RoundTripRouting.lookup(Collections.singletonList(start), new FiniteWeightFilter(fastestWeighting), locationIndex, new RoundTripRouting.Params(hints, heading, 3));
    assertEquals(3, stagePoints.size());
    assertEquals(0, stagePoints.get(0).getClosestNode());
    assertEquals(6, stagePoints.get(1).getClosestNode());
    assertEquals(0, stagePoints.get(2).getClosestNode());
    QueryGraph queryGraph = QueryGraph.create(g, stagePoints);
    List<Path> paths = RoundTripRouting.calcPaths(stagePoints, new FlexiblePathCalculator(queryGraph, new RoutingAlgorithmFactorySimple(), fastestWeighting, new AlgorithmOptions().setAlgorithm(DIJKSTRA_BI).setTraversalMode(tMode))).paths;
    // make sure the resulting paths are connected and form a round trip starting and ending at the start node 0
    assertEquals(2, paths.size());
    assertEquals(IntArrayList.from(0, 7, 6, 5), paths.get(0).calcNodes());
    assertEquals(IntArrayList.from(5, 4, 3, 2, 1, 0), paths.get(1).calcNodes());
}
Also used : PMap(com.graphhopper.util.PMap) LocationIndex(com.graphhopper.storage.index.LocationIndex) Snap(com.graphhopper.storage.index.Snap) GHPoint(com.graphhopper.util.shapes.GHPoint) RAMDirectory(com.graphhopper.storage.RAMDirectory) LocationIndexTree(com.graphhopper.storage.index.LocationIndexTree) QueryGraph(com.graphhopper.routing.querygraph.QueryGraph) Graph(com.graphhopper.storage.Graph) GHPoint(com.graphhopper.util.shapes.GHPoint) QueryGraph(com.graphhopper.routing.querygraph.QueryGraph) Test(org.junit.jupiter.api.Test)

Example 5 with QueryGraph

use of com.graphhopper.routing.querygraph.QueryGraph in project graphhopper by graphhopper.

the class CHTurnCostTest method test_issue_1593_simple.

@ParameterizedTest
@ValueSource(strings = { DIJKSTRA_BI, ASTAR_BI })
public void test_issue_1593_simple(String algo) {
    // 1
    // |
    // 3-0-x-5-4
    // |
    // 2
    NodeAccess na = graph.getNodeAccess();
    na.setNode(1, 0.2, 0.0);
    na.setNode(3, 0.1, 0.0);
    na.setNode(2, 0.0, 0.0);
    na.setNode(0, 0.1, 0.1);
    na.setNode(5, 0.1, 0.2);
    na.setNode(4, 0.1, 0.3);
    EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 1).setDistance(10));
    EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(10));
    GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 0).setDistance(10));
    GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 5).setDistance(10));
    GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 4).setDistance(10));
    // cannot go, 2-3-1
    setRestriction(edge1, edge0, 3);
    graph.freeze();
    prepareCH(0, 1, 2, 3, 4, 5);
    assertEquals(5, chGraph.getBaseGraph().getEdges());
    assertEquals(7, chGraph.getEdges(), "expected two shortcuts: 3->5 and 5->3");
    // there should be no path from 2 to 1, because of the turn restriction and because u-turns are not allowed
    assertFalse(findPathUsingDijkstra(2, 1).isFound());
    compareCHQueryWithDijkstra(2, 1);
    // we have to pay attention when there are virtual nodes: turning from the shortcut 3-5 onto the
    // virtual edge 5-x should be forbidden.
    LocationIndexTree index = new LocationIndexTree(graph, new RAMDirectory());
    index.prepareIndex();
    Snap snap = index.findClosest(0.1, 0.15, EdgeFilter.ALL_EDGES);
    QueryGraph queryGraph = QueryGraph.create(graph, snap);
    assertEquals(1, queryGraph.getNodes() - chGraph.getNodes(), "expected one virtual node");
    QueryRoutingCHGraph routingCHGraph = new QueryRoutingCHGraph(chGraph, queryGraph);
    RoutingAlgorithm chAlgo = new CHRoutingAlgorithmFactory(routingCHGraph).createAlgo(new PMap().putObject(ALGORITHM, algo));
    Path path = chAlgo.calcPath(2, 1);
    assertFalse(path.isFound(), "no path should be found, but found " + path.calcNodes());
}
Also used : RoutingAlgorithm(com.graphhopper.routing.RoutingAlgorithm) Path(com.graphhopper.routing.Path) QueryRoutingCHGraph(com.graphhopper.routing.querygraph.QueryRoutingCHGraph) Snap(com.graphhopper.storage.index.Snap) QueryGraph(com.graphhopper.routing.querygraph.QueryGraph) LocationIndexTree(com.graphhopper.storage.index.LocationIndexTree) ValueSource(org.junit.jupiter.params.provider.ValueSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Aggregations

QueryGraph (com.graphhopper.routing.querygraph.QueryGraph)37 Snap (com.graphhopper.storage.index.Snap)32 Test (org.junit.jupiter.api.Test)18 QueryRoutingCHGraph (com.graphhopper.routing.querygraph.QueryRoutingCHGraph)17 LocationIndexTree (com.graphhopper.storage.index.LocationIndexTree)16 EdgeIteratorState (com.graphhopper.util.EdgeIteratorState)11 Path (com.graphhopper.routing.Path)9 Weighting (com.graphhopper.routing.weighting.Weighting)9 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)7 RoutingAlgorithm (com.graphhopper.routing.RoutingAlgorithm)6 FastestWeighting (com.graphhopper.routing.weighting.FastestWeighting)6 PMap (com.graphhopper.util.PMap)6 ArrayList (java.util.ArrayList)6 GraphHopper (com.graphhopper.GraphHopper)5 GHPoint (com.graphhopper.util.shapes.GHPoint)5 ValueSource (org.junit.jupiter.params.provider.ValueSource)5 Graph (com.graphhopper.storage.Graph)4 LocationIndex (com.graphhopper.storage.index.LocationIndex)4 GHResponse (com.graphhopper.GHResponse)3 ResponsePath (com.graphhopper.ResponsePath)3