Упорядочение слоев в leaflet.js
Как заставить новый слой, добавленный на карту в Leaflet, быть первым над базовой картой?
Я не мог найти способ легко изменить порядок слоев, который является очень простой функцией ГИС. Я что-то пропустил?
5 ответов
Карта Leaflet состоит из набора "Панелей", порядок просмотра которых контролируется с помощью z-index. Каждая панель содержит коллекцию слоев. Порядок отображения панели по умолчанию: плитки-> тени-> оверлеи-> маркеры-> всплывающие окна. Как описал Этьен, вы можете управлять порядком отображения Paths в области оверлеев, вызывая bringToFront()
или же bringToBack()
, L.FeatureGroup
также есть эти методы, так что вы можете изменить порядок групп наложений сразу, если вам нужно.
Если вы хотите изменить порядок отображения всей панели, просто измените z-index панели с помощью CSS.
Если вы хотите добавить новую панель карт... ну, я пока не знаю, как это сделать.
Согласно Leaflet API, вы можете использовать bringToFront
или же bringToBack
на любых слоях, чтобы перенести этот слой вверх или вниз всех слоев пути.
Etienne
Для более подробной информации, Бобби Судекум (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);
Пришлось решить это недавно, но наткнулся на этот вопрос.
Вот решение, которое не опирается на CSS-хаки и работает с группами слоев. Он по существу удаляет и повторно добавляет слои в нужном порядке.
Я представляю это как лучшую "лучшую практику", чем текущий ответ. Он показывает, как управлять слоями и переупорядочивать их, что также полезно для других контекстов. Текущий метод использует слой 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();' />
Я нашел это исправление (CSS):
.leaflet-map-pane {
z-index: 2 !important;
}
.leaflet-google-layer {
z-index: 1 !important;
}
нашел его здесь: https://gis.stackexchange.com/questions/44598/leaflet-google-map-baselayer-markers-not-visible