在传单中打开和关闭图层(更复杂的场景)

Toggle layers on and off in Leaflet (more complex scenario)

我正在使用 jQuery 的 getJSON 方法加载我在 QGIS 中创建的外部线数据。

我想做的是打开和关闭图层 - 简单的复选框,底图没有单选按钮。我还希望在初始加载地图时关闭所有图层。

我的代码

var map=L.map('map').setView([41.9698, -87.6859], 12);

var basemap = L.tileLayer('http://a.tile.stamen.com/toner/{z}/{x}/{y}.png',
    {
      //attribution: would go here
      maxZoom: 17,
      minZoom: 9
    }).addTo(map);

//display geoJson to the map as a vector

var x = function(source, map)
{
var layers = L.geoJson(source,
    {

style: function(feature){
var fillColor, side=feature.properties.side;
    if (side==='Both') fillColor = '#309e2d';
    else if (side==='Neither') fillColor = '#d90f0f';
    else if (side==='West Only') fillColor = '#e27f14';
    else if (side==='East Only') fillColor = '#2b74eb';
    else if (side==='North Only') fillColor = '#eae42b';
    else if (side==='South Only') fillColor = '#552d04';
    else fillColor = '#f0f5f3';
    return { color: fillColor, weight: 3.5, opacity: null };
        },

onEachFeature: function(feature, geojson){
var popupText="<h1 class='makebold'>Border: </h1>"+feature.properties.name+"<br/>"+"<h1 class='makebold'>Which Side?: </h1>"+feature.properties.side;
geojson.bindPopup(popupText);
        }

    }).addTo(map);
};      

$.getJSON("data/Knox.geojson", function(source){ x(source, map); });
$.getJSON("data/abc.geojson", function(source){ x(source, map); });
$.getJSON("data/xyz.geojson", function(source){ x(source, map); });

我尝试在 L.geoJson 函数(var 层)之前分配一个变量,然后 L.control.layers(null, layers).addTo(map); 这似乎不起作用。

如何为已经与一些回调函数(L.geoJson、样式和 onEachFeature)关联的多个外部 geojson 创建图层控件? 谢谢提前。

编辑:

既然你澄清了你只想切换 整个集合 on/off,它就更简单了(几乎就像你通过分配你的 L.geoJsonvar layers), 但你必须照顾好 asynchronous processes.

要避免此问题,您可以执行以下操作:

var myLayerGroup = L.layerGroup(), // do not add to map initially.
    overlays = {
        "Merged GeoJSON collections": myLayerGroup
    };

L.control.layers(null, overlays).addTo(map);

function x(source, map) {
    // Merge the GeoJSON layer into the Layer Group.
    myLayerGroup.addLayer(L.geoJson({}, {
        style: function (feature) { /* … */ },
        onEachFeature: function (feature, layer) { /* … */ }
    }));
}

$.getJSON("data/Knox.geojson", function(source){
    x(source, map);
});

然后 myLayerGroup 将逐渐填充您的 GeoJSON 功能,当它们从 jQuery getJSON 请求中收到并由 L.geoJson 转换时。


如果我的理解是正确的,您希望能够从您的 GeoJSON 数据中独立切换 on/off 每个特征?

在这种情况下,您只需在构建 L.geoJson 层组时填充 layers 对象,例如onEachFeature 函数内部:

var layers = {};

L.geoJson(source, {

    style: function (feature) { /* … */ },

    onEachFeature: function(feature, layer){
        var popupText = "<h1 class='makebold'>Border: </h1>" +
                feature.properties.name + "<br/>" +
                "<h1 class='makebold'>Which Side?: </h1>" +
                feature.properties.side;

        layer.bindPopup(popupText);

        // Populate `layers` with each layer built from a GeoJSON feature.
        layers[feature.properties.name] = layer;
    }

});

var myLayersControl = L.control.layers(null, layers).addTo(map);

如果您有更多的 GeoJSON 数据要加载并转换为 Leaflet 图层,只需完全相同(将内置图层添加到 onEachFeature 函数中的 layers 中)并仅构建图层控件一次最后,或使用 myLayersControl.addOverlay(layer).

注意:如果您在单独的请求中加载每个 GeoJSON 数据,请确保构建代码以考虑多个异步进程。参考 jQuery 延迟对象。或者先创建图层控件并使用 addOverlay 方法。

如果您希望它们最初从地图中隐藏,只需 不要 将 geoJson 图层添加到地图中...

我在 Leaflet 中学到了很多关于图层控制的知识,这比我预期的要多,这很棒。 @ghybs 提供了非常有用的建议。

我的问题是关于打开和关闭外部 geoJson 文件,特别是使用 getJSON jQuery 方法。我试图在我的多个回调中分配一个变量,例如:

var layers=L.geoJson(source,{ {style: /*....*/}, {onEachFeature: /*....*/}}

然后 L.control.layers(null, layers).addTo(map);

那行不通(为什么?我仍然无法解释 - 我是初学者程序员)。我使它起作用的方法是分别创建我的 styleonEachFeature 函数,如下所示:

function borders (feature){
var fillColor, side=feature.properties.side;
if (side==='Both') fillColor = '#309e2d';
else if (side==='Neither') fillColor = '#d90f0f';
else if (side==='West Only') fillColor = '#e27f14';
else if (side==='East Only') fillColor = '#2b74eb';
else if (side==='North Only') fillColor = '#eae42b';
else if (side==='South Only') fillColor = '#552d04';
else fillColor = '#f0f5f3';
return { color: fillColor, weight: 3.5, opacity: null };
    };

function popUp (feature, geojson){
var popupText="<h1 class='makebold'>
Border: </h1>"+feature.properties.name+"<br/>"+"<h1 class='makebold'>
Which Side</h1>"+feature.properties.side;geojson.bindPopup(popupText);
 };

然后将这些作为回调直接分配给 getJSON 方法。通过这种方式,我 可以 在 "drawing" 我的 geoJson 到地图 L.geoJson() 之前创建一个变量。然后我可以将变量动态(?)分配给图层控件:

$.getJSON("data/xyz.geojson", function(source){
var xyz = L.geoJson(source, {
    style: borders,
    onEachFeature: popUp});
togglelayer.addOverlay(xyz, 'This name shows up on the control')});
});

我这样存储变量 togglelayer

var togglelayer = L.control.layers(null, null,{collapsed: false}).addTo(map);

这个 post 也很有帮助: