Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Leaflet: How to toggle ALL layers either off or on at once?

Currently, I have my control set so users can toggle each layer they want to view. But, I am unsure how to build a "all layers off" and a "all layers on" function into my UI. I have over 70+ layers and it can get messy, hence why the need for a "master" on and off switch.

Demo fiddle here

I have a single geojson object that I am filtering to display markers on my map like so:

var myData = [{...}];

var airport = L.geoJson(myData, {
filter: function(feature) {
    switch (feature.properties.Subcategory) {
        case 'Airport': return true;
            break;
    }
},
 onEachFeature: onEachFeature
});

var heliport = L.geoJson(myData, {
  filter: function(feature) {
    switch (feature.properties.Subcategory) {
        case 'Heliport': return true;
            break;
    }
},
 onEachFeature: onEachFeature
});

...
...
...
and so on...

I was thinking of putting a button control at top right of the map page like so:

<div id="toggle" style="display:none;">
Toggle all layers:
<button type="button" class="btn btn-link"     onClick="removeAllLayers()">OFF</button>
<button type="button" class="btn btn-link" onClick="addAllLayers()">ON</button>
</div>

and add that control to the map like so:

map.legendControl.addLegend(document.getElementById('toggle').innerHTML).setPosition('topright');

and assign all layers to a layerGroup like so:

var showAllLayers = L.layerGroup(myData);
var removeAllLayers = L.layerGroup(myData);

and build a function like so (only removeAllLayers example is shown):

function removeAllLayers() {
    removeAllLayers.clearLayers();
};

Of course, this doesn't work. Can someone show me the way to get this figured out or do you have any better ideas on how to approach this? THANK YOU!

like image 453
redshift Avatar asked Sep 26 '22 21:09

redshift


1 Answers

The easiest way to add/remove all the overlays is by iterating the _layers object used by L.Control.Layers (and L.Control.GroupedLayers), check if it's an overlay and add/removing them to/from the _map instance. You can easily include two new methods into the control to add that logic. For example:

L.Control.GroupedLayers.include({
    addOverlays: function () {
        for (var i in this._layers) {
            if (this._layers[i].overlay) {
                if (!this._map.hasLayer(this._layers[i].layer)) {
                    this._map.addLayer(this._layers[i].layer);
                }
            }
        }
    },
    removeOverlays: function () {
        for (var i in this._layers) {
            if (this._layers[i].overlay) {
                if (this._map.hasLayer(this._layers[i].layer)) {
                    this._map.removeLayer(this._layers[i].layer);
                }
            }
        }
    }
});

Example of the concept on Plunker: http://plnkr.co/edit/AvV55Pph7hkectadZSTb?p=preview

like image 134
iH8 Avatar answered Oct 11 '22 14:10

iH8