edgeState.setWayGeometry issue


For a number of edges I have additional geometry points (all 3D);
I have updated the geometries for a number of edges, via edgeState.setWayGeometry(new_point_list) as below.

AllEdgesIterator allEdges = hopper.getBaseGraph().getAllEdges();
while (allEdges.next()) {
      int edge_id = allEdges.getEdge();
      EdgeIteratorState edgeState = hopper.getBaseGraph().getEdgeIteratorState(edge_id, Integer.MIN_VALUE);
      RoadClass road_class = edgeState.get(roadClassEnc);
      PointList geo = edgeState.fetchWayGeometry(FetchMode.ALL);
      PointList new_point_list = set_new_geometry(road_class, geo, 5);

hopper.getBaseGraph().flush(); // This successfully updates the geometry file.

// I then re-run the application to ensure graph reload, and then perform a route request, for a route that I know goes through the points I updated above.

ghRequest.putHint(Parameters.Routing.CALC_POINTS, true);
GHResponse ghResponse = hopper.route(ghRequest);
ResponsePath path = ghResponse.getBest();

PointList path_coordinates = path.getPoints();

The problem is that path.getPoints() only returns the original coordinates when the graph was first created with the OSM road geometries. The new point list doesn’t show.

Why is the routing path algo not returning the updated geometry?

You mean you update and flush the graph and this works, but after restarting the server you still see the old data?

Yes, flushed the graph, the geometry file goes from 2.5MB to 24MB (the new points have been saved) but I see only old coordinates returned in the path.getPoints().

But how is this even possible? When you overwrite the old coordinates in the file and restart the process (i.e. clear the memory) the old coordinates must be gone. So either you did not really restart the process and they are still in memory, or overwriting the coordinates file does not work somehow?


here’s an image which attempts to illustrate the difference between what path.calcPoints() returns and what edge_state.fetchWayGeometry(FetchMode.All) returns, for one edge (neither a start nor end edge in the path object).

  • orange curve is what path.calcPoints() returns.
  • blue one (my new points) comes from PointList pl = edge_state.fetchWayGeometry(FetchMode.ALL)

The Blue points do contain the 4 orange points (the two bookends, and the other two somewhat inside the curve). Again, path.calcPoints() only returns these 4 points.

Currently it is not a good idea to change the point list after it was initially set as the geometry storage is an append-only storage. And the old points will use storage but won’t be accessible after you flushed the storage.

The Blue points do contain the 4 orange points (the two bookends, and the other two somewhat inside the curve). Again, path.calcPoints() only returns these 4 points.

What you report looks more like the path simplification done on the server side. You can disable this via way_point_max_distance=false in the request. (if you want to disable this for OSM import you would use routing.way_point_max_distance in the config)

You could try actually deleting the geometry file, then change your point lists, then flush and then load it again. This way the old geometries certainly must be gone?!

Thank you both for the pointers. I have now tried your directions/suggestions.

  1. Set ghRequest.putHint(WAY_POINT_MAX_DISTANCE, false);
  2. Delete graphs folder, set config.putObject(Parameters.Routing.INIT_WAY_POINT_MAX_DISTANCE, false); in the GH init config before app run.
  3. Delete geometry file Files.deleteIfExists(Path.of("data/graphs/graphs-gh/geometry") prior to changing the point list so the list gets recreated at flush call.

No change, path.getPoints() still returns 4 points (base, adj and two inside) when fetchWayGeometry there are 20 coordinates inside the edge.

The issue appears to be with edgeState which can’t be cleared but only appended to. Route calcs ignore the appended points although edgeStateIterator carries them.

At the moment the only solution I can see is to create a entirely new graph copying the values of the old one and setting new geometries at edge creation.

The issue appears to be with edgeState which can’t be cleared but only appended to.

Ah yes, that is probably what @karussell was trying to say. Think of the geometry storage as one continuous piece of memory. Since there is a different number of geometry points for each edge it is not possible to simply set different points for an existing edge (in case they are more there would not be enough space at this location). So instead of just deleting the geometry file you would have to make sure to clear the geometry DataAccess also in memory, and then set the new points for all edges (in the right order), i.e. recreate the geometry storage from scratch. And then flush it.

But depending on what you are really trying to achieve this might be too complicated. The easiest way to change the geometry would be to set it the way you want during the initial import of course.

Thank you for the hints @easbar.
I get it now. At first, I thought @karussel meant that the geometry file was append only but not necessarily the edge state iterator,

I’ll take the "create a new graph’ route (no pun intended), the only concern I have is RAM requirements when creating the second and final baseGraph and CH shortcuts, while the original donor graph is still loaded in memory. If that fails then I’ll try creating a custom OSM file (!) meaning add new nodes and their references to ways.

Thank you @easbar and @karussell, I learned a few things :slight_smile:

This is strange. I remembered when I was hacking something else that this worked (except the file size increased).

btw: You could also patch GH and avoid feeding the initial geometry in OSMReader :slight_smile:

Thanks @karussell. Re patching up GH, I use the GH generated geometry to build a new one.

Then you could patch it directly in OSMReader before setWayGeometry :slight_smile:

ah, get it, brilliant! :slightly_smiling_face:

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