简体   繁体   中英

Layer Ordering in leaflet.js

How can I force a new layer added to the map in Leaflet to be the first over the basemap?

I could not find a method to easily change the order of the layers, which is a very basic GIS feature. Am I missing something?

A Leaflet map consists of a collection of "Panes" whose view order is controlled using z-index. Each pane contains a collection of Layers The default pane display order is tiles->shadows->overlays->markers->popups. Like Etienne described, you can control the display order of Paths within the overlays pane by calling bringToFront() or bringToBack() . L.FeatureGroup also has these methods so you can change the order of groups of overlays at once if you need to.

If you want to change the display order of a whole pane then you just change the z-index of the pane using CSS.

If you want to add a new Map pane...well I'm not sure how to do that yet.

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

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

According to Leaflet API, you can use bringToFront or bringToBack on any layers to brings that layer to the top or bottom of all path layers.

Etienne

For a bit more detail, Bobby Sudekum put together a fantastic demo showing manipulation of pane z-index. I use it as a starting point all the time.

Here's the key code:

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

Had to solve this recently, but stumbled upon this question.

Here is a solution that does not rely on CSS hacks and works with layer groups. It essentially removes and re-adds layers in the desired order.

I submit this as a better "best practice" than the current answer. It shows how to manage the layers and re-order them, which is also useful for other contexts. The current method uses the layer Title to identify which layer to re-order, but you can easily modify it to use an index or a reference to the actual layer object.

Improvements, comments, and edits are welcome and encouraged.

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

Or scroll down and click "Run code snippet" and play with it. I set the initial zoom level to a point that should help illustrate the layerGroup overlap effect.

 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();' /> 

I've found this fix (css):

.leaflet-map-pane {
    z-index: 2 !important;
}

.leaflet-google-layer {
    z-index: 1 !important;
}

found it here: https://gis.stackexchange.com/questions/44598/leaflet-google-map-baselayer-markers-not-visible

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM