1.8. 使用地图窗格¶
在Leaflet中,地图窗格可以自动对层进行分组,但开发人员没有意识到这可以让浏览器更有效地处理多个层,而不是一次处理一个层。
地图窗格使用z索引的css属性属性来控制某些层显示在其他层的顶部。默认顺序如下:
TileLayer
S 和GridLayer
SPath
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());
这样,示例地图就完整了!