传单:如何一次关闭或打开所有图层?

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

目前,我设置了控件,以便用户可以切换他们想要查看的每个图层。但是,我不确定如何在我的 UI 中构建 "all layers off" 和 "all layers on" 函数。我有超过 70 层,它可能会变得混乱,因此为什么需要 "master" 打开和关闭开关。

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

当然,这不行。有人可以告诉我解决这个问题的方法,或者您对如何解决这个问题有更好的想法吗?谢谢!

你在这个问题中描述的问题,似乎有几个错误:

  • 您的 myData 是用于构建多个 L.GeoJSON 层的 GeoJSON 对象的初始数组。 myData 不能直接在层组中使用,因为它不是 Leaflet 层。您可以做的是在实例化图层组时传递一个 L.GeoJSON 图层数组。
  • 您不应该为图层组 removeAllLayers 和函数 removeAllLayers 使用相同的标识符。一个或另一个将不可访问(通常函数声明应优先)。
  • 在 jsfiddle 网站的上下文中,避免使用内联事件侦听器 (<button onclice="removeAllLayers()">),因为出于某种原因 jsfiddle 将它们剥离/丢失 HTML 部分和 JS 部分之间的引用……而是你应该从 JS 部分 add event listeners

实施这 3 点将得到:

var allLayers = [
  airport,
  heliport,
  seaplane,
  railroad,
  waterTaxi
];

var removeAllLayers2 = L.layerGroup(allLayers).addTo(map);

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

// After you add your button to the document.
document.getElementById("buttonOff").addEventListener("click", function () {
  removeAllLayers();
});

更新的 jsfiddle:http://jsfiddle.net/0pLwae33/4/

现在这只实现了所有图层的移除。您也可以轻松实现添加,但它可能会一次添加所有图层,而不管您在分组图层控件中选择的图层如何。

您可能会寻找一种在该插件中 "nest" 更多级别的方法,这样您就可以有一个 "master" 复选框来切换所有叠加层 on/off,然后您的分组图层。

对于这种用法,leaflet-layer-tree-plugin 似乎很有希望,但演示看起来很糟糕,也许是插件本身。

如果那确实是您需要的功能,请查看您当前使用的其他 layer switching control plugins, or consider improving the functionality of Leaflet.groupedlayercontrol plugin

add/remove所有覆盖的最简单方法是迭代L.Control.Layers(和L.Control.GroupedLayers)使用的_layers对象,检查它是否是覆盖和add/removing 他们 to/from _map 实例。您可以轻松地将两个新方法包含到控件中以添加该逻辑。例如:

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

Plunker 上的概念示例:http://plnkr.co/edit/AvV55Pph7hkectadZSTb?p=preview