How to get EdgeIteratorState from EdgeID

Hello,

We are trying to use GraphHopper for our application to decide how far an electric car can go.
For this we need elevation, and surface value for each point.
Currently we are able to get elevation, but we can only get surface value for the first 2 points, then we get a NullPointerException.

Essenillay, I would like to know how to createan EdgeIterator that would actually contain all the edges, or to get to EdgeIteratorState when I only have
an EdgeID.

Thank you in advance for your help.

Bellow is the code we are using:

   String osmFile = "C:\\OSM-Graphs\\colorado-latest.osm.pbf";
    String graphFolder =  "C:\\OSMGraphs\\Colorado7";
    String elevationCache = "A:\\tmp\\cgiar\\srtm_15_05";
    boolean includeElevation = true;
    ElevationProvider elevationProvider = new CGIARProvider(elevationCache);
    elevationProvider.setCalcMean(true);
    PathDetailsBuilderFactory detailsFactory = new PathDetailsBuilderFactory();
    GraphHopper hopper = new GraphHopperOSM();
    hopper.setDataReaderFile(osmFile);
    hopper.setGraphHopperLocation(graphFolder);
    hopper.setMinNetworkSize(200, 200);
    hopper.setElevationProvider(elevationProvider);
    hopper.setElevation(includeElevation);
    hopper.setPathDetailsBuilderFactory(detailsFactory);
    
    CarFlagEncoder flagEncoder = new CarFlagEncoder();
    OSMRoadClassLinkParser tagParser = new OSMRoadClassLinkParser();
    OSMSurfaceParser surfaceParser = new OSMSurfaceParser();
    OSMMaxSpeedParser speedParser = new OSMMaxSpeedParser();

    EncodingManager em = new EncodingManager.Builder().add(flagEncoder).add(tagParser).add(surfaceParser).add(speedParser).build();
    hopper.setEncodingManager(em);
    hopper.importOrLoad();

    int res = 300;
    LocationIndex index = new LocationIndexTree(hopper.getGraphHopperStorage().getBaseGraph(), new RAMDirectory(graphFolder, true));
    index.setResolution(res);
    ((LocationIndexTree) index).setMaxRegionSearch(50);
    index.setApproximation(false);
    
    if (!index.loadExisting()) 
        index.prepareIndex();
    
    double latFrom  = 40.189, lonFrom = -105.279, latTo = 40.016, lonTo = -105.279;
   
    GHRequest req = new GHRequest();
    req.addPoint(new GHPoint(latFrom, lonFrom));
    req.addPoint(new GHPoint(latTo, lonTo));
    
    req.setWeighting("fastest");
    req.setVehicle("car");
    req.setLocale(Locale.US);
    req.setAlgorithm(Parameters.Algorithms.ALT_ROUTE);
    req.setPathDetails(Arrays.asList(Parameters.Details.AVERAGE_SPEED, Parameters.Details.EDGE_ID));
    req.getHints().put(Parameters.Algorithms.AltRoute.MAX_PATHS, "16");
    req.getHints().put(Parameters.Details.PATH_DETAILS, "40");
    
    QueryResult qr = index.findClosest(latFrom, lonFrom, EdgeFilter.ALL_EDGES );
    int closestNode = qr.getClosestNode();
    
    EncodedValue ev = hopper.getEncodingManager().getEnumEncodedValue(RoadClass.KEY, RoadClass.class);
    EncodedValue ev2 = hopper.getEncodingManager().getEnumEncodedValue(Surface.KEY, Surface.class);

    EdgeIteratorState edgeState = qr.getClosestEdge();             
    
    String edgeName = edgeState.getName();
    String roadValue = edgeState.get((EnumEncodedValue<RoadClass>) ev).toString();
    int roadVlaueInt = edgeState.get((EnumEncodedValue<RoadClass>) ev).ordinal();
    String surfaceValue = edgeState.get((EnumEncodedValue<Surface>) ev2).toString();
    int surfaceValueInt = edgeState.get((EnumEncodedValue<Surface>) ev2).ordinal();

    //  now you can fetch the closest edge via:
    GHResponse rsp = hopper.route(req);
    GraphHopperStorage storage = hopper.getGraphHopperStorage(); 

    PathWrapper path = rsp.getBest();

    EdgeExplorer explorer = storage.createEdgeExplorer();
    EdgeIterator itr = explorer.setBaseNode(closestNode);
    Map<String, List<PathDetail>> details = path.getPathDetails();
    List<PathDetail>  edges = details.get(Parameters.Details.EDGE_ID);       
    for(PathDetail p: edges){  
        itr.next();
        int edgeID =(Integer) p.getValue();           
        int nodeID = itr.getAdjNode();
        EdgeIteratorState edge = storage.getEdgeIteratorState(edgeID, nodeID);
    // The second edge value is null
        String surfaceStr = edge.get((EnumEncodedValue<Surface>) ev2).toString();
        System.out.println(" surface value = " + surfaceStr);
    }
graph.getAllEdges()

and

// take the edges/nodes from the `Path` directly (no need for path details)
graph.getEdgeIteratorState(edgeId, adjNode);

Thank you for the response.
The problem here is that I only have the info for one adjacent node, while I have 412 edgesIDs.
AllEdgesIterator aei = storage.getAllEdges();
int nodeID = aei…getAdjNode(); returns zero, and subsequently I cannot get the EdgeIteratorState.
Currently I only have the info on one adjacent node, that is why I was trying
EdgeExplorer explorer = storage.createEdgeExplorer();
EdgeIterator itr = explorer.setBaseNode(closestNode);
but the iterator returns only one node. What kind of setting I should use so that I have access to all the nodes that were used to create the path?

Oh you need to call next() on the edge iterator, before this its not even in a sane state. With every call to next() you get the next edge and this way you can traverse all edges.

Getting all edges:

AllEdgesIterator allEdges = graph.getAllEdges();
while (allEdges.next()) {
    int adjNode = allEdges.getAdjNode();
    int baseNode = allEdges.getBaseNode();
    int edgeId = allEdges.getEdge();
}

Getting all edges adjacent to a certain node:

EdgeExplorer exp = graph.getEdgeExplorer();
EdgeIterator iter = exp.setBaseNode(yourNode);
while (iter.next()) {
    int adjNode = iter.getAdjNode();
    int baseNode = iter.getBaseNode();
    int edgeId = iter.getEdge();
}

Using the Path from the route calculation you can also get all the nodes or edge iterator states on this path: path.calcNodes() and path.calcEdges(). Take a look at the code it should be easy to see.

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.