如何在leaflet.js中更改图层顺序


10

我希望能够更改传单中图层的顺序。

我尝试实现两个传单插件以更改图层顺序。

首先,我尝试了leaflet-control-orderlayers,它似乎可以工作,但是不支持layerGroups,这是我的提起的bug

接下来,我尝试了mapbbcode,它确实支持layerGroups,但是似乎不起作用或无法维护。

有人对如何实现此功能有任何建议吗?


Answers:


9

您可以通过几种方式来执行此操作(至少;这是我的操作方式):

  1. layer.bringToFront()layer.bringToBack()但这些只会做一次一层,只有它推到前面或后面,而不是在两者之间。因此,您需要按所需的顺序放置图层,从要在底部的图层开始,然后layer.bringToFront()在每个图层上调用。

  2. 您也可以通过删除并重新添加图层来实现。这似乎有点浪费,但是由于无论如何在重新定位图层时都必须重新绘制地图,因此通常没什么大不了的。

这是一个相当复杂的小提琴,说明了这个问题

基本上,您删除所有图层,然后按升序重新添加它们z-index。因此,遍历所有叠加层,然后调用map.removeLayer(layer),然后根据需要对它们进行排序z-index,然后使用进行重新添加layer.addTo(map)


1

我遇到了同样的问题,并尝试了fixZOrder()方法,但遗憾的是它没有为我排序Leaf标记,因为它似乎并不影响Leaflet标记的zindex。

似乎.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

与@nothingis的答案类似,在layer.bringToFront()合并layer control和异步加载数据时,以下用法可保持z顺序。

我们不想清除图层并将它们添加回地图,因为这将添加所有图层,相反,我们希望以最小的开销尊重“ 图层控件”中的选定图层。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();
    });
}

使用“图层”控件时,当将一个图层切换到视图中时,它将位于其他图层之上,添加图层时,我们需要重新应用顺序逻辑。这可以通过绑定到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;

这样,您可以将图层添加到所需的窗格中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.