5

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);
}
0

2 Answers 2

3

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);
}
6
  • Exactly what i was looking for !! Thank very much.
    – Cdrice
    Jun 20, 2016 at 6:50
  • In order to understand further : So the "toggleLayer" is a similar function as grouplayer ? if i'd like to add other button, for other layers, i should just copy the code and add it bellow ? and just change the line "toggleLayer(['otherlayer'])" ? Is that the good way of doiing it ?
    – Cdrice
    Jun 20, 2016 at 7:14
  • Just another question also, as i watched the code of your exemple. why did you add <a class="active" href="#">toggle reciprocite</a></nav> ?, as the function already create the button ? is it to style it easilier after with css ?
    – Cdrice
    Jun 20, 2016 at 7:49
  • About the last comment. I did a "show source code" on your exemple, but some things were different, from the script to the divs, maybe because it's not the native code, but created with the initial script. So if i understand well, the code <a class="active" href="#">toggle reciprocite</a></nav> , is created with the function "document.createElement" ? Anyway, maybe time i learn how java work and stop asking too much, but man, it's hard !
    – Cdrice
    Jun 20, 2016 at 8:50
  • Sorry for so many comments, could find it myselft by searching a bit. found how to add another button layers: created another parameter (name) on the Togglelayer function so it look like this <code> function toggleLayer(name,ids) { var link = document.createElement('a'); link.href = '#'; link.className = 'active'; link.textContent = name; </code> and so i can add other layers, by giving them a name, like this <code>toggleLayer('name displayed',['layer1', 'layer2','layer3']); </code>
    – Cdrice
    Jun 20, 2016 at 9:47
-1

You are looking at leaflet documentation, so you can just use addLayer and removeLayer. I edited the example you linked to, http://leafletjs.com/examples/layers-control.html

See a fiddle here turn on and off layers

Basically, make your map

        var map = L.map('map', {
          center: [39.73, -104.99],
          zoom: 10,
          layers: [grayscale]
        });

Then I just added button to do the on and off. Edited to do it in single button.

      var layersOn = "No";

      $( "#off" ).click(function() {

        if (layersOn === "No") {
          map.addLayer(cities);
          layersOn = "Yes";
        } else {
          map.removeLayer(cities);
          layersOn = "No";
       }
    });
1
  • This is a Mapbox-GL question - although, if they struggle with JavaScript, Leaflet might be a good solution.
    – CCantey
    Jun 17, 2016 at 18:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.