OpenStreetMap

Inferring Default Speed Limits

Posted by westnordost on 20 June 2022 in English.

I would like to tell you about another small project I will be working on for the next months. It is made possible by a NLNet NGI Zero Discovery grant:

Missing maxspeed

Inferring default speed limits for situations where concrete maxspeed information is missing. Last time I checked, only 12% of roads had this tagged at all and while the number of roads tagged with maxspeed of course is increasing, so is the number of roads.

Compared with highway=unclassified, it looks pretty much like a zero sum game. This means, that not only did OSM based router software always have to fill huge holes in data to produce reasonably precise ETAs (etc.), it is also not something that will get any better on a global scale in the foreseeable future.

Why so sketchy?

It’s also understandable why the data is so sketchy: Roads can simply be traced from satellite imagery. Finding speed limit signs on the other hand often requires to look for them on-site or via good Mapillary / KartaView coverage which is in itself already much more time-intensive. Not only that - it’s even more time-intensive to confirm that there is no signed speed limit for a given segment of road as the speed limit sign could be located all the way down the road. (One reason why the speed-limits quest is disabled in StreetComplete.)

Finally, if it turns out there is no sign, tagging the correct maxspeed requires knowing the traffic legislation in the country one is mapping in. (And sometimes one errs in what one thinks is correct. Did you know that the default no-speed-limits in Germany are technically are not limited to the Autobahn?)

Goal

So, the goal is to get the OSM based routing engines to use this data in order to improve the routing precision (by filling the holes in the data), but also for other modes of transportation than just cars. (Nobody maps maxspeed:hgv unless there is a sign.) Since I am not the maintainer of either of those, at least the goal is to lower the (implementation effort) bar for them a lot. We’ll see.

What I will be working on specifically in the frame of the NLNet grant is to

  • review and try to complete this wiki page that (shall) contain all the legislative data regarding default speed limits I started years ago

  • complete and debug this parser that was started by Ian Wagner from StadiaMaps for that wiki page that outputs an easy to parse JSON

  • write a reference implementation that, given a set of tags and a country, determine the default max speeds (for the different vehicle types) using the data from that JSON. I’ll probably write

  • write a small simple web tool on which to try it out

Since the reference implementation would be used by that web-based tool, I’ll probably write the reference implementation in Kotlin Multiplatform because it can be transpiled to JavaScript (for the web-tool), JVM (maybe useful for GraphHopper) and native (maybe useful for Valhalla).

State of the Map

Finally, I will also hold a talk at the State of the Map 2022 in Florence about this. I hope I have something to show until then 😅 🤞

Discussion

Comment from thomersch on 21 June 2022 at 11:49

That’s interesting. A while ago I built some software for a customer that needed speed limit data, and maxspeed coverage is indeed limited, even if we just consider motorways and trunk roads. I was thinking about parsing tags, but I didn’t have a convincing idea how to analyse those. After all, a highway=primary can be either an urban road or an intercity road. Do you have an idea how to differentiate those?

Using Mapillary data seems promising to me, I even built a MapRoulette challenge which matches roads without speed limit info with detected speed signs, but mapping those is even more time consuming than I thought, so there was basically no mapper interest in those. A more automated solution has to be possible: Even my car has one of those computer vision systems which detects speed limits with staggering accuracy.

Comment from eternaltyro on 21 June 2022 at 12:42

Interesting and I hope to catch up with you in Florence. Out of curiosity, can’t we just add default maxspeed limits based on the type of roads? I am assuming different countries have standardized speed limits based on types of vehicles and roads.

Here is some dubious information about speed limits in India: https://en.wikipedia.org/wiki/Speed_limits_in_India (lacking citation for several claims though :( )

The claims in the Wiki-page don’t seem too far off what I’ve observed living there:

In April 2018, the Union Ministry of Road Transport and Highways fixed the maximum speed limit on expressways at 120 km/h, for national highways at 100 km/h, and for urban roads at 70 km/h for M1 category of vehicles. The M1 category includes most passenger vehicles that have less than 8 seats.

Does this mean we can programmatically fill in default maxspeed for roads based on type of road wherever the tag is absent?

Comment from westnordost on 21 June 2022 at 14:53

After all, a highway=primary can be either an urban road or an intercity road. Do you have an idea how to differentiate those?

That depends on the legislation. Some legislation define default speed limits based on the number of lanes a road has. Other legislation has different default speed limits based on whether the road has a dual carriageway or not (= a barrier that divides the traffic going into different directions). These things are potentially tagged. Communities in some countries also aligned the definitions of certain classifications of roads (for which different maxspeeds apply by default) with the definitions used in legislation. So for these countries, it may actually be possible to infer with certainty from e.g. highway=primary to a certain default speed limit.

But anyway, absolutely agree on that the information that is missing most of the times to properly infer the default speed limit is whether a road is within a built-up area or not. A tag like urban=yes/no does not exist. Router software maintainers struggle with this too.

A more automated solution has to be possible: Even my car has one of those computer vision systems which detects speed limits with staggering accuracy.

This is what Mapillary is doing, right? This data still needs to be (manually) processed and inserted into OSM though. It’s still a lot of work.

Actually, I think the best approach to properly get to current (non legislative but) de-facto speed limits is to not look at OSM data but have a fleet of cars constantly on the roads and sourcing the data for the current traffic situation for that. E.g. like Google does it (with data sourced by users of Google Maps). But whoever else may be collecting this kind of data (big taxi companies?, navigation system manufacturers?) , it is proprietary data and there is no good reason for them to give that away for free other than maybe to combine forces against a common market leader (Google).

So, bottomline, finding and properly mapping the legislative default speed limits to OSM tags is a improvement of the situation in any case.

Does this mean we can programmatically fill in default maxspeed for roads based on type of road wherever the tag is absent?

Yes, the goal is that data consumers can fill in default maxspeeds for roads where that information is missing in OSM. I.e. it should not be used to copy&paste maxspeed automatically everywhere, of course.

Comment from Piskvor on 22 June 2022 at 12:24

“whether a road is within a built-up area or not”

That’s the major issue around here (CZ): “source:maxspeed” alleviates this somewhat, but that’s even less frequent than maxspeed itself. OTOH, when this is determined, using the defaults is useful - maxspeed with source:maxspeed=sign/zone shows local variations.

Comment from westnordost on 22 June 2022 at 13:17

You mention one workaround to find if a road is urban or not with source:maxspeed, in fact, I think this (Overpass Wizard syntax-like) filter would yield the best result:

source:maxspeed~urban or maxspeed:type~urban or zone:maxspeed~urban or zone:traffic~urban or maxspeed~urban

But of course, this is only set accordingly if there is no maxspeed sign, which is an issue because

  • there are other traffic rules that apply depending on whether a road is within a built-up area or not, e.g. regarding parking
  • there are even other maxspeed related rules that apply only in a built-up area, e.g. the maxspeed of other vehicle types

But it is still an ok workaround. Additionally, if a fuzzy match is okay, one could look at highway~^service|living_street|residential$ or lit=yes or sidewalk~^yes|both|left|right$ or ~^sidewalk:(left|right|both)$=yes because e.g. roads in built-up areas usually have street lighting and sidewalks.

Comment from pnorman on 22 June 2022 at 22:34

Actually, I think the best approach to properly get to current (non legislative but) de-facto speed limits is to not look at OSM data but have a fleet of cars constantly on the roads and sourcing the data for the current traffic situation for that. E.g. like Google does it (with data sourced by users of Google Maps). But whoever else may be collecting this kind of data (big taxi companies?, navigation system manufacturers?) , it is proprietary data and there is no good reason for them to give that away for free other than maybe to combine forces against a common market leader (Google).

You need this information for good routing anyways, which is the main use-case for speed limit data. Typically you want to develop routing cost functions based on actual speed, not max speed.

Comment from westnordost on 3 August 2022 at 17:11

I have now finished implementing the python script that parses the default speed limits wiki page: https://github.com/westnordost/osm-legal-default-speeds-parser

and also finished implementing a reference implementation / library in Kotlin multiplatform: https://github.com/westnordost/osm-legal-default-speeds

Comment from westnordost on 9 August 2022 at 14:41

I put the parser into the same repo as osm-legal-default-speeds now (in directory /parser), so everything is in one place. The source code for the demo is also in that repo (directory /demo)

https://westnordost.github.io/osm-legal-default-speeds/

Comment from westnordost on 28 September 2022 at 21:38

I’ve noticed that the talks from the SotM 2022 are online:

https://media.ccc.de/v/sotm2022-18524-inferring-default-speed-limits

Log in to leave a comment