Buses: avoid u-turns

Hi there,
I’m trying to find the most likely route between 2 bus stops, but sometimes the stops coordinates are off the road and it goes some extra miles, sometimes leading to u-turns which of course are not recommended for buses.

I tried to disable u-turn by following the documentation, with no success:

val request: GHRequest = GHRequest(shape.lat, shape.lng, nextShape.lat, nextShape.lng)
.putHint(Parameters.CH.DISABLE, true)
.putHint(Parameters.Routing.PASS_THROUGH, false)
.putHint(Parameters.Routing.HEADING_PENALTY, 300)

Here is an exemple of what I want to avoid:

Waypoint 1 is a little bit off the road and GH tries to be as close as possible, but leading to a u-turn.

This is what I would like (I faked the Waypoint position for the example):

I think my issue is the same as Forbidding U-Turns - possible? but I can’t seem to get it to work for me.

What am I missing? What configuration could I use for my purpose?

If you want to prevent u-turns at via-waypoints (like the blue marker in your example) you need to set pass_through to true not false. This way it will become much less likely that there will be a u-turn at a via-waypoint. However in your example it looks like the blue marker is at the end of a dead end street so there is no other way than doing a u-turn. The pass_through option only changes the direction from which the route arrives at or leaves the waypoint, but the snapped coordinate will be the same.

To fix your example you want the blue marker to snap to the other road. You have two options to do this (apart from moving it closer to the road you want):

  1. You can use the point_hint parameter to make it more likely to snap to Rue des Papillons
  2. you can try to use snap_prevention (or SnapPreventionFilter really) to exclude certain types of roads (like tertiary) from snapping.

Here is your query including point_hints for Rue des Papillons


Thank you for your suggestions.
I can’t really avoid tertiary roads: buses don’t always take primary or secondary roads.
And I’m afraid I won’t be able to know the names of the streets, I only have a list of coordinates.

Could it be possible to tune the snap precision of points?

What do you think can be tuned? If you coordinates are closer to the ‘wrong’ road than the one you are hoping to find, how is GraphHopper supposed to know which one you want. Maybe have a look at LocationIndexTree#findNClosest. With this you can get multiple matches (and then somehow choose the one you are looking for).

Or maybe even try using map-matching. Map-matching already does this: It considers multiple snaps and finds a reasonable route.

Although not an answer to your problem. I just wanted to let share the “data cleanse solution” that I implemented for all of my address data to avoid the problem you are encountering.

With all of my address data points I had road segment associations in an oracle SQL database. This allowed me to “Snap to roadside” in SQL. Is there any chance you can improve your dataset?

Green points are original address locations and black points are snapped to 10m from roadside.

I was thinking of something similar, the coordinates of bus stops are sometimes more accurate in the OpenStreetMap data than in my data, but it is not entirely reliable.

I was thinking of something to tell “it’s okay to be far from a point if it avoids u-turn”.

When I try the same coordinates in Google Map, I have:

Can we get something similar with GraphHopper?

GraphHopper routing determines the snapped point before calculating any routes. So by the time it becomes apparent that there will be a u-turn it is ‘too late’ as the snapped point is already fixed.

However, GraphHopper map-matching does what you are describing: It first determines a set of multiple snapped coordinates. Then it calculates all possible routes and chooses the final route such that u-turns are avoided.

Btw the roads on the google maps screenshot look a bit different (and if I move the coordinate a bit further north it also snaps to the parking lot (and suggests a u-turn))

Btw there have been discussions about including this functionality into GraphHopper’s routing functionality and this will probably be done at some point.

Ok thank you, I’ll try with map-matching :+1:

Powered by Discourse