Different edge weighing depending on incline?


I can’t seem to find a way to create a custom routing profile that weighs edges depending on the incline (in the direction of travel). E.g. for the MTB profile I might be OK riding paths downhill (or level) but uphill (i.e. steeper than XY degrees) I might prefer track roads.

Is this possible at all?

Thanks for any feedback!

Unfortunately this is not implemented yet, but something we would really like to add. What kind of data do you think should be available for each edge? Many times the slope of an edge is not constant, i.e. a path crossing a hill between two junctions might go up and down again and it could even be that the overall elevation change is zero in this case. We can sample the elevation at some intermediate points so we get the elevation at multiple points along the path. But then the custom weighting also needs to take advantage of this data. For example we could make available the accumulated incline and decline instead of just the overall incline/decline. Or in an extreme case we could give access to the entire array of slopes and segment-lengths. Another question is how these calculations can be represented in a simple way/language so it is easy to make adjustments in the custom model language. In any case it would help a lot to know a couple of ideas/use-cases when implementing such an elevation-aware custom weighting, so your input will be highly appreciated.

1 Like

That’s interesting, I haven’t really thought about what “incline”, “uphill” or “downhill” actually mean.

The use case really is the mountain biking profile:

“As someone who loves riding single trails on an MTB I want the routing to weigh paths higher than other roads” -> that’s already doable :+1:

What I would like to add is:

“As someone who hates to push his bike I want routing to avoid paths that cannot be ridden on an MTB”

Clearly, some paths cannot be ridden on an MTB. Of course this depends somewhat on the personal skills but also on the difficulty of the trail (rocks, roots) and the incline. A trail with many rocks and roots may be ridable downhill but not uphill.

There is a PR that adds the difficulties: https://github.com/graphhopper/graphhopper/pull/1812

As a general rule I know for myself, that I can ride up to difficulty S3 downhill but uphill it shouldn’t be more than S1 or so.

So what’s missing is the “downhill”/“uphill” parts. Whatever that means :thinking:

I guess as a start something like this could work: if the end point is lower than the starting point it is downhill and vice versa. Or just a tag with the overall elevation gain (which could be negative)

1 Like

Yes being able to use the overall elevation gain/loss (and even in conjunction with the road type or surface) would certainly be a good first goal.

Maybe we can add the possibility to specify penalties for going up/down on certain road types per meter. In this case as authors of the custom weighting we would not have to think about overall vs segment-wise elevation changes.

1 Like

I think there are two problems here:

  1. we cannot express “if expression 1 AND expression 2 then set factor to X”
  2. there is no EncodedValue that stores the include/decline

Problem 2 is easy to solve via storing elevation per meter. Problem 1 is required to solve also for other use cases but I’m unsure how to do that. Should we throw away our YAML approach (as it is really limited) and go the harder way of a custom language or if we should try to find a rather limited solution within the YAML approach like instead of

   max_weight: { "<4.5": 0 }

doing it via

  "max_weight < 4.5": 0

Which would be then extendable via ANDs and ORs

   "max_weight < 4.5 AND elevation_incline < 0.1": 0

or even

   "max_weight < 4.5 AND some other expression": elevation_incline

Also the indention ugliness for YAML makes me nervous. (Of course we do not have this problem for the API endpoint as we use only JSON there but still)

Its difficult to answer the question whether we should stick with the current YAML approach or introduce something more powerful, but for the elevation stuff can we not do something like this?

  - road_class: {motorway: 0.1, tertiary: 0.7}
  - surface: {sand: 0.9}

So in the simplest case these would be distant-dependent costs, e.g. for every meter of elevation gain (per meter) a penalty is applied according to the factors specified in elevation_influence above. One thing I do not know yet is how we would be able to reduce costs when going downhill. We had a long discussion about this before (‘prefer’ for priority), but tbh right now I do not remember all the details.
Or should we apply the elevation influence (only) to the speed? This is a bit easier because there are always time-costs related to speed so going downhill can be modeled easily by increasing the speed (reducing the costs that are there anyway).

Anyway, I think my point is: With an elevation_influence section like (or similar to) the one above I do not (yet) see why the elevation support requires introducing a more complex modelling logic (using and/or etc.)

Where/why do you think this is ugly? The biggest advantage of YAML compared to JSON are comments imo.

Let’s us continue the discussion here: Custom Profile Spec Format

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