Search in sources :

Example 26 with EdgeIteratorState

use of com.graphhopper.util.EdgeIteratorState in project graphhopper by graphhopper.

the class DijkstraBidirectionCHTest method runTestWithDirectionDependentEdgeSpeed.

private void runTestWithDirectionDependentEdgeSpeed(int speed, int revSpeed, int from, int to, IntArrayList expectedPath, FlagEncoder encoder) {
    EncodingManager encodingManager = new EncodingManager(encoder);
    FastestWeighting weighting = new FastestWeighting(encoder);
    AlgorithmOptions algoOpts = AlgorithmOptions.start().weighting(weighting).build();
    GraphHopperStorage graph = createGHStorage(encodingManager, Arrays.asList(weighting), false);
    EdgeIteratorState edge = graph.edge(0, 1, 2, true);
    long flags = edge.getFlags();
    flags = encoder.setSpeed(flags, speed);
    flags = encoder.setReverseSpeed(flags, revSpeed);
    edge.setFlags(flags);
    graph.edge(1, 2, 1, true);
    CHGraph chGraph = graph.getGraph(CHGraph.class);
    for (int i = 0; i < 3; ++i) {
        chGraph.setLevel(i, i);
    }
    graph.freeze();
    RoutingAlgorithm algo = createCHAlgo(graph, chGraph, true, algoOpts);
    Path p = algo.calcPath(from, to);
    assertEquals(3, p.getDistance(), 1.e-3);
    assertEquals(p.toString(), expectedPath, p.calcNodes());
}
Also used : EdgeIteratorState(com.graphhopper.util.EdgeIteratorState) CHEdgeIteratorState(com.graphhopper.util.CHEdgeIteratorState) FastestWeighting(com.graphhopper.routing.weighting.FastestWeighting)

Example 27 with EdgeIteratorState

use of com.graphhopper.util.EdgeIteratorState in project graphhopper by graphhopper.

the class JTSTriangulator method triangulate.

public Result triangulate(Snap snap, QueryGraph queryGraph, ShortestPathTree shortestPathTree, ToDoubleFunction<ShortestPathTree.IsoLabel> fz, double tolerance) {
    final NodeAccess na = queryGraph.getNodeAccess();
    Collection<Coordinate> sites = new ArrayList<>();
    shortestPathTree.search(snap.getClosestNode(), label -> {
        double exploreValue = fz.applyAsDouble(label);
        double lat = na.getLat(label.node);
        double lon = na.getLon(label.node);
        Coordinate site = new Coordinate(lon, lat);
        site.z = exploreValue;
        sites.add(site);
        // add a pillar node to increase precision a bit for longer roads
        if (label.parent != null) {
            EdgeIteratorState edge = queryGraph.getEdgeIteratorState(label.edge, label.node);
            PointList innerPoints = edge.fetchWayGeometry(FetchMode.PILLAR_ONLY);
            if (innerPoints.size() > 0) {
                int midIndex = innerPoints.size() / 2;
                double lat2 = innerPoints.getLat(midIndex);
                double lon2 = innerPoints.getLon(midIndex);
                Coordinate site2 = new Coordinate(lon2, lat2);
                site2.z = exploreValue;
                sites.add(site2);
            }
        }
    });
    if (sites.size() > routerConfig.getMaxVisitedNodes() / 3)
        throw new IllegalArgumentException("Too many nodes would be included in post processing (" + sites.size() + "). Let us know if you need this increased.");
    // Sites may contain repeated coordinates. Especially for edge-based traversal, that's expected -- we visit
    // each node multiple times.
    // But that's okay, the triangulator de-dupes by itself, and it keeps the first z-value it sees, which is
    // what we want.
    Collection<ConstraintVertex> constraintVertices = sites.stream().map(ConstraintVertex::new).collect(Collectors.toList());
    ConformingDelaunayTriangulator conformingDelaunayTriangulator = new ConformingDelaunayTriangulator(constraintVertices, tolerance);
    conformingDelaunayTriangulator.setConstraints(new ArrayList<>(), new ArrayList<>());
    conformingDelaunayTriangulator.formInitialDelaunay();
    conformingDelaunayTriangulator.enforceConstraints();
    Geometry convexHull = conformingDelaunayTriangulator.getConvexHull();
    if (!(convexHull instanceof Polygon)) {
        throw new IllegalArgumentException("Too few points found. " + "Please try a different 'point' or a larger 'time_limit'.");
    }
    QuadEdgeSubdivision tin = conformingDelaunayTriangulator.getSubdivision();
    for (Vertex vertex : (Collection<Vertex>) tin.getVertices(true)) {
        if (tin.isFrameVertex(vertex)) {
            vertex.setZ(Double.MAX_VALUE);
        }
    }
    ReadableTriangulation triangulation = ReadableTriangulation.wrap(tin);
    return new Result(triangulation, triangulation.getEdges());
}
Also used : PointList(com.graphhopper.util.PointList) ConstraintVertex(org.locationtech.jts.triangulate.ConstraintVertex) Vertex(org.locationtech.jts.triangulate.quadedge.Vertex) NodeAccess(com.graphhopper.storage.NodeAccess) ArrayList(java.util.ArrayList) ConformingDelaunayTriangulator(org.locationtech.jts.triangulate.ConformingDelaunayTriangulator) QuadEdgeSubdivision(org.locationtech.jts.triangulate.quadedge.QuadEdgeSubdivision) ConstraintVertex(org.locationtech.jts.triangulate.ConstraintVertex) Geometry(org.locationtech.jts.geom.Geometry) Coordinate(org.locationtech.jts.geom.Coordinate) EdgeIteratorState(com.graphhopper.util.EdgeIteratorState) Collection(java.util.Collection) Polygon(org.locationtech.jts.geom.Polygon)

Example 28 with EdgeIteratorState

use of com.graphhopper.util.EdgeIteratorState in project graphhopper by graphhopper.

the class PtIsochroneResource method doGet.

@GET
@Produces({ MediaType.APPLICATION_JSON })
public Response doGet(@QueryParam("point") GHLocationParam sourceParam, @QueryParam("time_limit") @DefaultValue("600") long seconds, @QueryParam("reverse_flow") @DefaultValue("false") boolean reverseFlow, @QueryParam("pt.earliest_departure_time") @NotNull OffsetDateTimeParam departureTimeParam, @QueryParam("pt.blocked_route_types") @DefaultValue("0") int blockedRouteTypes, @QueryParam("result") @DefaultValue("multipolygon") String format) {
    Instant initialTime = departureTimeParam.get().toInstant();
    GHLocation location = sourceParam.get();
    double targetZ = seconds * 1000;
    GeometryFactory geometryFactory = new GeometryFactory();
    final FlagEncoder footEncoder = encodingManager.getEncoder("foot");
    final Weighting weighting = new FastestWeighting(footEncoder);
    DefaultSnapFilter snapFilter = new DefaultSnapFilter(weighting, graphHopperStorage.getEncodingManager().getBooleanEncodedValue(Subnetwork.key("foot")));
    PtLocationSnapper.Result snapResult = new PtLocationSnapper(graphHopperStorage, locationIndex, gtfsStorage).snapAll(Arrays.asList(location), Arrays.asList(snapFilter));
    GraphExplorer graphExplorer = new GraphExplorer(snapResult.queryGraph, gtfsStorage.getPtGraph(), weighting, gtfsStorage, RealtimeFeed.empty(), reverseFlow, false, false, 5.0, reverseFlow, blockedRouteTypes);
    MultiCriteriaLabelSetting router = new MultiCriteriaLabelSetting(graphExplorer, reverseFlow, false, false, 0, Collections.emptyList());
    Map<Coordinate, Double> z1 = new HashMap<>();
    NodeAccess nodeAccess = snapResult.queryGraph.getNodeAccess();
    for (Label label : router.calcLabels(snapResult.nodes.get(0), initialTime)) {
        if (!((label.currentTime - initialTime.toEpochMilli()) * (reverseFlow ? -1 : 1) <= targetZ)) {
            break;
        }
        if (label.node.streetNode != -1) {
            Coordinate nodeCoordinate = new Coordinate(nodeAccess.getLon(label.node.streetNode), nodeAccess.getLat(label.node.streetNode));
            z1.merge(nodeCoordinate, (double) (label.currentTime - initialTime.toEpochMilli()) * (reverseFlow ? -1 : 1), Math::min);
        } else if (label.edge != null && (label.edge.getType() == GtfsStorage.EdgeType.EXIT_PT || label.edge.getType() == GtfsStorage.EdgeType.ENTER_PT)) {
            GtfsStorage.PlatformDescriptor platformDescriptor = label.edge.getPlatformDescriptor();
            Stop stop = gtfsStorage.getGtfsFeeds().get(platformDescriptor.feed_id).stops.get(platformDescriptor.stop_id);
            Coordinate nodeCoordinate = new Coordinate(stop.stop_lon, stop.stop_lat);
            z1.merge(nodeCoordinate, (double) (label.currentTime - initialTime.toEpochMilli()) * (reverseFlow ? -1 : 1), Math::min);
        }
    }
    if (format.equals("multipoint")) {
        MultiPoint exploredPoints = geometryFactory.createMultiPointFromCoords(z1.keySet().toArray(new Coordinate[0]));
        return wrap(exploredPoints);
    } else {
        MultiPoint exploredPoints = geometryFactory.createMultiPointFromCoords(z1.keySet().toArray(new Coordinate[0]));
        // Get at least all nodes within our bounding box (I think convex hull would be enough.)
        // I think then we should have all possible encroaching points. (Proof needed.)
        locationIndex.query(BBox.fromEnvelope(exploredPoints.getEnvelopeInternal()), edgeId -> {
            EdgeIteratorState edge = snapResult.queryGraph.getEdgeIteratorStateForKey(edgeId * 2);
            z1.merge(new Coordinate(nodeAccess.getLon(edge.getBaseNode()), nodeAccess.getLat(edge.getBaseNode())), Double.MAX_VALUE, Math::min);
            z1.merge(new Coordinate(nodeAccess.getLon(edge.getAdjNode()), nodeAccess.getLat(edge.getAdjNode())), Double.MAX_VALUE, Math::min);
        });
        exploredPoints = geometryFactory.createMultiPointFromCoords(z1.keySet().toArray(new Coordinate[0]));
        CoordinateList siteCoords = DelaunayTriangulationBuilder.extractUniqueCoordinates(exploredPoints);
        List<ConstraintVertex> constraintVertices = new ArrayList<>();
        for (Object siteCoord : siteCoords) {
            Coordinate coord = (Coordinate) siteCoord;
            constraintVertices.add(new ConstraintVertex(coord));
        }
        ConformingDelaunayTriangulator cdt = new ConformingDelaunayTriangulator(constraintVertices, JTS_TOLERANCE);
        cdt.setConstraints(new ArrayList(), new ArrayList());
        cdt.formInitialDelaunay();
        QuadEdgeSubdivision tin = cdt.getSubdivision();
        for (Vertex vertex : (Collection<Vertex>) tin.getVertices(true)) {
            if (tin.isFrameVertex(vertex)) {
                vertex.setZ(Double.MAX_VALUE);
            } else {
                Double aDouble = z1.get(vertex.getCoordinate());
                if (aDouble != null) {
                    vertex.setZ(aDouble);
                } else {
                    vertex.setZ(Double.MAX_VALUE);
                }
            }
        }
        ReadableTriangulation triangulation = ReadableTriangulation.wrap(tin);
        ContourBuilder contourBuilder = new ContourBuilder(triangulation);
        MultiPolygon isoline = contourBuilder.computeIsoline(targetZ, triangulation.getEdges());
        // debugging tool
        if (format.equals("triangulation")) {
            Response response = new Response();
            for (Vertex vertex : (Collection<Vertex>) tin.getVertices(true)) {
                JsonFeature feature = new JsonFeature();
                feature.setGeometry(geometryFactory.createPoint(vertex.getCoordinate()));
                HashMap<String, Object> properties = new HashMap<>();
                properties.put("z", vertex.getZ());
                feature.setProperties(properties);
                response.polygons.add(feature);
            }
            for (QuadEdge edge : (Collection<QuadEdge>) tin.getPrimaryEdges(false)) {
                JsonFeature feature = new JsonFeature();
                feature.setGeometry(edge.toLineSegment().toGeometry(geometryFactory));
                HashMap<String, Object> properties = new HashMap<>();
                feature.setProperties(properties);
                response.polygons.add(feature);
            }
            JsonFeature feature = new JsonFeature();
            feature.setGeometry(isoline);
            HashMap<String, Object> properties = new HashMap<>();
            properties.put("z", targetZ);
            feature.setProperties(properties);
            response.polygons.add(feature);
            response.info.copyrights.addAll(ResponsePathSerializer.COPYRIGHTS);
            return response;
        } else {
            return wrap(isoline);
        }
    }
}
Also used : ConstraintVertex(org.locationtech.jts.triangulate.ConstraintVertex) Vertex(org.locationtech.jts.triangulate.quadedge.Vertex) NodeAccess(com.graphhopper.storage.NodeAccess) FlagEncoder(com.graphhopper.routing.util.FlagEncoder) Stop(com.conveyal.gtfs.model.Stop) ConstraintVertex(org.locationtech.jts.triangulate.ConstraintVertex) EdgeIteratorState(com.graphhopper.util.EdgeIteratorState) FastestWeighting(com.graphhopper.routing.weighting.FastestWeighting) QuadEdge(org.locationtech.jts.triangulate.quadedge.QuadEdge) DefaultSnapFilter(com.graphhopper.routing.util.DefaultSnapFilter) Instant(java.time.Instant) ReadableTriangulation(com.graphhopper.isochrone.algorithm.ReadableTriangulation) ConformingDelaunayTriangulator(org.locationtech.jts.triangulate.ConformingDelaunayTriangulator) QuadEdgeSubdivision(org.locationtech.jts.triangulate.quadedge.QuadEdgeSubdivision) JsonFeature(com.graphhopper.util.JsonFeature) FastestWeighting(com.graphhopper.routing.weighting.FastestWeighting) Weighting(com.graphhopper.routing.weighting.Weighting) ContourBuilder(com.graphhopper.isochrone.algorithm.ContourBuilder)

Example 29 with EdgeIteratorState

use of com.graphhopper.util.EdgeIteratorState in project graphhopper by graphhopper.

the class HeadingRoutingTest method calcNodes.

private int[] calcNodes(Graph graph, ResponsePath responsePath) {
    List<PathDetail> edgeKeys = responsePath.getPathDetails().get("edge_key");
    int[] result = new int[edgeKeys.size() + 1];
    for (int i = 0; i < edgeKeys.size(); i++) {
        int edgeKey = (int) edgeKeys.get(i).getValue();
        int edgeId = edgeKey / 2;
        EdgeIteratorState edgeIteratorState = graph.getEdgeIteratorState(edgeId, Integer.MIN_VALUE);
        result[i] = edgeKey % 2 == 0 ? edgeIteratorState.getBaseNode() : edgeIteratorState.getAdjNode();
        if (i == edgeKeys.size() - 1)
            result[edgeKeys.size()] = edgeKey % 2 == 0 ? edgeIteratorState.getAdjNode() : edgeIteratorState.getBaseNode();
    }
    return result;
}
Also used : PathDetail(com.graphhopper.util.details.PathDetail) EdgeIteratorState(com.graphhopper.util.EdgeIteratorState) GHPoint(com.graphhopper.util.shapes.GHPoint)

Example 30 with EdgeIteratorState

use of com.graphhopper.util.EdgeIteratorState in project graphhopper by graphhopper.

the class CHQueryWithTurnCostsTest method testFindPath_shortcutLoopIsRecognizedAsIncomingEdge.

@ParameterizedTest
@ArgumentsSource(FixtureProvider.class)
public void testFindPath_shortcutLoopIsRecognizedAsIncomingEdge(Fixture f) {
    // -0-
    // \ /
    // 3 -- 4 -- 2 -- 1
    EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(3, 4).setDistance(1));
    EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(4, 2).setDistance(1));
    EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(2, 0).setDistance(1));
    EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(0, 2).setDistance(1));
    EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(2, 1).setDistance(1));
    f.setRestriction(edge1, edge4, 2);
    f.freeze();
    f.setIdentityLevels();
    // contracting node 0 yields (the only) shortcut - and its a loop
    f.addShortcut(2, 2, edge2.getEdge(), edge3.getEdge(), edge2.getEdge(), edge3.getEdge(), 2, false);
    // node 2 is the bridge node where the forward and backward searches meet (highest level). since there is a turn restriction
    // at node 2 we cannot go from 4 to 1 directly, but we need to take the loop at 2 first. when the backward
    // search arrives at 2 it is crucial that the ('forward') loop-shortcut at 2 is recognized as an incoming edge
    // at node 2, otherwise the backward search ends at node 2. the forward search can never reach node 2 at all,
    // because it never goes to a lower level. so when the backward search does not see the 'forward' loop shortcut
    // no path between 3 and 1 will be found even though there is one.
    f.testPathCalculation(3, 1, 5, IntArrayList.from(3, 4, 2, 0, 2, 1));
}
Also used : EdgeIteratorState(com.graphhopper.util.EdgeIteratorState) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) ArgumentsSource(org.junit.jupiter.params.provider.ArgumentsSource)

Aggregations

EdgeIteratorState (com.graphhopper.util.EdgeIteratorState)137 Test (org.junit.jupiter.api.Test)55 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)25 Test (org.junit.Test)22 RepeatedTest (org.junit.jupiter.api.RepeatedTest)17 FlagEncoder (com.graphhopper.routing.util.FlagEncoder)13 Snap (com.graphhopper.storage.index.Snap)12 GraphHopperStorage (com.graphhopper.storage.GraphHopperStorage)11 CHEdgeIteratorState (com.graphhopper.util.CHEdgeIteratorState)11 QueryGraph (com.graphhopper.routing.querygraph.QueryGraph)10 FastestWeighting (com.graphhopper.routing.weighting.FastestWeighting)10 NodeAccess (com.graphhopper.storage.NodeAccess)10 GHIntHashSet (com.graphhopper.coll.GHIntHashSet)9 GraphBuilder (com.graphhopper.storage.GraphBuilder)8 QueryRoutingCHGraph (com.graphhopper.routing.querygraph.QueryRoutingCHGraph)7 DecimalEncodedValue (com.graphhopper.routing.ev.DecimalEncodedValue)6 EncodingManager (com.graphhopper.routing.util.EncodingManager)6 GHPoint (com.graphhopper.util.shapes.GHPoint)6 Fun (org.mapdb.Fun)6 IntArrayList (com.carrotsearch.hppc.IntArrayList)5