如何通过属性 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 函数删除图层。