Leaflet 官方教程 Working with map panes 處理map panes

       在leaflet中,map pane是一個很有用的屬性,它決定了圖層在地圖上的排列順序。一般情況下,先加載的圖層在下,後加載的圖層在上,而map pane使得我們可以忽略加載順序的影響,提前確定好我們要加載的多個圖層在地圖中的排列順序。圖層的z-index有類似的功能,可以對map pane相同的圖層的排列順序進一步的控制。

       下面我們看一下官網是怎麼介紹map pane屬性的。

How the default map panes work to display overlays on top of tiles, and how to override that.

本教程將爲你解答:默認的map panes是如何使overlays圖層展示在切片圖層之上的,以及如何改變它。

What are panes?

panes是什麼?

In Leaflet, map panes group layers together implicitly, without the developer knowing about it. This grouping allows web browsers to work with several layers at once in a more efficient way than working with layers individually.

在Leaflet中,map panes會將圖層分組,對開發人員是透明的,這使得瀏覽器能夠更有效的一次處理多個圖層,而不是一次處理一個圖層。

Map panes use the z-index CSS property to always show some layers on top of others. The default order is:

Map panes 使用z-index CSS屬性來控制某些圖層顯示在其他圖層之上。默認的順序如下:

  • TileLayers and GridLayers
  • Paths, like lines, polylines, circles, or GeoJSON layers.
  • Marker shadows
  • Marker icons
  • Popups

This is why, in Leaflet maps, popups always show “on top” of other layers, markers always show on top of tile layers, etc.

這也是爲什麼在Leaflet地圖中,popups會顯示在其他圖層之上,markers總是顯示在切片圖層之上等等的原因。

A new feature of Leaflet 1.0.0 (not present in 0.7.x) is custom map panes, which allows for customization of this order.

Leaflet 1.0.0之後增加了一個新特性(0.7.X沒有)可以自定義map panes,用於調整默認的順序。

The default is not always right

默認情況並不總是合適的

In some particular cases, the default order is not the right one for the map. We can demonstrate this with the Carto basemaps and labels:

在某些特殊情況下,默認的圖層排序並不總是合適的。我們用下面的底圖和標註圖層的例子解釋一下:

沒有標註的底圖、透明的標註圖層、標註圖層在底圖之上

If we create a Leaflet map with these two tile layers, any marker or polygon will show on top of both, but having the labels on top looks much nicer. How can we do that?

如果我們爲Leaflet 底圖添加了上述兩圖層,marker和polygon會顯示在兩圖層的上方,不過讓標註顯示在最上面可能是更好地選擇。這樣的話我們該怎樣實現呢?

 
See this example stand-alone.

Custom pane

自定義pane

We can use the defaults for the basemap tiles and some overlays like GeoJSON layers, but we have to define a custom pane for the labels, so they show on top of the GeoJSON data.

對於底圖和overlays圖層如GeoJSON圖層我們可以使用其默認設置,不過對於標註圖層我們就需要自定義一個pane了,以使其顯示在GeoJSON圖層之上。

Custom map panes are created on a per-map basis, so first create an instance of L.Map and the pane:

自定義map panes都依賴於固定的地圖,所以我們首先應創建一個地圖實例L.Map以及所需pane:

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

The next step is setting the z-index of the pane. Looking at the defaults, a value of 650 will make the TileLayer with the labels show on top of markers but below pop-ups. By using getPane(), we have a reference to the HTMLElementrepresenting the pane, and change its z-index:

下一步就是設置pane的z-index。可以查看各pane的默認值,將新pane的z-index設置爲650可以使標註圖層顯示在markers圖層之上popups圖層之下。使用getPane方法可以獲取pane的Html元素,然後設置其z-index值。

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

One of the problems of having image tiles on top of other map layers is that the tiles will capture clicks and touches. If a user clicks anywhere on the map, the web browser will assume she clicked on the labels tiles, and not on the GeoJSON or on the markers. This can be solved using the pointer-events CSS property:

讓切片圖層位於其他圖層之上的問題之一就是切片會捕獲點擊或觸摸等事件。如果用戶點擊了地圖的某個區域,瀏覽器會認爲用戶點擊的是切片圖層,而非GeoJSON 元素或者markers。使用 CSS屬性pointer-events 可以解決該問題。

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

With the pane now ready, we can add the layers, paying attention to use the pane option on the labels tiles:

新增的pane已經設置好了,我們可以添加圖層了,注意要在標註切片圖層上使用pane  options參數。

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

Finally, add some interaction to each feature on the GeoJSON layer:

最後,爲GeoJSON圖層中的矢量元素添加一些交互操作。

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

map.fitBounds(geojson.getBounds());

Now the example map is complete!

這樣示例地圖就完成了!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章