Edge ID not constant

Hi,

From the locationIndex, I can find the closest edge and I store its ID with some additional information and I set a flag to tell that this edge had additional information on the side.
Then, this information is given to my routing algorithm.

However, the ID of the edge is different from the locationIndex and from inside the routing algorithm.

Is there a way to retrieve it?

Should I store a fakeID in the edge?

Thanks

Can you describe your use case?

If you do a lookup in the QueryGraph virtual edges and nodes are created - do you mean this?

I have custom constraints that I want to apply on the graph.

However, some of them are quite complex (time based) and don’t fit in the flags of the edge.

Therefore my idea was to create a map<edgeID,restriction> and enrich the graph edge with a flag “additional restriction present”.

Then in the routing algorithm, I check that flag. If there is an additional info, I go to have a look into my map. But I can’t find my edge back because its ID is changed between the addition of the constrains.

So to resume, the enriching phase is done on the graphhopper instantiation (I have extend it, but you get it) and the lookup is done in an extended version of AStar.

I hope that this clarifies it a bit. Feel free to ask additional information if needed.

Regards

The edge IDs do not change, the only possibility is that the edge IDs you are referring to are the virtual edges created for the QueryGraph: at the query location a new ‘temporary’ node with all the associated edges are created and uses different edge and node IDs.

There is currently no official way to get the ‘original/underlying’ edgeId, but there is an official workaround :wink:

if (edgeState instanceof VirtualEdgeIteratorState) {
   VirtualEdgeIteratorState vEdge = (VirtualEdgeIteratorState) edgeState;
   // the traversal key has also the information of the orientation but we just want the edgeId:
   int edgeId = vEdge.getOriginalTraversalKey() / 2;
}
1 Like

I was working with VirtualEdgeIterator so I had to adapt it a bit

if (iter instanceof VirtualEdgeIterator) {
    EdgeIteratorState edge = iter.detach(false);
    if ( edge instanceof VirtualEdgeIteratorState) {
        VirtualEdgeIteratorState vEdge = (VirtualEdgeIteratorState) edge;
        // the traversal key has also the information of the orientation but we just want the edgeId:
        edgeId = vEdge.getOriginalTraversalKey() / 2;
    }
}

In all cases I got it work, Thank you very much :slightly_smiling:

Why did you need the detach?

To get the current edge of the VirtualEdgeIterator.

Is there a better way to do it ?

If I try to do that,

I get the following

java.lang.ClassCastException: com.graphhopper.routing.VirtualEdgeIterator cannot be cast to com.graphhopper.routing.VirtualEdgeIteratorState

if (iter instanceof VirtualEdgeIterator) {
    VirtualEdgeIteratorState vEdge = (VirtualEdgeIteratorState) iter;
    // the traversal key has also the information of the orientation but we just want the edgeId:
    edgeId = vEdge.getOriginalTraversalKey() / 2;
}

If I try to test the instance as instanceof VirtualEdgeIteratorSlate, I just return false all the time.

The detach should not be necessary and a direct cast to the VirtualEdgeIteratorState should be successful, if its a VirtualEdgeIterator.

if edgeIter.next() == true the iter goes in the next valid state and with detach you can then store this state somewhere without being influenced from a potentially next call of the iterator. Normally detaching creates a new object, but this is not the case for VirtualEdgeIterators and so it should not matter performance-wise

Can a VirtualEdgeIterator can contains anything else than a VirtualEdgeIteratorState ?

When I do the test, I see that the detach sometimes return a com.graphhopper.storage.BaseGraph.EdgeIterable
which cannot be casted into the virtual one.

I don’t know if that helps

com.graphhopper.storage.BaseGraph.EdgeIterable which cannot be casted into the virtual one.

Yes, this happens if the query is very close to a junction and does not need to create virtual edges or nodes

java.lang.ClassCastException: com.graphhopper.routing.VirtualEdgeIterator cannot be cast to com.graphhopper.routing.VirtualEdgeIteratorState

Oh, indeed. Sorry, for the confusion. The VirtualEdgeIterator implements ony EdgeIteratorState and not VirtualEdgeIteratorState and so you need to ‘fetch’ these objects via the detach … so all in all very low level and the code you proposed is good to go, also performance should be okay when using detach for the virt edges only.

Still please try if you can avoid the second if and do:
VirtualEdgeIteratorState edge = (VirtualEdgeIteratorState) virtEdgeIter.detach(false);

That breaks as the detach return BaseGraph.EdgeIterable which then generate an exception in the attempt of casting.

But indeed, performance are still ok when using the detach.

Sorry, I meant:

if(iter instanceof VirtualEdgeIterator) {
    VirtualEdgeIteratorState vEdge = (VirtualEdgeIteratorState) iter.detach(false);
    edgeId = vEdge.getOriginalTraversalKey() / 2;
}

This cannot work because the assignation raise an error:

VirtualEdgeIteratorState vEdge = (VirtualEdgeIteratorState) iter.detach(false);

  1. The edge is detached and return a BaseGraph.EdgeIterable
  2. The BaseGraph.EdgeIterable tries to be casted and generate the exception

I am not sure that there is a way around the double if :frowning:

1 Like

Oh, you are right. It can be the case that the virt edge iterator contains normal edge states, when no new edges are created (as I said earlier). We need a more beautiful way to do this :slight_smile:

Yeah, thanks. That’s what I needed! :smiley: