Jak zmienić kolejność warstw w pliku leaflet.js


10

Chciałbym móc zmienić kolejność warstw w ulotce.

Próbowałem zaimplementować dwie wtyczki ulotki, aby zmienić kolejność warstw.

Najpierw wypróbowałem kontrolery ulotek , które wydają się działać, ale nie obsługują grup warstw, oto mój zgłoszony błąd .

Następnie wypróbowałem mapbbcode , który obsługuje warstwy layerGroups, ale wydaje się, że nie działa ani nie jest utrzymywany.

Czy ktoś ma jakieś sugestie dotyczące sposobu wdrożenia tej funkcji?


Odpowiedzi:


9

Możesz to zrobić na kilka sposobów (przynajmniej; tak to robię):

  1. layer.bringToFront()a layer.bringToBack()jednak to zrobi tylko jedną warstwę na raz, i tylko popycha go do przodu lub do tyłu, a nie pomiędzy nimi. Musisz więc ustawić warstwy w pożądanej kolejności, zacząć od warstwy, którą chcesz znaleźć na dole, i wywołać layer.bringToFront()każdą warstwę.

  2. Możesz to również zrobić, usuwając i ponownie dodając warstwę. Wydaje się to trochę marnotrawstwem, ale ponieważ mapa i tak musi się przerysowywać podczas zmiany położenia warstw, generalnie nie jest to taka wielka sprawa.

Oto dość skomplikowane skrzypce, które ilustrują problem

Zasadniczo usuwasz wszystkie warstwy, a następnie dodajesz je ponownie w z-indexkolejności rosnącej . Przejdź przez wszystkie warstwy nakładki i wywołaj map.removeLayer(layer), a następnie posortuj je według swoich potrzeb z-index, a następnie dodaj je ponownie za pomocą layer.addTo(map).


1

Miałem ten sam problem i wypróbowałem metodę fixZOrder (), ale niestety nie zamówiła ona dla mnie znaczników Leaf, ponieważ wydaje się, że nie wpływa ona na zindex znaczników Leaflet.

Wygląda na to. mój przypadek.

W pobliżu

Zamiast tego po prostu zostawiłem kolejność warstw w Ulotce (opcje) w kolejności, w jakiej je załadowałem, co spowodowało problemy ze stosem znaczników (wtyczka OMS Spiderf) podczas korzystania z kontrolek warstw , ale udało mi się je rozwiązać za pomocą mojej własnej funkcji opartej na setZIndexOffset ()

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

Chociaż mój scenariusz nie wymagał fixZOrder(layers)w końcu, aby ktokolwiek inny stosujący tę metodę wraz ze stosami znaczników mógł potrzebować zastosować podobne podejście, dlatego zamieszczam to jako dodatkowe rozwiązanie dla potencjalnych użytkowników wyżej wspomnianej metody porządkowania warstw.

W pobliżu

CREDIT : ghybs odpowiedź na stackoverflow.com/a/37850189/11106279


0

Podobne do odpowiedzi z @ nic nie jest konieczne, layer.bringToFront()aby zachować porządek Z po połączeniu layer controli asynchronicznym ładowaniu danych.

nie chcemy usuwać warstw i dodawać ich z powrotem do mapy, ponieważ spowoduje to dodanie wszystkich warstw, zamiast tego chcemy respektować wybrane warstwy w Kontroli warstw przy minimalnych nakładach. bringToFront()możemy to zrobić, ale musimy wywoływać to tylko w grupie warstw, która zawiera warstwy (zawartość).

Zdefiniuj warstwy:

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);

Użyj poniższej funkcji, aby wymusić kolejność w kolejności 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();
    });
}

Podczas korzystania z kontrolki Warstwa, gdy Warstwa jest przełączana na widok, będzie ona na wierzchu innych warstw, musimy ponownie zastosować logikę porządku po dodaniu warstwy. Można to zrobić przez powiązanie ze overlayaddzdarzeniem na mapie i wywołanie fixZOrderfunkcji:

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

Jeśli ładujesz dane asynchronicznie, może być również konieczne wywołanie fixZOrderpo zakończeniu ładowania danych, nowe warstwy dodane w czasie wykonywania będą renderowane na wszystkich innych warstwach.


0

Musisz utworzyć Panel, aby kontrolować zamówienie.

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

Dzięki temu możesz dodać warstwę do wybranego panelu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.