perliedman / leaflet-routing-machine

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

Display route calculations (distance/time) on each marker #653

Closed koufopoulosf closed 2 years ago

koufopoulosf commented 2 years ago

Hello all,

First of all I'd like to thank the community and especially the contributors for this awesome library!

I would like to display route calculations, on each marker. Suppose we add 3 waypoints A, B and C, then:

However, I could only achieve this result with the following method:

const routeControl = L.Routing.control({ // first instance
    waypoints: custom_waypoints,
    show: false,
    createMarker: function() { return null; }, // hide markers
});

routeControl._updateLines = function() { return null; }; // hide lines

routeControl.on('routesfound', function(e) {
//  ... perform calculations using e.routes[0]
//              e.g. e.routes[0].summary.totalDistance;
//                   e.routes[0].instructions[i].distance
//                      e.t.c.
    var total_distance = e.routes[0].summary.totalDistance / 1000 ;

    const routeControl2 = L.Routing.control({ // second instance
        waypoints: custom_waypoints,
        createMarker: function (i, wp) {
            return L.marker(wp.latLng).bindPopup(function () {
                return "Content with calculations ... e.g. " + total_distance
            })
        }
    }).addTo(map);

}).addTo(map);

The issue with this solution is that once a new marker is created, calculations are bound to the first routeControl instance, thus making the above process, invalid for achieving the desired result.

Moreover, the end result should have markers that can move freely around the map and be able to adjust and display their calculations on each marker accordingly.

Any help would be highly appreciated!

curtisy1 commented 2 years ago

I might not be 100% on point with this, but I think you have a couple of options to achieve the desired result.

  1. If using internal functions is not an issue then routeControl.getPlan()._updateMarkers(); should work fine, since it recreates the markers.
  2. If you don't intend to use this, you could use a combination of spliceWaypoints() and autoRoute: false
  3. This is the most versatile solution. You can create your own L.Routing.Plan object and use that to create the markers. This is pretty similar to 1. but you'll have the option of using your own logic in addition to _updateMarkers. Alternatively, you could also just override _updateMarkers with your own logic.

For a quick rundown of 1. and 2., you can check this fiddle. If those 2 options aren't enough and you need help on getting 3. to work, feel free to ask me anytime

koufopoulosf commented 2 years ago

Hello @curtisy1,

Thank you very much for your valuable feedback and the time you devoted to it, I appreciate it!

I tested the fiddle and the first option of using routingControl.getPlan()._updateMarkers(); seems by far the simplest, yet effective way to deal with this issue. However, thanks to the fiddle you provided, I noticed that most of the problem was caused by declaring the variable (e.g. var total_distance = ...) inside the routesfound event.

Besides my poor javascript skills, I also tested the fiddle by commenting both routingControl.getPlan()._updateMarkers(); & routingControl.route(); and I could still get updated values on markers, so it makes me wonder whether these are actually necessary for simple scenarios, or they apply on more complex ones.

Thank you once again for your time and for actively maintaining this library.