perliedman / leaflet-routing-machine

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

Shortest or Fastest route priority work around #602

Closed Rich-Tee closed 4 years ago

Rich-Tee commented 4 years ago

Hi there, I've added a rough work around feature to my copy of leaflet-routing-machine.js to allow route results to be prioritised by either distance (shortest route) or time (fastest route) , hope this helps anyone.

By default the OSRM returns the fastest routes, the controlDiv will show the primary route and (if there is one) a collapsed alternative slower route which may actually be shorter in distance to the primary one. All this workaround does is expand the alternative route IF it's distance is shorter than the primary route and use it as the selected route.

Step 1. Edit leaflet-routing-machine.js find the section :- module.exports = Itinerary.extend({ options: { bydistance: true, //--- add this line (a new option) --- fitSelectedRoutes: 'smart', ...etc....

Step 2. find the section setAlternatives: function(routes) { replace the line : this._selectRoute({route: this._routes[0], alternatives: this._routes.slice(1)}); with this snippet : if(this.options.bydistance == true){ for (var r = 0; r < this._routes.length; r++) { if( this._routes[r].summary.totalDistance < this._routes[0].summary.totalDistance ) { this._selectRoute({route: this._routes[1], alternatives: this._routes.slice(0)});
} else {
this._selectRoute({route: this._routes[0], alternatives: this._routes.slice(1)});
}
} } else {
this._selectRoute({route: this._routes[0], alternatives: this._routes.slice(1)}); }

Editing of leaflet-routing-machine.js complete.

Step 3. Add the newly created option in the L.Routing.control( bydistance : true, //--if true (default) expand the alternative (if shorter) - if false dont do anything -----

I'm sure the code above isnt as efficient as it might be but it's easy to understand and works for me.

perliedman commented 4 years ago

Hi, thanks for this! However, if I understand this code correctly, it will only prioritize the alternatives returned by OSRM (or whatever backend you use): in a lot of cases, OSRM will only return a single alternative, and I do not think I have ever seen it return more than two alternatives. These alternatives are by no means guaranteed to include the shortest, they will be prioritzed by whatever weighting criteria your server uses (minimum time, by default).

To really get shortest distance routes instead of shortest time, you need to alter the backend configuration for this. It's simply outside LRM's control/scope.

Rich-Tee commented 4 years ago

Hi, thanks for your comments and a great plugin. In my application I do tend to get 2 routes returned most of the time so this works for me, but may not be right for everyone. Thanks again.