Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapbox GL JS: Style is not done loading

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?

like image 628
fralbo Avatar asked Jun 06 '17 15:06

fralbo


People also ask

Is Mapbox GL JS free?

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.

How do I get Mapbox style URL?

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.

What is Mapbox GL JS?

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.

How to get Mapbox to load new styles?

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.

How do I add my own data to a GL JS map?

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.

How do I check for browser support for Mapbox GL?

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.


Video Answer


1 Answers

1. Listen styledata event to solve your problem

You 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();
});

2. Reasons why you shouldn't use other methods mentioned above

  1. 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;
  2. 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;
  3. .isStyleLoaded() works but can't be called all the time until style is full loaded, you need a listener rather than a judgement method;
like image 134
hijiangtao Avatar answered Sep 21 '22 03:09

hijiangtao