perliedman / leaflet-routing-machine

Control for routing in Leaflet
https://www.liedman.net/leaflet-routing-machine/
Other
1.06k stars 347 forks source link

How to create a custom step by step route based by elevation? #669

Open antonioOrtiz opened 1 year ago

antonioOrtiz commented 1 year ago

I would like to return a route where each step in the journey would have a elevation which would be lower than the previous.

Below is a route where A would be the highest in elevation and F would be the lowest.

[A,B,C,D,E,F]

I have tried first to create a circle first, with 4/5 originating from the center on each degree. [0, 345, 330, 315, 300, 285, 270, 255, 240, 225, 210, 195, 180, 165, 150, 135, 120, 105, 90, 75, 60, 45, 30, 15],

Note: Originally this method would have laid out the point on buildings however I used reverse geocoding to get the points on streets/cross-streets.

But this method creates the problem in which it is difficult to parse a route from the greater data points.

Is there a way to do this?

curtisy1 commented 1 year ago

Hey there!

I'm afraid lrm itself doesn't support any form of sorting by x, y, z params, since it usually leaves it up to the backend to find the best designated route.

As such, you would probably have to implement a custom router for that as well, like I mentioned before here

Suppose you get some form of elevation from whatever api you're using, then your route() function would have to do the sorting and return the waypoints sorted by elevation.

antonioOrtiz commented 1 year ago

Ahoy! Thanks for responding.

Think the problem I'm having from a high level is while I can easily attach the elevation data from an API to an object:

{lat: Number, lng: Number, elevation: Number}

And with that get the objects in the collection/array with the highest and lowest elevation value and feed that to LRM, for the starting and destination waypoints.

But how could one corral the LRM router to use the objects with a sorted elevation object relevant to the route itself?

For example if I made a collection of data points in an area all with elevation data

             *
         s * * *
       * * * * * * *
          * * * *
             d          

And imagine if the s represents the starting point for LRM and the d is the destination. From what I understand the routing machine will just find the best route for those two points, but how would you tell the LRM to use the next point that is lower in elevation AND relevant to the route.

           A
        s B C D
       E F G H I J 
        K L M N 
           d       

Meaning if I would want a route based on the starting point above I would want the next point to be either A, B, E, F, and lets say if it's F then logically the next point should be either G, K, L.

Basically exclude points that would points backwards and points that would exclude non neighboring points.

Hmm writing this post made me think I need to create a function that would do that and then feed that result to the LRM.

Thoughts?

curtisy1 commented 1 year ago

Sorry for taking a while to respond! And thank you for providing this detailed writeup.

From what I understand the routing machine will just find the best route for those two points, but how would you tell the LRM to use the next point that is lower in elevation AND relevant to the route.

Yes and no. What LRM does is rather simple in the end (although it has many different functionalities which makes it pretty complex). Basically, it simply acts on a route you give it. Where the route comes from is mostly up to you, which is where different routing plugins come into play.

What this means is that you have a total of two options, depending on the amount of control you have on the data provider:

Option 1 is what you already mentioned, let's call it transforming data:

Hmm writing this post made me think I need to create a function that would do that and then feed that result to the LRM.

That's essentially what I would suggest as it gives you the most flexibility. Essentially, the route function you may override would do just that and then return route(s) with your transformed data.

Option 2 is finding a data provider that includes such an option already. That way you could simply request the data and wouldn't have to worry about transforming it. I know OSRM can do it, but you'd have to set up your own server probably. Then there's brouter which does something with elevation. Mapbox apparently does it too but I'm not too sure about that, hence I'd scrap the trouble and just go with option 1

antonioOrtiz commented 1 year ago

Thanks so much for your feedback and links/references! Think I just have to sit and mess around and with that experimentation maybe something will click!

Cheers!