Leaflet Routing – How to Bring a Route on Top with Leaflet-Routing-Machine

leafletrouting

On a simple Leaflet map, with leafleat-routing-machine, if two routes pass by the same place, only the top one is visible. I can live with this if I can choose which route is on top, (for example by clicking on it). Go, given a route, how can I put it on top?

Here is a simple code sample I would like to improve:

map = L.map("map");

L.tileLayer("https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png", {
    attribution: "&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors"
}).addTo(map);

var route1 = L.Routing.control({
    waypoints: [
        L.latLng(-22.985308, -43.204845),
        L.latLng(-22.983449, -43.202773),
    ],
}).addTo(map);

var route2 = L.Routing.control({
    waypoints: [
        L.latLng(-22.983449, -43.204845),
        L.latLng(-22.984708, -43.202430),
    ],
}).addTo(map);

// Now I would love this to exist:
function bringOnTop() {
    ...
}

bringOnTop(route1);
bringOnTop(route2);

Best Answer

Final solution is quite simple but was very hard to come by.

Every element displayed on Leaflet map is placed in one of the standard map panes, which are DOM elements used to control the ordering of layers on the map. It is also possible to have user defined panes for fine tuning display order of overlays with DOM zIndex property. User defined pane has to be set as pane option when defining new layer.

Leaflet-routind-machine plugin creates routing lines as polylines and places all of them in overlayPane pane where they are all equal as far as zIndex is concerned.

Since routing lines are created with L.polyline method, it is possible to assign each one of them to separate pane with pane option, the only problem is how to get this option to the place where actuall creation takes place.

After a lot of trials and inspecting the guts of plugin it turned out that this option can simply be specified as on of the styles in lineOptions option of L.Routing.control method.

So to make possible dynamically choosing which of two routing lines is on top, two map panes are defined and then their zIndex is changed as needed. In the example below initially line 1 (red) is displayed above line 2 (blue) and then after 3 seconds line 2 (blue) is placed above line 1 (red).

var pane1 = map.createPane('pane1');
var pane2 = map.createPane('pane2');

pane1.style.zIndex = 2000;
pane2.style.zIndex = 3000;

var route1 = L.Routing.control({
    waypoints: [
        L.latLng(-22.985308, -43.204845),
        L.latLng(-22.983449, -43.202773),
    ],
     lineOptions: {styles: [{pane:'pane1', color: 'blue', opacity: 1, weight: 2}]}
}).addTo(map);

var route2 = L.Routing.control({
    waypoints: [
        L.latLng(-22.983449, -43.204845),
        L.latLng(-22.984708, -43.202430),
    ],
    lineOptions: {styles: [{pane:'pane2', color: 'red', opacity: 1, weight: 2}]}
}).addTo(map);

setTimeout(function() {
  pane1.style.zIndex = 3000;
  pane2.style.zIndex = 2000;
}, 3000);