Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

I'm building a monitor that will calculate the average travel time from 115000 points in the Netherlands to their nearest amenity of certain types, eg primary school, supermarket etc to get an idea of the relative remoteness of places. (pretty much an updated version of my earlier work 10 years ago https://github.com/WorldBank-Transport/ram-backend/blob/v0.1.0/README.md )

However this time I'd like to use the average car and bike speeds for road segments, instead of the posted max speed, or inferred speed based on the type of road. I have this information for (nearly) all roads both for rush hour and free flow. I am wondering what the best approach would be to embed this information into the OSRM network.

Looking at the car profile and the extract workflow it seems to me it should be done either at the OSM source file (eg setting a new tag on each segment with the average speed) and update the car.lua file to accept the new tag as preferred speed or with a separate lookup file that gives the speeds for segment IDs. I remember that back in the day this approach was investigated, but I do not see any mention of it so it might have come to nothing.

It is very much not a realtime speed routing solution I'm looking for. The calculations will be done once a year or maybe once a month so extensive preprocessing is not a big issue, though quicker is better of course. Having two separate models for rush hour and freeflow traveltimes is neither an issue (knowing that OSRM doesn't understand time based speeds)

You must be logged in to vote

Replies: 1 comment

Comment options

Got it, here’s the reply draft to that message, without em dashes:

Great framing on the free flow / slowdown factor decomposition. That’s actually the cleanest way to think about it conceptually, and it maps well onto how you’d implement this technically.

The two approaches you identified are both viable, but they differ significantly in pipeline fit.

Option A: Tag the OSM source, update the Lua profile
You add a custom tag (e.g. avg_speed:car:freeflow=52) to each way and modify car.lua to prefer it over the normal speed logic. This works with both the CH and MLD pipelines, is straightforward to reason about, and keeps everything self-contained in the extract step. The downside is that conflating your speed dataset onto OSM ways is where most of the pain lives. Matching your road segments to OSM way IDs, handling directionality, splits, etc. gets messy fast. OSM ways get split at every intersection during extract, so a single way ID in your speed data may correspond to multiple internal edges.

Option B: Segment speed CSV via osrm-customize
This is the approach that was actually built and it’s part of the MLD pipeline. After osrm-extract and osrm-partition, osrm-customize can accept a CSV of from_node_id,to_node_id,speed pairs that override the extracted speeds for individual directed edges. This is OSRM’s intended traffic integration point. The catch: you need OSM node IDs as your join key, not way IDs, which makes the conflation problem slightly different but not simpler.

For a once-a-year or once-a-month batch run, Option B with MLD is probably the right architecture. You extract and partition once, then re-run osrm-customize with each speed vintage (freeflow, AM peak, PM peak) in minutes rather than re-extracting the whole graph.

On the free flow framing specifically
This is worth leaning into. If you build your freeflow model as the baseline, essentially “what’s the travel time if the road network behaves as designed, at legal speeds, with no congestion?”, you get a clean policy-relevant metric: structural access, independent of traffic. Your rush-hour model then gives you the traffic penalty as a ratio per OD pair. That ratio is interpretable, transferable across years (road networks change slowly, traffic patterns less so), and lets you separate infrastructure adequacy from congestion as distinct policy levers.
The conflation step is unavoidable either way. The central question is what identifier your speed dataset uses. If it’s road segment IDs from a national dataset (NDW? WEGGEG?), you’ll need a geometric or attribute-based match to OSM. If you already have speeds keyed to OSM node pairs, Option B is essentially plug-and-play.

What does your speed data look like structurally, and what’s the primary join key?​​​​​​​​​​​​​​​​

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
🙏
Q&A
Labels
None yet
2 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.