如何通过属性 in Leaflet.js过滤TopoJSON特征?
How to filter TopoJSON features by property in Leaflet.js?
我需要根据某个值(一个国家/地区的内容项数)为地图上的国家/地区着色。如果该值为 0(空),则相应的国家/地区不应为 coloured/displayed.
就 Leaflet.js 而言,这意味着我有一个 GeoJSON 文件,其中包含世界上每个国家/地区的特征。但是,只有当内容项的数量大于 0 时,该功能才会呈现(添加到地图)。使用 GeoJSON 输入文件时,这已经类似于 Leaflet.js: is it possible to filter geoJSON features by property?
的答案
这是 GeoJSON 的片段:
var mapLayer = L.geoJson(world, {
filter: function(feature, layer) {
return getContentItems(feature.properties.ISO2, "count");
},
onEachFeature: function (feature, layer) {
var contentCount = getContentItems(feature.properties.ISO2, "count");
if (contentCount) {
layer.setStyle({
'weight': 1,
'fillOpacity': .75,
'fillColor': "#0077c8", // Actually a function depending on contentCount
'opacity': .75,
'color': "#0077c8"
});
}
}
});
现在,由于地图上的详细信息,GeoJSON 文件的大小高达 11 MB。我了解了 TopoJSON,它非常棒,因为源文件现在小于 2 MB,而且具有相同的细节等级。我还设法让 TopoJSON 数据显示在地图上,但是,我不知道如何应用过滤器。
这是我当前用于添加 TopoJSON 层的代码段:
L.TopoJSON = L.GeoJSON.extend({
addData: function(jsonData) {
if (jsonData.type === "Topology") {
for (key in jsonData.objects) {
geojson = topojson.feature(jsonData, jsonData.objects[key]);
L.GeoJSON.prototype.addData.call(this, geojson);
}
}
else {
L.GeoJSON.prototype.addData.call(this, jsonData);
}
}
});
var topoLayer = new L.TopoJSON();
$.getJSON('scripts/world.topo.json')
.done(addTopoData);
function addTopoData(topoData) {
topoLayer.addData(topoData);
topoLayer.addTo(map);
topoLayer.eachLayer(handleLayer);
}
function handleLayer(layer) {
layer.setStyle({'opacity': 0}); // Too late.
}
我尝试将过滤器函数添加到 TopoJSON 声明中的 GeoJSON 扩展,但没有成功。 handleLayer()函数来晚了,我想,功能已经添加了。
编辑:
如果内容计数为 0,我可以通过将 handleLayer() 函数更改为
来删除图层
function handleLayer(layer) {
var contentCount = getContentItems(layer.feature.properties.ISO2, "count");
if (contentCount == 0) {
map.removeLayer(layer);
}
}
出于性能目的,我想在绘制之前过滤特征。我现在只是卡在需要添加过滤功能的地方。
按照 FranceImage 的建议深入 Javascript 阅读有关继承的内容后,我找到了我正在寻找的解决方案。我可以将自定义过滤器函数作为选项传递,而不是仅仅使用 var topoLayer = new L.TopoJSON();
创建一个新的 TopoJSON 对象:
var topoLayer = new L.TopoJSON(null, {
filter: function(feature, layer) {
return getNN(feature.properties.ISO2, "check");
},
onEachFeature: function (feature, layer) {
var contentCount = getContentItems(feature.properties.ISO2, "count");
if (contentCount) {
layer.setStyle({
'weight': 1,
'fillOpacity': .75,
'fillColor': "#0077c8",
'opacity': .75,
'color': "#0077c8"
});
}
}
});
无需使用 handleLayers 函数删除图层。
我需要根据某个值(一个国家/地区的内容项数)为地图上的国家/地区着色。如果该值为 0(空),则相应的国家/地区不应为 coloured/displayed.
就 Leaflet.js 而言,这意味着我有一个 GeoJSON 文件,其中包含世界上每个国家/地区的特征。但是,只有当内容项的数量大于 0 时,该功能才会呈现(添加到地图)。使用 GeoJSON 输入文件时,这已经类似于 Leaflet.js: is it possible to filter geoJSON features by property?
的答案这是 GeoJSON 的片段:
var mapLayer = L.geoJson(world, {
filter: function(feature, layer) {
return getContentItems(feature.properties.ISO2, "count");
},
onEachFeature: function (feature, layer) {
var contentCount = getContentItems(feature.properties.ISO2, "count");
if (contentCount) {
layer.setStyle({
'weight': 1,
'fillOpacity': .75,
'fillColor': "#0077c8", // Actually a function depending on contentCount
'opacity': .75,
'color': "#0077c8"
});
}
}
});
现在,由于地图上的详细信息,GeoJSON 文件的大小高达 11 MB。我了解了 TopoJSON,它非常棒,因为源文件现在小于 2 MB,而且具有相同的细节等级。我还设法让 TopoJSON 数据显示在地图上,但是,我不知道如何应用过滤器。
这是我当前用于添加 TopoJSON 层的代码段:
L.TopoJSON = L.GeoJSON.extend({
addData: function(jsonData) {
if (jsonData.type === "Topology") {
for (key in jsonData.objects) {
geojson = topojson.feature(jsonData, jsonData.objects[key]);
L.GeoJSON.prototype.addData.call(this, geojson);
}
}
else {
L.GeoJSON.prototype.addData.call(this, jsonData);
}
}
});
var topoLayer = new L.TopoJSON();
$.getJSON('scripts/world.topo.json')
.done(addTopoData);
function addTopoData(topoData) {
topoLayer.addData(topoData);
topoLayer.addTo(map);
topoLayer.eachLayer(handleLayer);
}
function handleLayer(layer) {
layer.setStyle({'opacity': 0}); // Too late.
}
我尝试将过滤器函数添加到 TopoJSON 声明中的 GeoJSON 扩展,但没有成功。 handleLayer()函数来晚了,我想,功能已经添加了。
编辑: 如果内容计数为 0,我可以通过将 handleLayer() 函数更改为
来删除图层function handleLayer(layer) {
var contentCount = getContentItems(layer.feature.properties.ISO2, "count");
if (contentCount == 0) {
map.removeLayer(layer);
}
}
出于性能目的,我想在绘制之前过滤特征。我现在只是卡在需要添加过滤功能的地方。
按照 FranceImage 的建议深入 Javascript 阅读有关继承的内容后,我找到了我正在寻找的解决方案。我可以将自定义过滤器函数作为选项传递,而不是仅仅使用 var topoLayer = new L.TopoJSON();
创建一个新的 TopoJSON 对象:
var topoLayer = new L.TopoJSON(null, {
filter: function(feature, layer) {
return getNN(feature.properties.ISO2, "check");
},
onEachFeature: function (feature, layer) {
var contentCount = getContentItems(feature.properties.ISO2, "count");
if (contentCount) {
layer.setStyle({
'weight': 1,
'fillOpacity': .75,
'fillColor': "#0077c8",
'opacity': .75,
'color': "#0077c8"
});
}
}
});
无需使用 handleLayers 函数删除图层。