Mapbox | setStyle切换源保留添加图层
问题描述
在使用 Mapbox-GL 构建地图 Web 应用程序。它有很多很酷的功能。根据需求在地图上设置了切换基本地图(即卫星、地形等)的按钮。
遇到的问题是,当使用setStyle()更改样式时,它会删除作为图层加载的多边形并重新加载地图,而且会把我后续单独添加的图层给删除,我希望能够更改基本地图并保留这些图层。
有没有办法在不重新加载地图或至少不删除图层的情况下更改样式?
解决方法
与 Leaftlet 等地图库不同,Mapbox GL JS 没有底图
与其他图层
的概念。
所有图层都是同一个实体的一部分:样式。
因此,您需要保留数据层的一些状态,并在每次更改时调用它的 addLayer。
说白了,就是定义一个全局变量,专门把后面单独添加的图层存进去并做顺序处理,在每次切换style源的时候,监视style.load
事件从而把这些图层再添加到地图。
点击查看示例代码
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title></title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<link href="https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.js"></script>
</head>
<body>
<style>
body {
margin: 0;
padding: 0;
}
.map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
.menu {
position: absolute;
z-index: 1;
top: 10px;
right: 10px;
border-radius: 3px;
width: 120px;
}
.menu button {
font: 13px/20px 'Helvetica Neue', sans-serif;
background: #3887be;
color: #fff;
display: block;
width: 100%;
margin: 0;
padding: 0;
padding: 10px;
border: none;
border-bottom: 1px solid rgba(0, 0, 0, 0.25);
cursor: pointer;
}
.menu button:first-child {
border-radius: 3px 3px 0 0;
}
.menu button:last-child {
border-radius: 0 0 3px 3px;
border: none;
}
.menu button.active,
.menu button:hover {
background-color: #52a1d8;
}
</style>
<nav id='menu' class='menu'></nav>
<div id='map' class='map'></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiZWNob2h5ZSIsImEiOiJjbGNuM3hmeXo2a2FjM3Fsa2JpM2praGp4In0.olt3jKXnWYuYiDmiNvvndg';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [113, 32],
zoom: 4
});
var baseLayers = [{
label: 'Streets',
id: 'streets-v11'
}, {
label: 'Light',
id: 'light-v10'
}, {
label: 'Dark',
id: 'dark-v10'
}];
var menu = document.getElementById('menu');
var geojson;
function addDataLayer() {
map.addSource('urban-areas', {
'type': 'geojson',
'data': geojson
});
map.addLayer({
'id': 'urban-areas-fill',
'type': 'fill',
'source': 'urban-areas',
'paint': {
'fill-color': 'red',
'fill-opacity': 0.4
}
});
}
map.on('style.load', function () {
if (geojson) addDataLayer();
});
map.on('load', function () {
fetch('https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_urban_areas.geojson').then(e => e.json()).then(e => {
geojson = e;
addDataLayer();
})
baseLayers.forEach(function (l) {
var button = document.createElement('button');
button.textContent = l.label;
button.addEventListener('click', function () {
map.setStyle('mapbox://styles/mapbox/' + l.id);
});
menu.appendChild(button);
});
});
</script>
</body>
</html>
Mapbox-GL setStyle 移除图层
Mapbox-GL setStyle 删除图层 - stack overflow
mapbox地图自定义主题切换踩坑指南