osrm-backend icon indicating copy to clipboard operation
osrm-backend copied to clipboard

Determine speed limit for route

Open parsispresswala opened this issue 6 years ago • 13 comments

Hello guys,

I'm trying to find a way to obtain all the speed limits in km/h unit for a specific route using openstreetmap. Right now I am using annotation=speed but I don't understand the result. My API of routing is something like this: http://127.0.0.1:5000/route/v1/driving/72.860856,19.198877;72.860084,19.195128?steps=true&alternatives=false&geometries=geojson&annotations=speed

weight: 102, distance: 1278.3, annotation: { speed: [ 14.3, 14.4, 14.4, 14.3, 14.4, 14.1, 14.6, 14.5, 11.2, 11.1, 11, 11.2, 15.6, 11, 11.1, 11.1, 10.8, 11.3, 14.8, 15.6, 14.9, 14.1, 14.5, 14.4 ] }, summary: "Western Express Highway, Datta Mandir Road", duration: 102 }

Anyone develop something similar, or does anything like this already exist?

Thanks!

parsispresswala avatar Nov 27 '18 11:11 parsispresswala

I got the answer. The given speed is of m/s unit and we need to convert it in km/h. 1 m/s = 3.4 km/h.

parsispresswala avatar Dec 03 '18 09:12 parsispresswala

@parsispresswala Note that the speed value returned by OSRM is the speed we decide for routing, not exactly the maxspeed= tag from OSM. The speed values are decided by the car.lua script when parsing the OSM tags - maxspeed= is considered, but we rarely use its value exactly.

In order to fetch the actual maxspeed= data, you would need to use something like annotations=nodes in combination with https://github.com/mapbox/route-annotator to fetch the OSM tag information for the route after the route is found.

danpat avatar Dec 03 '18 17:12 danpat

@danpat Thanks for tip.

parsispresswala avatar May 01 '19 07:05 parsispresswala

Hello, I find this link for speed limit. https://help.openstreetmap.org/questions/32644/determining-speed-limits-for-given-route

Can I get speed limit of route by changing some code in car.lua profile? If yes, what changes do I have to made?

parsispresswala avatar May 01 '19 09:05 parsispresswala

@danpat is https://github.com/mapbox/route-annotator also how Mapbox Directions annotates the response with a maxspeed array (https://github.com/mapbox/MapboxDirections.swift/pull/367)?

datwelk avatar May 31 '19 09:05 datwelk

Hey guys,

Allow me to squeeze in here with a related question.

I'm trying to get speed limits (used by OSRM, don't need exact maxspeed) for each of the steps along the route.

Here is a very short route I'm using: http://router.project-osrm.org/route/v1/driving/-88.900584,42.225831;-88.881613,42.233121?steps=true&annotations=speed

There are 4 steps and 9 locations if you decode the geometry value (I use https://google-developers.appspot.com/maps/documentation/utilities/polyline-utility/polylineutility).

The annotation -> speed returns 43 entries with speed values, similar to the one parsispresswala showed. So, I'm struggling to correlate those 43 speed values with 4 steps along the route. Can't understand which values are related to which steps.

What I want to achieve is to relate speed values to each of the steps. Like:

  • Step 1: 17m/s
  • Step 2: 20m/s
  • Step 3: 13m/s
  • Step 4: 30m/s

Any advice on how to read and interpret that annotation -> speed array? Thank you in advance!

pavlo-tk avatar Sep 15 '19 22:09 pavlo-tk

@parsispresswala 1 m/s = 3.6 km/h

@pavlo-tk Use the geometry in the step and ignore repeated coordinates. You can get decoded values by passing geometries=geojson. There will be one less element in the annotation array, I believe this is because the first coordinate will have a speed of 0.

mohd-akram avatar Jun 16 '20 05:06 mohd-akram

If you just need it for each step, note that the RouteStep object has a distance and duration property - you can just do speed = step[n].distance/step[n].duration.

danpat avatar Jun 16 '20 13:06 danpat

I am using OSMBonusPack for OSM based map on Android

i am querying https://router.project-osrm.org/route/v1/driving/105.8680712896,20.9947322000;105.8922453000,21.0393411000?alternatives=true&overview=full&steps=true to get the data.

Now i want the speed limit between each node.

Can anybody guide me how to do that ?

amlan007 avatar Feb 01 '21 11:02 amlan007

is there any working example how to get actual route speed limit ?

lukasa1993 avatar Jun 13 '21 10:06 lukasa1993

is there any working example how to get actual route speed limit ?

Do you finally found the solution of this ?

boooch avatar Jul 12 '22 13:07 boooch

is there any working example how to get actual route speed limit ?

Do you finally found the solution of this ?

no sorry

lukasa1993 avatar Jul 12 '22 14:07 lukasa1993

I ended up building a bespoke solution using OSM data. But haven't found a way to query it in OSRM.

jasonwiener avatar Jul 12 '22 15:07 jasonwiener

I was wondering, if there is an easy way to extend the annotations with max speed. Some of the annotations, like weight, should have the same value as calculated in lua, right? So it should also be possible to include the max speed somehow.

In assemble_geometry this is done, any hints, how we could get the max speed from any of the available facades or any other property? Storing it into the annotations list would be easy then.

Guess we have to add it in lua first, then store it somewhere in extractor_callbacks and then access it from where the annotations are built. Would that be a valid approach?

SamuelBrucksch avatar Jan 28 '23 19:01 SamuelBrucksch

OSRM isn't a general purpose OSM query tool, so trying to get some of this data is never as easy as it feels like it should be.

A quick-n-dirty way to get speed limit information is to encode it in the .name property on edges. To do this, you need to make two changes:

  1. Find where the .name property is set in car.lua and embed the maxspeed= tag value in it, so say "Main St, 35km/h"
  2. In MakeLegs() here dig through and see if you need to disable any of the step collapsing logic. In some cases, OSRM will join two edges together in the result, even if the name changes - you'd need to disable that behaviour in order to be sure you get all the name properties along your route.

danpat avatar Jan 28 '23 21:01 danpat

Thanks @danpat, this is actually something i tried already, but then i saw that there are various checks, that use the roadname for some additional logic. One case for example is this: https://github.com/Project-OSRM/osrm-backend/blob/95c45239873818ec5d982dd5f7bfb4f66930fec4/src/engine/guidance/collapse_scenario_detection.cpp#L32

In this case the check will always be false, as we attach the speed limit after the name.

Another one here which is used in various places: https://github.com/Project-OSRM/osrm-backend/blob/95c45239873818ec5d982dd5f7bfb4f66930fec4/include/engine/guidance/collapsing_utility.hpp#L123-L149

And here: https://github.com/Project-OSRM/osrm-backend/blob/95c45239873818ec5d982dd5f7bfb4f66930fec4/src/engine/guidance/post_processing.cpp#L549

So from my understanding this could cause issues in recognizing some szenarios.

Or are my concerns not justifioed in these cases?

SamuelBrucksch avatar Jan 29 '23 07:01 SamuelBrucksch

@SamuelBrucksch Depends what you're looking to get out of the result. None of the code you linked will impact the route that is found. What will change is the detail in the steps in the response - there will be more of them. If you're just looking to use OSRM to find a path and extract metadata about that path, then this quick hack is workable.

If you need the route steps to be sensible(ish) and fit for human consumption, then this isn't the way to go.

danpat avatar Jan 30 '23 05:01 danpat

Thanks for more detailed explanation. That this does not affect the route is what I expected, as this affects guidance only. However new name is converted into other instructions sometimes, so this is where i have some doubts. More new name instructions are fine, as we can filter them anyways, but if due to that instructions are not converted anymore in certain situations that would not be so nice.

SamuelBrucksch avatar Jan 30 '23 06:01 SamuelBrucksch

Ok so i did some further investigation on this and it really breaks a few instructions, so this is not really the way to go.

@danpat what would be the easiest way, to get maxspeed (or other metadata) into the route similiar to the annotations for example? I saw a PR here, that adds the way_ids to the annotations: https://github.com/Project-OSRM/osrm-backend/pull/5968

My assumption would be, that if we can add the way_ids to the annotations, it should also be possible to add the speed limits instead for that way. However that PR is not merged for 2 years and the memory consumption increased, so not sure if that is a solution we should follow.

My other idea was to add metadata from lua in a certain way, then grab it in OSRM and add a new MetaData instruction, which is hidden and not touched anywhere, except in the route to json before sending it back. Is that something which could work? And if so do you have some hints for me how to start on this?

Or is there any other approach, that would work better than reusing the name? There actually are other routing APIs, for example HERE, that allow adding metadata like speed limits, elevation and so on to be returned as part of the route, so i think this is a valid usecase, especially for navigation solutions that don't have internet on the way.

Found another related issue: https://github.com/Project-OSRM/osrm-backend/issues/6281

SamuelBrucksch avatar Mar 11 '23 11:03 SamuelBrucksch

There actually are other routing APIs, for example HERE, that allow adding metadata like speed limits

Yep, for sure - but they also don't give you the routing engine itself, so it's not clear what their runtime requirements are on the backend - probably quite big if they're returning all that extra metadata :-)

Ultimately, the conflict here is that OSRM isn't really a general-purpose road network database - its focus is on pathfinding.

Years ago, I wrote https://github.com/mapbox/route-annotator which allows you to take a sequence of OSM node IDs and retrieve all the tags between all the pairs of nodes in the route - but you'd need to run that service separately, and it is also quite memory hungry.

Other open source routing engines like Valhalla and pgRouting store some extra fields, as they allow them to be used for route selection. But there's no free lunch - if you want that extra data, you have to store it somewhere, so your memory/disk needs get bigger.

danpat avatar Mar 13 '23 17:03 danpat

But max_speed is already used while finding the route, so can't we just somehow add the meta data on the fly while putting together the route? If route-annotator also is memory hungry and needs to run in parallel, it should be fine if OSRM consumes a bit more and runs as standalone application.

I don't mind if this would b a custom solution like adding it to the names, so we can also do this on our own instance and not push it to the main version.

I just would need a starting point / some help on where to inject the data or where to best grab it, so it can be added to the route in the end.

SamuelBrucksch avatar Mar 14 '23 05:03 SamuelBrucksch

The OSM maxspeed tag is only used during preprocessing, to come up with an estimated travel time for each section of road. When maxspeed is present, it's used as a hint as to how fast you can travel on that road. If it's missing, we guess based on other tags. But ultimately, all the OSM tags are discarded and we derive a single duration for every road - that is the thing stored in the routing graph.

If it were me, the quickest hack I can think of would be to:

  1. Keep appending the metadata you want to the .name property, after some special separator, like | or something.
  2. Once the route is found, iterate over the edge sequence and extract the appended data from the .name values.
  3. Customize the post-processing logic to ignore the appended metadata (e.g. things like haveSameName)
  4. Add an annotation to the route based on what you extracted in (2)

Not very clean, but I think would be the fewest code changes. You could alternatively add a completely new edge property similar to .name and replicate all the places where we store/add that - but that would be dozens of code changes all over the place most likely.

danpat avatar Mar 14 '23 06:03 danpat

Thanks for explaining. I'll check if that works for us.

SamuelBrucksch avatar Mar 14 '23 06:03 SamuelBrucksch

Did anyone actually try to use overpass api to get the speed limits for a route based on node IDs that are returned with annotations=nodes? I managed to get ways for node IDs, but they were not in the order of the node IDs I passed in. But i have the feeling, that it should be possible to do somehow. Maybe we can help out each other and build a nice overpass filter, to return the max speed (or any other requested tag) in a similiar format as we have for the node ID array.

SamuelBrucksch avatar Mar 31 '23 15:03 SamuelBrucksch