1.8. 使用地图窗格

在Leaflet中,地图窗格可以自动对层进行分组,但开发人员没有意识到这可以让浏览器更有效地处理多个层,而不是一次处理一个层。

地图窗格使用z索引的css属性属性来控制某些层显示在其他层的顶部。默认顺序如下:

  • TileLayer S 和 GridLayer S

  • Path S,如直线,多段线,圆或者 GeoJSON 图层。

  • Marker 阴影

  • Marker 图标

  • Popup S

这就是为什么在Leaflet地图中,弹出窗口显示在其他层的顶部,标记始终显示在切片层上,依此类推。

Leaflet 1.0.0添加了一项新功能(0.7.X不可用),以自定义地图窗格以调整默认顺序。

1.8.1. 默认值并不总是合适的

在某些特殊情况下,默认的层排序并不总是合适的。我们使用以下底图和标签图层的示例进行说明:

<style>
    .tiles img {
        border: 1px solid #ccc;
        border-radius: 5px;
    }
</style>

Basemap without annotation

Transparent label layer

Label the layer above the basemap

如果我们将上面的底图和注释层添加到Leaflet地图,任何多边形或标记都将显示在这两个层的上方,但让注释层显示在顶部可能会更好。那么应该如何实现这一点?

Show the example

1.8.2. 自定义窗格

对于底图和覆盖层(如GeoJSON),可使用其默认设置,但对于注释层,需要自定义一个窗格,使其显示在GeoJSON层的顶部。

自定义地图窗格是在原始地图的基础上创建的,因此应该首先创建 L.Map 以及它所需的面板:

var map = L.map('map');
map.createPane('labels');

下一步是设置面板的z索引值。要查看该窗格的默认值,请将新窗格的z索引值设置为650,以使Label层显示在Markers层上方的Popup层的下方。使用 getPane() 方法来获取该窗格的HTML元素,修改其z索引值。

map.getPane('labels').style.zIndex = 650;

将图像层放在其他层之上的问题之一是,切片会捕获点击或触摸等事件。如果用户点击地图的某个区域,浏览器会认为用户点击的是图像层,而不是GeoJSON层或标记层。我们可以使用CSS的指针事件属性来解决这个问题:

map.getPane('labels').style.pointerEvents = 'none';

新的面板已经创建,可添加层,请注意 pane 标签层上的选项:

var positron = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png', {
    attribution: '©OpenStreetMap, ©CartoDB'
}).addTo(map);

var positronLabels = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png', {
    attribution: '©OpenStreetMap, ©CartoDB',
    pane: 'labels'
}).addTo(map);

var geojson = L.geoJson(GeoJsonData, geoJsonOptions).addTo(map);

最后,向GeoJSON层添加一些交互功能:

geojson.eachLayer(function (layer) {
    layer.bindPopup(layer.feature.properties.name);
});
map.fitBounds(geojson.getBounds());

这样,示例地图就完整了!