Hi graphhopper developers,
first of all many thanks for your work, you made a great product!
I’m struggling now with some issues in routing behavior at borders of area specified in some osm.pbf file. For example in belgium-latest set (https://download.geofabrik.de/europe/belgium-latest.osm.pbf). If I use current master version of engine and calculate a route, that starts/ends near the border some segments of highways will be completely ignored. Example:
profile - car, config - standard
With version 7 I get similar results.
But if I put some buffer to dataset and use custom osm file like Belgium + 100km buffer - all highways will be routed fine. Unfortunately this workaround is not the option for the current project I’m working on, because of additional resources.
I’m wondering if it’s some problem with osm data or in graphhopper logic, because all these segments are present in sets, but are ignored during routing.
Appreciate your support and have a great day!
I fear that the Geofabrik extract removes the motorway segment crossing the border. GraphHopper will fallback to the nearest road which happens to be the small track next to the motorway.
How did you verify this?
Thanks for your reply! I check it in QGIS and PostgreSQL
Can you enable ‘Show Routing Graph’ in the web UIs layer menu to verify the motorway is not included?
I just tried this and the motorway is included in the graph but it is recognized as a (one-way) subnetwork and thus excluded when the start position is ‘snapped’ onto the routing graph. We use the subnetwork search to make sure we only snap to points of the routing graph that are connected to the rest of the network. For example imagine a little ‘island’ of roads that are (for whatever reason) not connected to the nearby road network. Snapping the start or destination points to such an island would never yield a route so they are excluded. In the present case snapping the starting position to the motorway seems reasonable, because we surely can start a route there. However, since driving is only permitted in one direction using the same point as destination wouldn’t work (with the very exception that the start point would also be on the motorway a bit closer to the border of the map). For this reason the motorway’s
car_subnetwork encoded value is true which is why GH does not snap onto the motorway.
Sure, here is a screenshot:
Hi easbar, thanks for your reply!
I’m trying to understand your detailed answer now, but it’s a bit hard. Can you please tell me if there is in the end a solution or workaround instead of adding the buffer? Because for me it’s not very logical, that I cannot use motorway to leave the parking lot to move on.
Generally GraphHopper only snaps to points that are connected in both directions. Starting a journey at the green marker would be reasonable, but because of the map border it isn’t possible to reach it from your target position. This prevents different kinds of other possible problems, but here you ran into a case where this strategy fails in a way.
A pragmatic solution could be ignoring the
car_subnetwork attribute for motorways. For this you would have to modify the code in
Router.java where you need to add this special handling for motorways in createEdgeFilter and (if you are using heading and/or curbsides) also in createDirectedEdgeFilter. You could also ignore
car_subnetwork entirely, but then you might run into other problematic cases that are normally avoided by this mechanism. This is possible even without modifying the code, you would just have to set
prepare.min_network_size: 0 in the config file and run a new import.
Maybe another solution would be ‘shrinking’ your map, i.e. use belgium-latest.osm.pbf as it is, but generally deny routes that start/stop near the borders of the map. This way the routeable area would be smaller of course, but at least you do not risk returning strange routes like the one in your example.
If you want to dig deeper it should be possible to identify parts of the road network that are connected to the main network only in one direction. With this in place you could allow snapping to such roads only in one direction.
thanks a lot, I’ll try it. At least now I understand where is the problem:)
Hi, I’m back with the problem:) I’ve implemented the solution with ignoring the
car_subnetwork attribute for motorways in EdgeFilter, but noticed that it allows snapping to oneway
motorways, that are cut with the border, so leading nowhere. Also
service road class is affected. I would try your further suggestion with prevention of snapping in “wrong” direction, but not sure what the best place for that. Maybe
SnapPreventionEdgeFilter ? But how do we know the direction of travel during snapping?
Thanks in advance!
But how do we know the direction of travel during snapping?
We don’t (unless a heading parameter is used or something). Just by looking at an edge (like in the filter you mentioned) you won’ be able to tell if snapping to it will lead to nowhere (resulting in a connection-not-found error). To do this you would have to traverse the graph, or do some preprocessing to identify these problematic edges beforehand. Since this all might be non-trivial, can you not just create a bigger map extract (larger than the area you want to be looking at) and deny queries close to the (extended) border?
I’m using some custom data, so there are a lot of pre-processing steps with osm. Usage of bigger dataset can provide some issues with storage and serving. But if it’s the only way to solve the problem, I’ll discuss it with data provider. Thanks for help!
It’s certainly not the only way to solve the problem, but possibly the easiest. An algorithmic way to solve it could be starting a graph traversal from every edge with
subnetwork=true to check if the search finds edges with
subnetwork=false. If yes, mark these edges as possible start locations, if not do nothing. Then repeat the same with backward searches to mark edges that are possible target locations. In your edge filter during snapping you would then only allow edges with either
subnetwork=false, or those with
subnetwork=true that are marked as start/target locations.
Sounds promising! I’ll try to implement it tomorrow