javascript - 从 Azure Map 中删除/隐藏/删除一系列功能
问题描述
这是来自Azure Maps(使用 Turf.js)的问题的后续 - 无法从 SymbolLayer 获得“点”
我现在有一个从 JSON 位置加载数据“onclick”的函数。
我现在要做的是删除数据。开启/关闭功能。
完整代码为:https ://espiritos.projectwebdev.co.uk/index-v1.0.8a.html
但我关心的关键功能是:
$(document).on("click", ".toggleCounty.on", function(event) {
if ($(this).hasClass("on")) {
var elementsToRemove = "";
$(this).toggleClass("off");
$(this).toggleClass("on");
var countyID = $(this).attr("data-countyID");
var url = geoJsonData[countyID].url;
$.getJSON(url, function(data) {
var noOfFeatures = Object.keys(data.features).length;
console.log(noOfFeatures);
for (var i = 0; i < noOfFeatures; i++) {
console.log("[" + i + "]");
console.log(data.features[i]);
datasource.remove(data.features[i]);
// map.data.remove(data.features[i]);
debugger;
}
});
}
});
我从变量“geoJsonData”进行 API 查找:
var geoJsonData = [
{
name: "Hertfordshire",
shown: "off",
url:
"https://www.naptan.projectwebdev.co.uk/api/v1/get/stoppoints?fields=all&format=geojson&filter=NptgLocalityRef|E0000708",
geomType: "points"
},
{
name: "Hampshire",
shown: "off",
url:
"https://www.naptan.projectwebdev.co.uk/api/v1/get/stoppoints?fields=all&format=geojson&filter=NptgLocalityRef|E0044074",
geomType: "points"
},
{
name: "Oxfordshire",
shown: "off",
url:
"https://www.naptan.projectwebdev.co.uk/api/v1/get/stoppoints?fields=all&format=geojson&filter=NptgLocalityRef|E0000708",
geomType: "points"
}
];
我从 JSON 加载“功能”...
然后我就是不知道如何从地图中删除这些功能。
我弹出了一个“调试器”;问题出在哪里。
我非常感谢任何指导。谢谢你。
解决方案
看起来在第一个代码块中,您正在从 Web 加载 GeoJSON 数据,然后尝试将其从数据源中删除,但您从未将其添加到数据源中。那是行不通的。如果您之前将相同的数据加载到数据源中,我认为这也行不通,因为这些是根本不同的 JSON 对象实例。实现此功能的一种方法是为 GeoJSON 文件中的每个功能添加唯一 ID。然后数据源可以对此进行匹配。例如:
{
"type": "Feature",
"id": 1,
"geometry": {
"type": "Point",
"coordinates": [-0.61827807482, 51.537852954]
},
"properties": {
"AtcoCode": "040000000127",
"NaptanCode": "bucgjtjt",
"CommonName": "Farnham House",
"Street": "Farnham Lane",
"Indicator": "adj",
"NptgLocalityRef": "E0044074",
"GridType": "UKOS",
"Easting": "495927",
"Northing": "183010",
"StopType": "BCT",
"BusStopType": "MKD",
"TimingStatus": "OTH",
"CompassPoint": "SE",
"Degrees": "135",
"StopAreaRef": "",
"AdministrativeAreaRef": "70"
}
},
请注意,您需要确保所有文件中的所有 id 都是唯一的。
您可以考虑其他一些方法;
- 如果每个特征中都有一个属性可以将特征关联回其原始文件(即“源”:“Hertfordshire”),那么您可以在图层中使用过滤器来控制基于此属性渲染的内容。
- 如果您一次只加载一个文件的数据并删除所有其他数据,请考虑使用该
datasource.setShapes
功能。这将覆盖数据源中的所有数据。
更新
我整理了一个更深入的示例,显示了不同数据集之间的切换。看起来这些数据集很小,所以我在第一次需要它们时将它们加载到数据源中并将它们保留在那里。然后切换我只需在图层级别使用过滤器。这使得第二次重新加载数据集变得更快。这适用于数万大小的数据集。如果您正在处理更大的数据集,则可能需要考虑删除数据。我还注意到,将这个示例放在一起时,您提供的第一个和最后一个数据集的 URL 是相同的(假设这是一个错误)。
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<!-- Add references to the Azure Maps Map control JavaScript and CSS files. -->
<link rel="stylesheet" href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.css" type="text/css" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.js"></script>
<script type='text/javascript'>
var map, datasource, layer;
var geoJsonData = [
{
name: "Hertfordshire",
shown: "off",
url:
"https://www.naptan.projectwebdev.co.uk/api/v1/get/stoppoints?fields=all&format=geojson&filter=NptgLocalityRef|E0000708",
geomType: "points"
},
{
name: "Hampshire",
shown: "off",
url:
"https://www.naptan.projectwebdev.co.uk/api/v1/get/stoppoints?fields=all&format=geojson&filter=NptgLocalityRef|E0044074",
geomType: "points"
},
{
name: "Oxfordshire",
shown: "off",
url:
"https://www.naptan.projectwebdev.co.uk/api/v1/get/stoppoints?fields=all&format=geojson&filter=NptgLocalityRef|E0000708",
geomType: "points"
}
];
function GetMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
center: [-0.76, 51.6],
zoom: 10,
view: 'Auto',
//Add your Azure Maps key to the map SDK. Get an Azure Maps key at https://azure.com/maps. NOTE: The primary key should be used as the key.
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});
//Wait until the map resources are ready.
map.events.add('ready', function () {
//Create a data source and add it to the map.
datasource = new atlas.source.DataSource();
map.sources.add(datasource);
//Create a layer to render the points.
layer = new atlas.layer.BubbleLayer(datasource);
map.layers.add(layer);
loadDataSetPanel();
});
}
function loadDataSetPanel(){
var html = [];
for(var i=0;i<geoJsonData.length;i++){
html.push(`<input type="checkbox" onclick="toggleDataSet('${geoJsonData[i].name}')"> ${geoJsonData[i].name}<br/>`);
}
document.getElementById('dataSetPanel').innerHTML = html.join('');
}
function toggleDataSet(name){
var ds = getDataSetByName(name);
if(ds){
//Toggle the shown state of the data set.
ds.show = (typeof ds.show === undefined)? true : !ds.show;
//Update filter on data source.
updateFilter();
//Check to see if data set is loaded, if not, load it.
if(!ds.loaded){
loadDataSet(ds);
}
}
}
function loadDataSet(ds) {
//Fetch the data directly as we want to modify it before it is entered into the data source.
fetch(ds.url)
.then(r => r.json())
.then(r => {
var f = r.features;
//Enrich the features.
for(var i=0;i<f.length;i++){
//Make the AtcoCode the unique ID for each feature. This will allow for lookups and removal by ID.
f[i].id = f[i].properties.AtcoCode;
//Add the data set name as a property for each feature for filtering purposes.
f[i].properties.dataset = ds.name;
}
//Add the features to the data source.
datasource.add(f);
});
}
function updateFilter(){
var dataSetsToShow = [];
//Get the name of each data set that should be shown.
for(var i=0;i<geoJsonData.length;i++){
if(geoJsonData[i].show){
dataSetsToShow.push(geoJsonData[i].name);
}
}
if(dataSetsToShow.length === 0){
//If there is no layers to show, set filter to false.
layer.setOptions({ filter: ['literal', false] });
} else {
//Create a data driven filter to hide the
var filter = [
'match',
//Get the data set property.
['get', 'dataset'],
//See if it matches any of the data set names to show.
dataSetsToShow,
//If so, return true, to indicate the feature should be shown.
true,
//Else, return false to not render feature.
false
];
//Update the filter on the layer.
layer.setOptions({ filter: filter });
}
}
function getDataSetByName(name){
for(var i=0;i<geoJsonData.length;i++){
if(geoJsonData[i].name === name){
return geoJsonData[i];
}
}
return null;
}
</script>
<style>
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#myMap {
position: relative;
width: 100%;
height: 100%;
}
#dataSetPanel {
position: absolute;
left:10px;
top:10px;
background-color: white;
padding: 10px;
border-radius: 5px;
}
</style>
</head>
<body onload="GetMap()">
<div id="myMap"></div>
<div id="dataSetPanel"></div>
</body>
</html>
推荐阅读
- java - 是否 setContentView 方法是 AppCompatActivity 的方法
- c - 应该打印 n 的值的程序!(n 由用户输入)在 C 中使用长双精度时表现得很奇怪
- python - Python:将小时连接到数据文件中的 dd/mm/yyyy 列
- laravel - laravel pusher 错误 api 密钥不在集群中
- opengl - 将非零 uint 转换为 255 的着色器
- java - 使用 Stack java 的 HTML 标记验证器
- python - 比较不同月份的日期
- javascript - 如何防止每次触发else语句
- android - 即使在用户关闭应用程序后也显示图像
- arrays - 如何将两个数组组合成一个具有内部列表的列表?