jjimenezshaw / Leaflet.Control.Layers.Tree

a Tree Layers Control for Leaflet
https://jjimenezshaw.github.io/Leaflet.Control.Layers.Tree/examples/basic.html
BSD 3-Clause "New" or "Revised" License
146 stars 36 forks source link

Layer ordering issue ? #52

Open olivbrau opened 3 years ago

olivbrau commented 3 years ago

Hi, I create 3 LayerGroup (L1, L2, L3). I would like that L3 is over L2 and L2 over L1. In pure leaflet code, if create the 3 layergroups and add them to the map in this order 1->2->3 and the result is OK. But if then I create a ControlTreeLayer with these 3 layers, if I deselect then reselect L1, it goes over L2 and L3. -> how can I maintain the order of the layers, whatever I do with selection/deselection ? I forced the option autoZIndex:true (which is true by default anyway) but it doesn't seem to work. Thanks a lot for your help ! Olivier

jjimenezshaw commented 3 years ago

The problem is that the layers are added as you click on them in the menu, if I a not wrong. You would have the same problem using a ControlLayer, right? If that ordering is that critical, you can detect when a layer is added, and reorder them "internally" (be careful to not get into an infinite loop)

olivbrau commented 3 years ago

Thanks for your answer. Indeed, it is not an issue of your plugin. As you say, I reordered the layers, and it works well, but I'm not sure the best way to do it. To avoid infinite loop, for now, I have modified the leaflet code : the function _onInputClick of ControlLayer :

_onInputClick: function () {
    var inputs = this._layerControlInputs,
        input, layer;

    this._handlingClick = true;

    var bLayerAdded = false;
    for (var i = inputs.length - 1; i >= 0; i--) {
        input = inputs[i];
        layer = this._getLayer(input.layerId).layer;

        if (input.checked) {
            if (this._map.hasLayer(layer)) {
                // RAF sauf si une couche a été ajoutée en dessous !
                if (bLayerAdded) {
                    this._map.removeLayer(layer);
                    this._map.addLayer(layer);
                }
            } else {
                this._map.addLayer(layer);
                bLayerAdded = true;
            }
        } else {
            if (this._map.hasLayer(layer)) {
                this._map.removeLayer(layer);
            }
        }
    }

    this._handlingClick = false;
    this._refocusOnMap();
},

As removing and re-adding layer can be slow (if many layers), the bLayerAdded allow to optimize a bit (i remove/re-add only if a layer has been added below)

Maybe I can modify a copy of your plugin instead of modifiyng leaflet code, it seems more clean for me. -> do you know a way to implement this reordering in your plugin, I've not found a good way (but I am a real beginner in javascript)

Thanks in advance. Olivier

jjimenezshaw commented 3 years ago

I was thinking more on defining onAdd (and onRemove?) for your selected layers. Then you do not have to modify the control. Just be sure that when L1 is added, if L3 is there, remove it and add again (to put it on top).