fra*_*lbo 5 mapbox mapbox-gl mapbox-gl-js
我有一张地图,我们可以经典地从一种样式切换到另一种样式,例如从街道到卫星。
我想知道样式已加载,然后添加一个图层。
根据文档,我试图等待样式加载以基于GEOJson数据集添加图层。
当页面加载并触发时,该方法效果很好,map.on('load')但是当我更改样式时出现错误,因此从添加图层时map.on('styledataloading'),甚至在Firefox中出现内存问题。
我的代码是:
mapboxgl.accessToken = 'pk.token';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v10',
center: [5,45.5],
zoom: 7
});
map.on('load', function () {
loadRegionMask();
});
map.on('styledataloading', function (styledata) {
if (map.isStyleLoaded()) {
loadRegionMask();
}
});
$('#typeMap').on('click', function switchLayer(layer) {
var layerId = layer.target.control.id;
switch (layerId) {
case 'streets':
map.setStyle('mapbox://styles/mapbox/' + layerId + '-v10');
break;
case 'satellite':
map.setStyle('mapbox://styles/mapbox/satellite-streets-v9');
break;
}
});
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'regions.json', true);
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
callback(xobj.responseText);
}
};
xobj.send(null);
}
function loadRegionMask() {
loadJSON(function(response) {
var geoPoints_JSON = JSON.parse(response);
map.addSource("region-boundaries", {
'type': 'geojson',
'data': geoPoints_JSON,
});
map.addLayer({
'id': 'region-fill',
'type': 'fill',
'source': "region-boundaries",
'layout': {},
'paint': {
'fill-color': '#C4633F',
'fill-opacity': 0.5
},
"filter": ["==", "$type", "Polygon"]
});
});
}
Run Code Online (Sandbox Code Playgroud)
错误是:
Uncaught Error: Style is not done loading
at t._checkLoaded (mapbox-gl.js:308)
at t.addSource (mapbox-gl.js:308)
at e.addSource (mapbox-gl.js:390)
at map.js:92 (map.addSource("region-boundaries",...)
at XMLHttpRequest.xobj.onreadystatechange (map.js:63)
Run Code Online (Sandbox Code Playgroud)
为什么loadRegionMask()在测试加载样式后调用却出现此错误?
好吧,这个地图框问题很糟糕,但我有一个解决方案
myMap.on('styledata', () => {
const waiting = () => {
if (!myMap.isStyleLoaded()) {
setTimeout(waiting, 200);
} else {
loadMyLayers();
}
};
waiting();
});
Run Code Online (Sandbox Code Playgroud)
我混合了两种解决方案。
styledata事件解决你的问题您可能需要styledata在您的项目中监听事件,因为这是 mapbox-gl-js 文档中提到的唯一标准事件,请参阅https://docs.mapbox.com/mapbox-gl-js/api/#map.event:样式数据。
你可以这样使用它:
map.on('styledata', function() {
addLayer();
});
Run Code Online (Sandbox Code Playgroud)
setTimeout 可能有效,但不是解决问题的推荐方法,如果渲染工作繁重,您会得到意想不到的结果;style.load是 mapbox 中的私人事件,如 issue https://github.com/mapbox/mapbox-gl-js/issues/7579 中所述,所以我们显然不应该听它;.isStyleLoaded() 工作但不能一直调用直到样式满载,你需要一个监听器而不是一个判断方法;我遇到了类似的问题,最终得到了这个解决方案:
我创建了一个小函数来检查样式是否已完成加载:
// Check if the Mapbox-GL style is loaded.
function checkIfMapboxStyleIsLoaded() {
if (map.isStyleLoaded()) {
return true; // When it is safe to manipulate layers
} else {
return false; // When it is not safe to manipulate layers
}
}
Run Code Online (Sandbox Code Playgroud)
然后,每当我交换或以其他方式修改应用程序中的图层时,我都会使用如下函数:
function swapLayer() {
var check = checkIfMapboxStyleIsLoaded();
if (!check) {
// It's not safe to manipulate layers yet, so wait 200ms and then check again
setTimeout(function() {
swapLayer();
}, 200);
return;
}
// Whew, now it's safe to manipulate layers!
the rest of the swapLayer logic goes here...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3813 次 |
| 最近记录: |