Skip to content

Determine speed limit for route #5286

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
parsispresswala opened this issue Nov 27, 2018 · 25 comments
Closed

Determine speed limit for route #5286

parsispresswala opened this issue Nov 27, 2018 · 25 comments
Labels

Comments

@parsispresswala
Copy link

parsispresswala commented Nov 27, 2018

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
Copy link
Author

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.

@danpat
Copy link
Member

danpat commented Dec 3, 2018

@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.

@parsispresswala
Copy link
Author

@danpat Thanks for tip.

@parsispresswala
Copy link
Author

parsispresswala commented May 1, 2019

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 parsispresswala changed the title How to get the maxspeed of a route in km/h? Determine speed limit for route May 1, 2019
@datwelk
Copy link
Contributor

datwelk commented May 31, 2019

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

@pavlo-tk
Copy link

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!

@mohd-akram
Copy link

@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.

@danpat
Copy link
Member

danpat commented Jun 16, 2020

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.

@amlan007
Copy link

amlan007 commented Feb 1, 2021

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 ?

@lukasa1993
Copy link

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

@boooch
Copy link

boooch commented Jul 12, 2022

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

Do you finally found the solution of this ?

@lukasa1993
Copy link

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

Do you finally found the solution of this ?

no sorry

@jasonwiener
Copy link

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

@SamuelBrucksch
Copy link
Contributor

SamuelBrucksch commented Jan 28, 2023

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?

@danpat
Copy link
Member

danpat commented Jan 28, 2023

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.

@SamuelBrucksch
Copy link
Contributor

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:

const auto unnamed = link_step.name.empty();

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:

inline bool haveSameName(const RouteStep &lhs, const RouteStep &rhs)
{
const auto has_name_or_ref = [](auto const &step) {
return !step.name.empty() || !step.ref.empty();
};
// make sure empty is not involved
if (!has_name_or_ref(lhs) || !has_name_or_ref(rhs))
{
return false;
}
// easy check to not go over the strings if not necessary
else if (lhs.name_id == rhs.name_id)
return true;
// ok, bite the sour grape and check the strings already
else
return !util::guidance::requiresNameAnnounced(lhs.name,
lhs.ref,
lhs.pronunciation,
lhs.exits,
rhs.name,
rhs.ref,
rhs.pronunciation,
rhs.exits);
}

And here:

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

Or are my concerns not justifioed in these cases?

@danpat
Copy link
Member

danpat commented Jan 30, 2023

@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.

@SamuelBrucksch
Copy link
Contributor

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
Copy link
Contributor

SamuelBrucksch commented Mar 11, 2023

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:
#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:
#6281

@danpat
Copy link
Member

danpat commented Mar 13, 2023

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.

@SamuelBrucksch
Copy link
Contributor

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.

@danpat
Copy link
Member

danpat commented Mar 14, 2023

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.

@SamuelBrucksch
Copy link
Contributor

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

@SamuelBrucksch
Copy link
Contributor

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.

Copy link

github-actions bot commented Jul 8, 2024

This issue seems to be stale. It will be closed in 30 days if no further activity occurs.

@github-actions github-actions bot added the Stale label Jul 8, 2024
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Aug 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

10 participants