Leaflet 中的 geoJSON:显示与列表中的值匹配的特征

geoJSON in Leaflet: Displaying features that match values in a list

我希望答案不是太明显,但我对 Javascript 和 Leaflet 都很陌生。

这几天我一直在研究这个问题。我有一个 geoJSON 文件,我已将其作为点图层添加到我的地图中——现在我想 select 显示这些点的一个子集,具体取决于 OBJECTID 字段中的要素值是否显示在我定义的数组。

到目前为止,我已经能够 select 通过将 OBJECTID 值硬编码到我的函数中来显示一个点,如下所示:

L.geoJSON(co_schools,{filter: schoolFilter}).addTo(mymap);

function schoolFilter (layer) {
    if (layer.properties.OBJECTID===3955) return true;
};

如果我在 函数中定义我的数组 ,我已经能够 select 显示多个点,如下所示:

L.geoJSON(co_schools,{filter: schoolFilter}).addTo(mymap);

function schoolFilter (layer) {
    idlist = [3955, 5298, 5299];
    for (i=0; i<idlist.length; i++) {
        if (layer.properties.OBJECTID===idlist[i]) return true;
    }
};

但是当我尝试将数组作为参数传递时出现以下错误:Uncaught TypeError: Cannot read 属性 'length' of undefined at Object.schoolFilter [作为过滤器]

L.geoJSON(co_schools,{filter: schoolFilter}).addTo(mymap);
idlist = [3955, 5298, 5299];

schoolFilter(layer, idlist);

function schoolFilter (layer, list) {
    for (i=0; i<list.length; i++) {
        if (layer.properties.OBJECTID===list[i]) return true;
    }
};

如果我在 运行 我的 L.geoJSON 命令(如下)之前定义它,我 可以 传递数组,但随后我收到此错误消息: 无法读取 schoolFilter

未定义的 属性 'OBJECTID'
function schoolFilter (layer, list) {
    for (i=0; i<list.length; i++) {
        console.log(list);
        if (layer.properties.OBJECTID===list[i]) return true;
}
};

idlist = [3955, 5298, 5299];

L.geoJSON(co_schools,{filter: schoolFilter(co_schools, idlist)}).addTo(mymap);

我希望得到任何帮助或建议 -- 谢谢!

通常,我们总是希望在使用函数之前先定义函数(例如schoolFilter())。现在 filter 选项需要一个具有特定签名的函数,所以我们不应该改变它(例如,通过添加更多参数)。您可能想要声明一个全局变量(在本例中为 list)并从函数中读取它:

you can click Run code snippet to see this code in action!

const mymap = L.map('mapid').setView([51.505, -0.09], 15);

L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
  attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
  maxZoom: 18,
  id: 'mapbox/streets-v11',
  tileSize: 512,
  zoomOffset: -1,
  accessToken: 'pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw'
}).addTo(mymap);

var popup = L.popup();
mymap.on('click', function(e) {
  popup
    .setLatLng(e.latlng)
    .setContent(e.latlng.toString())
    .openOn(mymap);
});

// dummy data
const co_schools = {
  "type": "FeatureCollection",
  "features": [{
      "properties": {
        "OBJECTID": 1
      },
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-0.092697, 51.504041]
      },
    },
    {
      "properties": {
        "OBJECTID": 2
      },
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-0.097332, 51.503213]
      },
    },
    {
      "properties": {
        "OBJECTID": 3
      },
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-0.085702, 51.505938]
      },
    },
    {
      "properties": {
        "OBJECTID": 4
      },
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [-0.086989, 51.50332]
      },
    },
  ],
};

// your code starts here

// var list = [1, 2, 3, 4];    
var list = [1, 2, 3]; // try filtering 4

function schoolFilter(layer) {
  return list.includes(layer.properties.OBJECTID)
}

L.geoJSON(co_schools, {
  filter: schoolFilter
}).addTo(mymap);
#mapid {
  min-height: 250px;
}
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="" />
<!-- Make sure you put this AFTER Leaflet's CSS -->
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin=""></script>
<div id="mapid"></div>