Is it possible to consider turn as penalty?

Good day!

I was using GraphHopper 0.6 for long time and it always performances good !

Recently I feed our traffic data so that every road has its own speed. Then I find the results always prefer some small roads instead of one main road, just to save several seconds (I was using FASTEST weighting). So I’m trying to find a way to avoid such routing.

I find TurnCost (and maxTurnCost) feature but from what I understand, it can only add restriction on specific turn, say, one turn is totally forbidden if turnCost > maxTurnCost.

So my questions are:

  1. Am I correct with the understanding on TurnCost above?
  2. Is there any way to avoid too many turns, or add penalty for every turn, so that the algorithm will not prefer things like “drive into small streets then go back to main road again”?

Per default it is blocking vs. allowing (just one bit) but you can tune it to e.g. avoid left turns without blocking them completely e.g. increase to two bits

Is there any way to avoid too many turns, or add penalty for every turn, so that the algorithm will not prefer things like “drive into small streets then go back to main road again”?

If you let the graph know what a ‘turn’ is then this is already possible, yes. To decide if it is a left or right turn you might be interested in recent work on turn instructions: Improve instructions by boldtrn · Pull Request #955 · graphhopper/graphhopper · GitHub

Hi karussell,

Thanks for your reply!

After reading the code, is this the right way to add turn costs ?

  1. Get TurnCostExtension from graph
  2. Use addTurnInfo() in TurnCostExtension class

Yes, and the ‘turn flags’ for turn costs can be retrieved via: “turnCostFlagEncoder.getTurnFlags(false, 2);”

These should be helpful enough. Thanks!

Hello,
In graphhopper 0.12 I would like to create a (default) penalty foreach left-turn in the CH mode for the region Europe.
I enabled the parameters :
prepare.ch.edge_based: edge_or_node
and
graph.flag_encoders: car|turn_costs=true
so I could start to try to understand where I need to implement this… but I can’t.

  1. Can someone show me the way ?
  2. Do I need to store this information (and how to retrieve it in the processing) or can I calculate it on the fly ?
    thanks !
  3. could I use edge_or_node or edge_and_node

This is certainly an interesting feature, but might be not so easy to realize.

I enabled the parameters …

This is how you enable turn cost support for speed mode. By default the OSM import will set turn restrictions (forbidden) turns that are in OSM. You can either add turn costs/restrictions on each junction using the turn cost extension (easier to do, but takes more memory), or take a look at how TurnWeighting applies u-turn costs, and do something similar for left turns. For CH see also this PR: Allows setting finite u-turn costs. by easbar · Pull Request #1672 · graphhopper/graphhopper · GitHub. In any case you need to increase the 'maxTurnCost` parameter on the encoder to allow turn costs (not just restrictions).

  • could I use edge_or_node or edge_and_node

This is rather unrelated here. edge_or_node just means that since you specified |turn_costs=true you will get edge-based (turn cost supporting) CH and edge_and_node would give you edge- and node-based CH preparations (so you can choose per request).

1 Like

Thanks for your reply.
I will look into the PR.