Как изменить порядок слоев в leaflet.js


10

Я хотел бы иметь возможность изменить порядок слоев в листовке.

Я попытался реализовать два плагина листовок, чтобы изменить порядок слоев.

Сначала я попробовал leaflet-control-orderlayers , который, кажется, работает, но не поддерживает layerGroups, вот моя ошибка .

Затем я попробовал mapbbcode , который поддерживает layerGroups, но, похоже, не работает и не поддерживается.

У кого-нибудь есть предложения по реализации этой функции?


Ответы:


9

Вы можете сделать это несколькими способами (по крайней мере, так я это делаю):

  1. layer.bringToFront()и , layer.bringToBack()но они будут делать это только один слой за один раз, и только толкает его к передней или задней части , а не между ними. Таким образом, вам нужно будет расположить слои в нужном порядке, начать со слоя, на котором вы хотите быть внизу, и вызвать layer.bringToFront()каждый слой.

  2. Вы также можете сделать это, удалив и повторно добавив слой. Это кажется немного расточительным, но поскольку карта все равно должна перерисовываться при изменении положения слоев, это, как правило, не так уж важно.

Вот довольно сложная скрипка, которая иллюстрирует проблему

В основном вы удаляете все слои, а затем снова добавляете их в z-indexпорядке возрастания . Так что переберите все ваши слои наложения и вызовите map.removeLayer(layer), затем сортируйте их по вашему желанию z-index, затем добавьте их снова, используя layer.addTo(map).


1

У меня возникла та же проблема, и я попробовал метод fixZOrder (), но, к сожалению, он не упорядочил маркеры Leaf для меня, так как он, похоже, не влияет на zindex маркеров Leaflet.

Похоже, что .bringToFront () работает только с векторными фигурами, которые поддерживают этот метод, в отличие от маркеров Leaf, которые я развернул, делая это решение неработоспособным, не говоря уже о другой проблеме кода, с которой я сталкивался с fixZOrder (), но это может быть уникально для мое дело.

​​

Вместо этого я просто оставил порядок слоев в Leaflet (параметры) в порядке их загрузки, что вызвало проблемы с наложением маркеров (плагин OMS Spiderf) при использовании элементов управления слоями , но мне удалось решить их с помощью моей собственной функции, основанной на setZIndexOffset ()

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

Хотя мой сценарий не требовал, чтобы fixZOrder(layers)в конце концов кому-то другому, использующему этот метод вместе со стековыми маркерами, возможно, пришлось бы применить аналогичный подход, и поэтому я публикую это как дополнительное решение для потенциальных пользователей вышеупомянутого метода порядка слоев.

​​

КРЕДИТ : Ghybs ответ на stackoverflow.com/a/37850189/11106279


0

Аналогично ответу из @nothingisne Необходимы следующие действия layer.bringToFront()для поддержания z-порядка при комбинированной layer controlи асинхронной загрузке данных.

мы не хотим очищать слои и добавлять их обратно на карту, так как это добавит все слои, вместо этого мы хотим уважать выбранные слои в Layer Control с минимальными накладными расходами. bringToFront()Можно сделать это, но мы должны вызывать его только для группы слоев, в которой есть слои (содержимое).

Определите слои:

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

Используйте следующую функцию для обеспечения 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();
    });
}

При использовании элемента управления Layer, когда Layer переключается в поле зрения, он будет поверх других слоев, нам нужно повторно применять логику упорядочения при добавлении слоя. Это может быть сделано путем привязки к overlayaddсобытию на карте и вызова fixZOrderфункции:

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

Если вы загружаете данные асинхронно, вам также может понадобиться позвонить, fixZOrderкогда загрузка данных будет завершена, новые слои, добавленные во время выполнения, будут отображаться поверх всех остальных слоев.


0

Вы должны создать панель для управления заказом.

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

При этом вы можете добавить слой на нужную панель.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.