Skip to content

Conversation

@flother
Copy link
Contributor

@flother flother commented Apr 2, 2021

Let's say we have a tertiary road with the following tags:

  • maxspeed=60
  • surface=gravel
  • smoothness=horrible

The maxspeed tag tells us the legal speed limit, but the surface and smoothness tags have much more effect on the real-world speed of a car. In the default car profile, the gravel surface sets a driving speed of 40kph, and the horrible smoothness sets a driving speed of 10kph. It seems to me that the tags should be processed in this order:

  1. maxspeed
  2. surface
  3. smoothness

That is, maxspeed can be overridden by the surface tag, which can in turn be overridden by the smoothness tag. In the case of our secondary road, it would start with a driving speed of 60kph (from maxspeed), which would be reduced to 40kph (from surface), and end at 10kph (from smoothness).

However, before this change, the maxspeed tag is processed after surface and smoothness: our road starts with a driving speed of 40kph (from surface), it's reduced to 10kph (from smoothness), and then increased to 60kph (from maxspeed).

This change alters the processing order so that maxspeed is processed first, giving it the lowest priority of these three tags.

Let's say we have a tertiary road with the following tags:

- maxspeed=60
- surface=gravel
- smoothness=horrible

The maxspeed tag tells us the legal speed limit, but the surface and
smoothness tags have much more effect on the real-world speed of a car.
In the default car profile, the gravel surface sets a driving speed of
40kph, and the horrible smoothness sets a driving speed of 10kph. It
seems to me that the tags should be processed in this order:

1. maxspeed
2. surface
3. smoothness

That is, maxspeed can be overridden by the surface tag, which can in
turn be overridden by the smoothness tag. In the case of our secondary
road, it would start with a driving speed of 60kph (from maxspeed),
which would be reduced to 40kph (from surface), and end at 10kph (from
smoothness).

However, before this change, the maxspeed tag is processed *after*
surface and smoothness: our road starts with a driving speed of 40kph
(from surface), it's reduced to 10kph (from smoothness), and then
*increased* to 60kph (from maxspeed).

This change alters the processing order so that maxspeed is processed
first, giving it the lowest priority of these three tags.
@mjjbell
Copy link
Member

mjjbell commented Apr 14, 2021

It looks like there is historical precedent for maxspeed to override the speed assigned by highway type, which is why the tests are failing.

There aren't any tests that reference surface characteristics, so the ordering could be

    WayHandlers.speed,
    WayHandlers.maxspeed,
    WayHandlers.surface,

However, in principle I can see why maxspeed would always take precedence as its value is specific to the road, whereas surface speeds are estimates for all roads of that type.

Is the example you provided hypothetical, or do you see this issue occurring in OSM?

@systemed
Copy link
Member

Is the example you provided hypothetical, or do you see this issue occurring in OSM?

It's moderately common in some US states where bulk edits have been done to add a county-wide speed limit to all roads. First example I stumbled across: https://www.openstreetmap.org/way/14761419

@flother
Copy link
Contributor Author

flother commented Apr 19, 2021

Is the example you provided hypothetical, or do you see this issue occurring in OSM?

Similar to what @systemed said, in Iceland (where I use OSRM) the speed limit on rural gravel roads is 80kph (50mph) and many of the roads have the maxspeed=80 tag set in OSM. But, to take Hrafnseyrarvegur as an example, you wouldn't travel at 80kph if you value your paintwork or your suspension. Here's a photo from the road as an example of the road conditions there.

I came across this while I was looking into why OSRM was recommending a poorly-maintained gravel road (maxspeed=80) over a parallel well-maintained asphalt road (maxspeed=90). It turns out that the asphalt road has advisory speed limits of 50kph on a few sharp bends, and they too were tagged on OSM (as maxspeed=50, though maxspeed:advisory=50 would be more accurate). In this particular case taking the surface and smoothness into account would have been an improvement.

If there's a consensus on what should be done here (if anything) I'm willing to have a go at fixing the tests.

@mjjbell
Copy link
Member

mjjbell commented Apr 20, 2021

It's moderately common in some US states where bulk edits have been done to add a county-wide speed limit to all roads. First example I stumbled across: https://www.openstreetmap.org/way/14761419

in Iceland (where I use OSRM) the speed limit on rural gravel roads is 80kph (50mph) and many of the roads have the maxspeed=80 tag set in OSM. But, to take Hrafnseyrarvegur as an example, you wouldn't travel at 80kph if you value your paintwork or your suspension. Here's a photo from the road as an example of the road conditions there.

Thanks, sounds like relying on maxspeed is not the best option.

With regards to the tests, the use of maxspeed over highway speed seems to go back a long way and its use as a heuristic has changed over time (1, 2, 3), so it's not clear how much of original reasoning still applies in the face of non-specific bulk edits.

In which case, the ordering mentioned above seems like a good intermediate step. It will fix your issue without breaking the tests (and anyone who may currently rely on that behaviour).

Related: #5576

Let's say we have a tertiary road with the following tags:

   highway=tertiary
   maxspeed=60
   surface=gravel
   smoothness=intermediate

While the maxspeed tag tells us the legal speed limit, the surface and
smoothness tags have much more effect on the real-world speed of a car.
We should process the maxspeed tags first, and then update the road's
forwards/backwards speeds according to any surface and smoothness tags.
For our hypothetical road the process in the car.lua profile now goes
like this:

1. Get default speed from profile (tertiary = 40 on line 150 of car.lua)
2. Change speed to 60 using maxspeed tag (WayHandlers.maxspeed function
   in way_handlers.lua, lines 434-447)
3. Change speed to 40 using surface tag (WayHandlers.surface function
   in way_handlers.lua, lines 360-363)
4. Check speed according to smoothness tag --- but because it's higher
   than the speed according to the surface tag, leave the speed
   unchanged (WayHandlers.surface function again, lines 368-371)

<https://github.com/Project-OSRM/osrm-backend/blob/ec36319232f6b6558080c5586d21fc0bd150de44/profiles/car.lua#L150>
<https://github.com/Project-OSRM/osrm-backend/blob/ec36319232f6b6558080c5586d21fc0bd150de44/profiles/lib/way_handlers.lua#L354-L372>

Note in step 3 above the speed's only changed from 60kph to 40kph
because it's a lower value. If the surface speed was higher than than
the previous value, the speed would remain unchanged. Another example:

   highway=tertiary
   maxspeed=60
   surface=compacted
   smoothness=intermediate

Here, although the profile's speed for compacted is 80, it would stay at
the lower value of 60 (see way_handlers.lua, lines 360-363).

<https://github.com/Project-OSRM/osrm-backend/blob/ec36319232f6b6558080c5586d21fc0bd150de44/profiles/lib/way_handlers.lua#L360-L363>
@flother
Copy link
Contributor Author

flother commented Jun 1, 2021

Your suggested reordering makes much more sense: handle default profile speeds first, then maxspeed tags, and then surface/tracktype/smoothness tags. I've just updated the PR to use that order. Now, to use a hypothetical road with these tags:

  • highway=tertiary
  • maxspeed=60
  • surface=gravel
  • smoothness=intermediate

The speed would be processed like this:

  1. Get the default speed from the profile (tertiary = 40 on line 150 of car.lua)
  2. Change speed to 60 kph using maxspeed=60 tag (WayHandlers.maxspeed function in way_handlers.lua, lines 434–447)
  3. Change speed to 40 kph using surface=gravel tag (WayHandlers.surface function in way_handlers.lua, lines 360-363)
  4. Check speed according to smoothness=intermediate tag — but because it's higher (80 kph) than the speed according to the surface tag, leave the speed unchanged (WayHandlers.surface function again, lines 368-371)

I've left a bit more detail in the message for commit ab471c51.

Copy link
Member

@mjjbell mjjbell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks 👍

@mjjbell mjjbell merged commit f7478ba into Project-OSRM:master Jun 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants