使用 Leaflet 动态加载多个外部 GeoJson 数据文件并动态调用多个图层

Dynamically Loading multiple External GeoJson data files and calling multiple layers dynamically using Leaflet

我要在地图上添加大约 50 个不同的地图图层。每个地图图层数据都存储为单独的 JS 文件(lay1.js、lay2.js、……lay50.js)。每个层都有自己不同的属性,比如一些层可能是多边形,一些可能是标记等。我的代码几乎如下所示。当用户单击其相应的图层复选框而不是将所有加载为脚本文件时,有什么方法可以动态添加这些 .js geojson 数据文件?我也想知道如何动态调用图层而不是将每个图层存储在单独的变量中,如下面的代码所示。

var layer1 = L.geoJSON([lay1], {style: function (feature) {}, onEachFeature: onEachFeature}); 

请帮忙。我的完整代码如下。

<script src="lay1.js" type="text/javascript"></script>
<script src="lay2.js" type="text/javascript"></script>
..............
..............
<script src="lay50.js" type="text/javascript"></script>

<input type="checkbox" id="1" onClick="togglejsonLayer(this);"/> Layer 1
<input type="checkbox" id="2" onClick="togglejsonLayer(this);"/> Layer 2
..............
..............
<input type="checkbox" id="50" onClick="togglejsonLayer(this);"/> Layer 50

<div id="map" style="height:600px; width:100%;"></div>

<script>
    mbAttr = '',
    mbUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=xxxxxxxxxxxxx';
var streets = L.tileLayer(mbUrl, {id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mbAttr}),
    sattelite = L.tileLayer(mbUrl, {id: 'mapbox/satellite-v9', tileSize: 512, zoomOffset: -1, attribution: mbAttr});

var map = L.map("map", {
    center: [8.4819, 77.0361],
    zoom: 12, 
    layers: [streets]
    });         
var baseLayers = {
    "Streets": streets, 
    "Sattelite": sattelite              
    };
L.control.layers(baseLayers).addTo(map);

function onEachFeature(feature, layer) {
    var popupContent;
    if (feature.properties && feature.properties.popupContent) {
        popupContent = feature.properties.popupContent;
    }
    layer.bindPopup(popupContent);
}

var layer1 = L.geoJSON([lay1], {style: function (feature) {}, onEachFeature: onEachFeature});
var layer2 = L.geoJSON([lay2], {style: function (feature) {}, onEachFeature: onEachFeature});
..............
..............
var layer50 = L.geoJSON([lay50], {style: function (feature) {}, onEachFeature: onEachFeature});
});

var layers = [layer1, layer2, .............. ,layer50];
selId = null;
function togglejsonLayer(checkbox) {
    var checkId = checkbox.id;
    if (checkbox.checked) {
      layers[checkId - 1].addTo(map);
      selId = checkId;
      }
    else {
      map.removeLayer(layers[checkId - 1]);
      selId = null;
   }
}
</script>

您可以通过复选框选中每个 geojson 以将其显示在地图上。

async function getGeojson(checkbox, layerName) {
    const response = await fetch(`./${layerName}.json`);
    const geojson = await response.json();
    return geojson;
}

const layers = {};
    
const togglejsonLayer = async (checkbox, layerName) => {
   const geojsonData = await getGeojson(checkbox, layerName);
   const geojson = L.geoJSON([geojsonData], { onEachFeature  });

   const checkId = checkbox.id;
   if (checkbox.checked) {
     layers[layerName] = geojson;
     layers[layerName].addTo(map);
   } else map.removeLayer(layers[layerName]);
};

您可以将地理要素存储在关联数组(层)中,一旦您获取它们并通过它们的文件名(应该是唯一的)检索它们以便能够将它们从地图中删除。

要避免一次又一次地获取相同的特征,您可以扩展 getGeojson 通过检查之前存储在层中的内容来只获取一次

async function getGeojson(checkbox, layerName) {
   if (layers[layerName]) {
      if (checkbox.checked) layers[layerName].addTo(map);
      else map.removeLayer(layers[layerName]);
      return;
   }

    ...
 }

最后但同样重要的是,您可以通过 js 添加它们来删除重复的输入声明。遍历文件名并分别在 ids 和 onClick 第二个参数上添加键。

Demo