I have a map wher we can classically switch from one style to another, streets to satellite for example.
I want to be informed that the style is loaded to then add a layer.
According to the doc, I tried to wait that the style being loaded to add a layer based on a GEOJson
dataset.
That works perfectly when the page is loaded which fires map.on('load')
but I get an error when I just change the style, so when adding layer from map.on('styledataloading')
, and I even get memory problems in Firefox.
My code is:
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"]
});
});
}
And the error is:
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)
Why do I get this error whereas I call loadRegionMask()
after testing that the style is loaded?
Is Mapbox GL JS open source? The previous version, Mapbox GL JS v1, is indeed a free and open-source, BSD3 licensed software. Anyone can contribute to it, or start their own derived work based on it, for free. As of February 2021, the v1 source code is still available from the Mapbox Github.
You can find the style URL on your Styles page in Mapbox Studio. Click on the menu next to a style to reveal its style URL. Click the icon to copy the style URL. For each custom style you create in Mapbox Studio, there is a draft and a production style URL available.
Mapbox GL JS is a client-side JavaScript library for building web maps and web applications with Mapbox's modern mapping technology. You can use Mapbox GL JS to display Mapbox maps in a web browser or client, add user interactivity, and customize the map experience in your application.
Give 1 second for mapbox to load the style after you set the style and you can draw the layer when you use map.on ('styledataloading') it will trigger couple of time when you changes the style Show activity on this post.
You can also upload your own data using Mapbox Studio, Mapbox Tiling Service, or the Uploads API, then access and display it in your Mapbox GL JS map. You can use any Mapbox-owned style like Mapbox Streets to style your map. Or you can use your own custom styles created in Mapbox Studio.
Use supported to check for Mapbox GL browser support, and show an alert if the browser does not support Mapbox GL. Find more information about browser support for Mapbox tools in the Browser support troubleshooting guide.
styledata
event to solve your problemYou may need to listen styledata
event in your project, since this is the only standard event mentioned in mapbox-gl-js documents, see https://docs.mapbox.com/mapbox-gl-js/api/#map.event:styledata.
You can use it in this way:
map.on('styledata', function() {
addLayer();
});
setTimeout
may work but is not a recommend way to solve the problem, and you would got unexpected result if your render work is heavy;style.load
is a private event in mapbox, as discussed in issue https://github.com/mapbox/mapbox-gl-js/issues/7579, so we shouldn't listen to it apparently;.isStyleLoaded()
works but can't be called all the time until style is full loaded, you need a listener rather than a judgement method;If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With