[英]Dynamically fetch and display map layers based on the value selected in a select/dropdown box instead of checkbox
I have about 5 map layers as separate json files.我有大约 5 个地图图层作为单独的 json 文件。 Each map layer file is fetched and displayed dynamically using checkbox click.
使用复选框单击动态获取和显示每个地图图层文件。 It is working perfectly.
它运行良好。 My code is as seen given below.
我的代码如下所示。 i have another requirement to change these 5 checkboxes to a single dropdown.
我还有另一个要求将这 5 个复选框更改为单个下拉列表。 When i select a particular value from dropdown input field it has to display its corresponding layer.
当我从下拉输入字段中选择特定值时,它必须显示其对应的图层。 And if i select another value from dropdown it has to remove the previously selected map layer and display the corresponding layer of newly selected value.
如果我从下拉列表中选择另一个值,它必须删除先前选择的地图图层并显示新选择值的相应图层。 Is it possible to do the same in dropdown?
是否可以在下拉列表中做同样的事情?
<div id="inputParentId" />
<input type="checkbox" id="1" onClick="togglejsonLayer(this,'lay1');" />
Layer 1
<input type="checkbox" id="2" onClick="togglejsonLayer(this,'lay2');" />
Layer 2
<input type="checkbox" id="3" onClick="togglejsonLayer(this,'lay3');" />
Layer 3
<input type="checkbox" id="4" onClick="togglejsonLayer(this,'lay4');" />
Layer 4
<input type="checkbox" id="5" onClick="togglejsonLayer(this,'lay5');" />
Layer 5
<div id="map" style="height: 600px; width: 100%;"></div>
<script>
const mbAttr = "";
const mbUrl =
"https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=xxxxxxxx";
const streets = L.tileLayer(mbUrl, {
id: "mapbox/streets-v11",
tileSize: 512,
zoomOffset: -1,
attribution: mbAttr
});
const sattelite = L.tileLayer(mbUrl, {
id: "mapbox/satellite-v9",
tileSize: 512,
zoomOffset: -1,
attribution: mbAttr
});
const map = L.map("map", {
center: [39.74739, -105],
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);
}
async function getGeojson(checkbox, layerName) {
if (layers[layerName]) {
if (checkbox.checked) layers[layerName].addTo(map);
else map.removeLayer(layers[layerName]);
return;
}
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]);
};
</script>
You could use a Layer.Control
because it does the same job as JRI mentioned but since you want an implementation outside the map you could the following:您可以使用
Layer.Control
因为它与 JRI 提到的工作相同,但由于您想要在地图之外的实现,您可以执行以下操作:
You keep as it was before with a slight change for caching the layers that have been already fetched您保持原样,稍作更改以缓存已获取的图层
async function getGeojson(layerName) {
const response = await fetch(`./${layerName}.json`);
const geojson = await response.json();
return geojson;
}
You can have one variable that keeps all the fetched layers and one to add/remove the current selected layer on the map instantly.您可以使用一个变量来保留所有获取的图层,并使用一个变量来立即在地图上添加/删除当前选定的图层。 Also reuse a
clearMap
function to empty the map once you are in the caching and not caching mode.一旦您处于缓存而不是缓存模式,还可以重用
clearMap
函数来清空地图。
const layerCaching = {};
const currentDisplayedLayer = {};
document.getElementById("layers").onchange = (e) => {
togglejsonLayer(e.target.value);
};
const clearMap = () => {
Object.keys(currentDisplayedLayer).forEach((layer) => {
map.removeLayer(currentDisplayedLayer[layer]);
delete currentDisplayedLayer[layer];
});
};
const togglejsonLayer = async (id) => {
if (id === "0") return clearMap();
const layerName = `lay${id}`;
let geojson;
if (!layerCaching[layerName]) {
const geojsonData = await getGeojson(layerName);
geojson = L.geoJSON([geojsonData], { onEachFeature });
} else geojson = layerCaching[layerName];
if (Object.keys(currentDisplayedLayer).length > 0) clearMap();
currentDisplayedLayer[layerName] = geojson;
if (!layerCaching[layerName]) layerCaching[layerName] = geojson;
currentDisplayedLayer[layerName].addTo(map);
}
Last but not least you can run a for loop to build dynamically the select items so in case you decide to add more layers in the future with the convention laynumber it will be reall yeasy to do so.最后但并非最不重要的一点是,您可以运行 for 循环来动态构建选择项,因此如果您决定将来使用约定的层号添加更多层,这样做将非常容易。
<select name="layers" id="layers"></select>
const layersSelect = document.getElementById("layers");
layersSelect.add(new Option("Select Layer", "0"));
const arrayLength = Array.from(Array(5).keys());
arrayLength.forEach((_, id) => {
layersSelect.add(new Option(`Layer ${id + 1}`, id + 1));
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.