leaflet.js中的图层顺序排列

21

我该如何强制 Leaflet 中新添加的图层成为地图上最上方的图层?

我无法找到一种简单更改图层顺序的方法,而这是一个非常基本的 GIS 功能。我是否错过了什么?

5个回答

13
Leaflet地图由一组“窗格”(Pane)组成,其视图顺序由z-index控制。每个窗格包含一组图层(Layer)。默认的窗格显示顺序是:瓷砖->阴影->覆盖层->标记->弹出窗口。就像Etienne所描述的那样,您可以通过调用bringToFront()或bringToBack()来控制覆盖层窗格内路径的显示顺序。L.FeatureGroup也有这些方法,因此如果需要,您可以一次更改一组覆盖层的顺序。
如果要更改整个窗格的显示顺序,则只需使用CSS更改窗格的z-index即可。
如果要添加一个新的地图窗格...嗯,我还不确定如何做到这一点。

http://leafletjs.com/reference.html#map-panes

http://leafletjs.com/reference.html#featuregroup


7
根据Leaflet API,您可以在任何图层上使用bringToFrontbringToBack,将该图层置于所有路径图层的顶部或底部。

2
Leaflet最近还添加了setZIndex方法,可用于TileLayer上,以使用CSS手动管理瓷砖层次顺序。 - Etienne Desgagné

5

稍微详细一些,Bobby Sudekum制作了一个很棒的演示,展示了面板z-index的操作。我经常以此为起点。

这是关键代码:

var topPane = L.DomUtil.create('div', 'leaflet-top-pane', map.getPanes().mapPane);
var topLayer = L.mapbox.tileLayer('bobbysud.map-3inxc2p4').addTo(map);
topPane.appendChild(topLayer.getContainer());
topLayer.setZIndex(7);

3
在SO中,不鼓励使用链接作为答案,建议用自己的话回答问题,并在必要时提供链接作为参考。此外,链接可能会失效,这会使您的答案变得无意义。 - Math
第三个命令似乎只能用于 Mapbox 的 tileLayers,featuregroups 没有 getContainer() 方法。 - raphael
@RobertSiemer 好观点!我认为这已经被上面的内置函数所取代。 - Bill Morris

2

最近我也遇到了这个问题,但是在这个问题上卡住了。

这里提供的解决方案不依赖于CSS hack,并且可以使用图层组。它基本上是按所需顺序删除和重新添加图层。

我认为这是比当前答案更好的“最佳实践”。它展示了如何管理图层并重新排序它们,这对于其他情况也很有用。当前方法使用图层Title来标识需要重新排序的图层,但您可以轻松修改它以使用索引或对实际图层对象的引用。

欢迎和鼓励改进、评论和编辑。

JS Fiddle:http://jsfiddle.net/ob1h4uLm/

或者向下滚动并单击“运行代码段”,然后进行操作。我将初始缩放级别设置为应该有助于说明layerGroup重叠效果的点。

function LeafletHelper() {

    // Create the map
    var map = L.map('map').setView([39.5, -0.5], 4);

    // Set up the OSM layer
    var baseLayer = L.tileLayer(
        'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 18
    }).addTo(map);

    var baseLayers = {
        "OSM tiles": baseLayer
    };

    this.map = map;

    this.BaseLayers = {
        "OSM tiles": baseLayer
    };
    this.LayersControl = L.control.layers(baseLayers).addTo(map);

    this.Overlays = [];
    this.AddOverlay = function (layerOptions, markers) {
        var zIndex = this.Overlays.length;
        var layerGroup = L.layerGroup(markers).addTo(map);
        this.LayersControl.addOverlay(layerGroup, layerOptions.title);
        this.Overlays.push({
            zIndex: zIndex,
            LeafletLayer: layerGroup,
            Options: layerOptions,
            InitialMarkers: markers,
            Title: layerOptions.title
        });
        return layerGroup;
    }
    this.RemoveOverlays = function () {
        for (var i = 0, len = this.Overlays.length; i < len; i++) {
            var layer = this.Overlays[i].LeafletLayer;
            this.map.removeLayer(layer);
            this.LayersControl.removeLayer(layer);
        }
        this.Overlays = [];
    }
    this.SetZIndexByTitle = function (title, zIndex) {

        var _this = this;

        // remove overlays, order them, and re-add in order
        var overlays = this.Overlays; // save reference
        this.RemoveOverlays();
        this.Overlays = overlays; // restore reference

        // filter overlays and set zIndex (may be multiple if dup title)
        overlays.forEach(function (item, idx, arr) {
            if (item.Title === title) {
                item.zIndex = zIndex;
            }
        });

        // sort by zIndex ASC
        overlays.sort(function (a, b) {
            return a.zIndex - b.zIndex;
        });

        // re-add overlays to map and layers control
        overlays.forEach(function (item, idx, arr) {
            item.LeafletLayer.addTo(_this.map);
            _this.LayersControl.addOverlay(item.LeafletLayer, item.Title);
        });
    }
}

window.helper = new LeafletHelper();

AddOverlays = function () {
    // does not check for dups.. for simple example purposes only
    helper.AddOverlay({
        title: "Marker A"
    }, [L.marker([36.83711, -2.464459]).bindPopup("Marker A")]);
    helper.AddOverlay({
        title: "Marker B"
    }, [L.marker([36.83711, -3.464459]).bindPopup("Marker B")]);
    helper.AddOverlay({
        title: "Marker C"
    }, [L.marker([36.83711, -4.464459]).bindPopup("Marker c")]);
    helper.AddOverlay({
        title: "Marker D"
    }, [L.marker([36.83711, -5.464459]).bindPopup("Marker D")]);
}

AddOverlays();

var z = helper.Overlays.length;

ChangeZIndex = function () {
    helper.SetZIndexByTitle(helper.Overlays[0].Title, z++);
}

ChangeZIndexAnim = function () {
    StopAnim();
    var stuff = ['A', 'B', 'C', 'D'];
    var idx = 0;
    var ms = 200;
    window.tt = setInterval(function () {
        var title = "Marker " + stuff[idx++ % stuff.length];
        helper.SetZIndexByTitle(title, z++);
    }, ms);
}

StopAnim = function () {
    if (window.tt) clearInterval(window.tt);
}
#map {
    height: 400px;
}
<link rel="stylesheet" type="text/css" href="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.css">
<script type='text/javascript' src="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.js"></script>
<div id="map"></div>
<input type='button' value='Remove overlays' onclick='helper.RemoveOverlays();' />
<input type='button' value='Add overlays' onclick='AddOverlays();' />
<input type='button' value='Move bottom marker to top' onclick='ChangeZIndex();' />
<input type='button' value='Change z Index (Animated)' onclick='ChangeZIndexAnim();' />
<input type='button' value='Stop animation' onclick='StopAnim();' />


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接