Come modificare l'ordine dei livelli in leaflet.js


10

Vorrei essere in grado di cambiare l'ordine degli strati nell'opuscolo.

Ho provato a implementare due plugin di volantini per cambiare l'ordine dei livelli.

Per prima cosa ho provato i volantini-controllo-ordinatori , che sembra funzionare, ma non supporta layerGroups, ecco il mio bug archiviato .

Successivamente ho provato mapbbcode , che supporta layerGroups, ma non sembra funzionare o essere mantenuto.

Qualcuno ha qualche suggerimento su come implementare questa funzione?


Risposte:


9

Puoi farlo in un paio di modi (almeno; ecco come lo faccio):

  1. layer.bringToFront()e layer.bringToBack()ma questi faranno solo un livello alla volta e lo spingeranno solo in avanti o indietro, non nel mezzo. Quindi dovresti mettere i tuoi livelli nell'ordine desiderato, iniziare con il livello che vuoi essere in fondo e chiamare layer.bringToFront()ogni livello.

  2. Puoi anche farlo rimuovendo e aggiungendo nuovamente il livello. Questo sembra un po 'dispendioso, ma poiché la mappa deve essere ridisegnata quando si riposizionano i livelli, in genere non è un grosso problema.

Ecco un violino abbastanza complesso che illustra il problema

Fondamentalmente rimuovi tutti i livelli e poi li aggiungi nuovamente in z-indexordine crescente . Quindi, passa in rassegna tutti i tuoi strati sovrapposti e chiama map.removeLayer(layer), quindi ordinali secondo i tuoi desideri z-index, quindi aggiungili nuovamente usando layer.addTo(map).


1

Avevo lo stesso problema e ho provato il metodo fixZOrder (), ma purtroppo non ha ordinato i marcatori Leaf per me in quanto non sembra influenzare lo zindex dei marcatori Leaflet.

Sembra che .bringToFront () funziona solo su forme vettoriali che supportano questo metodo, al contrario dei marcatori Leaf che ho distribuito rendendo questa soluzione non realizzabile, per non parlare dell'altro problema di codice che stavo riscontrando con fixZOrder (), ma questo potrebbe essere unico per il mio caso.

​​

Invece ho semplicemente lasciato il layer in ordine su Leaflet (opzioni) nell'ordine in cui li ho caricati, il che ha causato problemi con l' accumulo di marker (plug-in OMS Spiderf) durante l'utilizzo dei controlli layer , ma sono riuscito a risolverli con l'aiuto della mia funzione basata su setZIndexOffset ()

function myBring2Front() {
        //layer1.bringToFront();
        layer1.eachLayer(function (layer) {
          layer.setZIndexOffset(2000);
        });
        layer2.eachLayer(function (layer) {
          layer.setZIndexOffset(1000);
        });
    }

Sebbene il mio scenario non richiedesse alla fixZOrder(layers)fine chiunque altro usando questo metodo insieme a marcatori in pila potrebbe aver bisogno di adottare un approccio simile e quindi sto pubblicando questo come una soluzione aggiuntiva per i potenziali utenti del suddetto metodo di ordine dei livelli.

​​

CREDITO : ghybs risposta su stackoverflow.com/a/37850189/11106279


0

Simile alla risposta di @nothing non è necessario i seguenti usi layer.bringToFront()per mantenere l'ordine z quando si sono combinati layer controle il caricamento asincrono dei dati.

non vogliamo cancellare i livelli e aggiungerli di nuovo alla mappa in quanto ciò aggiungerà tutti i livelli, invece vogliamo rispettare i livelli selezionati nel Controllo livello con costi generali minimi. bringToFront()possiamo farlo ma dobbiamo chiamarlo solo su un gruppo di livelli che contiene livelli (contenuto) al suo interno.

Definisci i livelli:

var dataLayers = {
    Districts: new L.geoJSON(),
    Farms: new L.featureGroup(),
    Paddocks: new L.geoJSON(),
    Surveys: new L.geoJSON()
};

L.control.layers(
    // base maps
    {
        OSM: L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>', subdomains: ['a', 'b', 'c'] });,
    },
    dataLayers,
    {
        collapsed: false,
        hideSingleBase: true
    }).addTo(map);

Utilizzare la seguente funzione per applicare l'ordine z:

/**
 * Ensure that layers are displayed in the correct Z-Order
 * Instead of explicitly defining z-order on the groups the order of the calls to beingToFront controls the resulting zOrder
 * @param {any} dataLayers Object that holds the references to the layer groups toggled by the layer control
 **/
function fixZOrder(dataLayers) {

    // only similar approach is to remove and re-add back to the map
    // use the order in the dataLayers object to define the z-order
    Object.keys(dataLayers).forEach(function (key) {

        // check if the layer has been added to the map, if it hasn't then do nothing
        // we only need to sort the layers that have visible data
        // Note: this is similar but faster than trying to use map.hasLayer()
        var layerGroup = dataLayers[key];
        if (layerGroup._layers
            && Object.keys(layerGroup._layers).length > 0
            && layerGroup._layers[Object.keys(layerGroup._layers)[0]]._path
            && layerGroup._layers[Object.keys(layerGroup._layers)[0]]._path.parentNode)
            layerGroup.bringToFront();
    });
}

Quando si utilizza il controllo Livello, quando un Livello viene attivato e visualizzato, sarà in cima agli altri livelli, quando si aggiunge un livello è necessario riapplicare la logica dell'ordine. Questo può essere fatto legandosi overlayaddall'evento sulla mappa e chiamando la fixZOrderfunzione:

map.on('overlayadd', function (e) {
    fixZOrder(dataLayers);
}

Se si caricano i dati in modo asincrono, potrebbe essere necessario chiamare anche fixZOrderquando il caricamento dei dati è stato completato, i nuovi livelli aggiunti in fase di esecuzione verranno visualizzati sopra tutti gli altri livelli.


0

È necessario creare il Pannello per controllare l'ordine.

map.createPane('myPane1');
map.createPane('myPane2');
map.getPane('myPane1').style.zIndex = 400;
map.getPane('myPane2').style.zIndex = 800;

Con questo è possibile aggiungere il livello al riquadro desiderato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.