[GIS] Mapbox GLJS – group layers

group-layerlayersmapbox-gl-js

I'm trying to build an interactive map, without any knowledge in javascript, and i found myself a bit lost in this large world.
I've already designed my style in mapbox studio. And now, trying to make it work on the web.
I'd like to display/hide multiple layers, but with one button and the default visibility set as none (tried to set "visibility" as none, but doesn't seem to work). (user must click on 1 button to load all layers in a group)

Followed this tutorial : https://www.mapbox.com/mapbox-gl-js/example/toggle-layers/
I could accomplish it, but i got 1 button for each layer.
So i tried to group them, following this tutorial: http://leafletjs.com/examples/layers-control.html

But things aren't that easy, I'm trying to mix things every way I can, but can't figure how to make it work…

Here is my basic code:

mapboxgl.accessToken = 'pk.eyJ1IjoiY2RyaWNlIiwiYSI6ImNpcDZvMTU2cDAwMGR2MW03aXZ1Y2xpdXAifQ.DIB1RcA8uDyXSVvyz7Skcg';

// Set bounds 
var bounds = [
    [5.336040, 47.678506], // Southwest coordinates
    [7.202343, 48.697659]  // Northeast coordinates
];

var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/cdrice/cip6vwuus000wdkm3q2adkr24',
    center: [6.95, 48.28],
    zoom: 8.5,
    maxBounds: bounds // Sets bounds as max
});

map.on('load', function () {

map.addLayer({
        'id': 'reciprocite',
        'type': 'fill',
        'source': 'reciprocite',
        'layout': {
            'visibility': 'none'
        },       
        'source-layer': 'reciprocite-gap'
    });

map.addLayer({
        'id': 'reciprocite',
        'type': 'fill',
        'source': 'reciprocite',
        'layout': {
            'visibility': 'none'
        },       
        'source-layer': 'reciprocite-gpv'
    });
 });
addLayer('Reciprocite', 'reciprocite-gpv');
addLayer('Reciprocite', 'reciprocite-gap');
function addLayer(name, id) {
    var link = document.createElement('a');
    link.href = '#';
    link.className = 'active';
    link.textContent = name;

    link.onclick = function (e) {
        e.preventDefault();
        e.stopPropagation();

        var visibility = map.getLayoutProperty(id, 'visibility');

        if (visibility === 'visible') {
            map.setLayoutProperty(id, 'visibility', 'none');
            this.className = '';
        } else {
            this.className = 'active';
            map.setLayoutProperty(id, 'visibility', 'visible');
        }
    };

    var layers = document.getElementById('menu');
    layers.appendChild(link);
}

Best Answer

Because you created your own style with the "reciprocite" layers baked in through Mapbox Studio, you don't need to re-add the layers.

To toggle your layers with one button you will want to loop through your layers - copy and paste this into your script tags:

Here is the working example: http://geo-odyssey.com/links/stack.html

mapboxgl.accessToken = 'pk.eyJ1IjoiY2RyaWNlIiwiYSI6ImNpcDZvMTU2cDAwMGR2MW03aXZ1Y2xpdXAifQ.DIB1RcA8uDyXSVvyz7Skcg';

// Set bounds 
 var bounds = [
     [5.336040, 47.678506], // Southwest coordinates
     [7.202343, 48.697659]  // Northeast coordinates
 ];

var map = new mapboxgl.Map({
     container: 'map',
     style: 'mapbox://styles/cdrice/cip6vwuus000wdkm3q2adkr24',
     center: [6.95, 48.28],
     zoom: 8.5,
     maxBounds: bounds // Sets bounds as max
});

//whatever layers you want to toggle go in to this function
toggleLayer(['reciprocite-gpv', 'reciprocite-gap','reciprocite-gprmv'], 'reciprocite toggle 1');
toggleLayer(['reciprocite-non-recipro','reciprocite-eh3vv'], 'reciprocite toggle 2');

function toggleLayer(ids, name) {
    var link = document.createElement('a');
    link.href = '#';
    link.className = 'active';
    link.textContent = name;

    link.onclick = function (e) {
        e.preventDefault();
        e.stopPropagation();
        for (layers in ids){
            var visibility = map.getLayoutProperty(ids[layers], 'visibility');
            if (visibility === 'visible') {
                map.setLayoutProperty(ids[layers], 'visibility', 'none');
                this.className = '';
            } else {
                this.className = 'active';
                map.setLayoutProperty(ids[layers], 'visibility', 'visible');
            }
         }

    };

    var layers = document.getElementById('menu');
    layers.appendChild(link);
}