传单:如何从 URL 获取 geojson 并将其传递给 L.geoJson

Leaflet: How to fetch geojson from URL and pass it to L.geoJson

我尝试从 URL 加载 geojson 并将其显示在带有传单的地图中:

<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" type="text/css" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"/>
    <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
</head>

<body>
<div id="my_map" style="height: 600px"></div>
<script>
const map = L.map('my_map')
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
map.setView([37.8, -96], 4);
async function load_shapefile() {
    let url = 'https://raw.githubusercontent.com/shawnbot/topogram/master/data/us-states.geojson';
    let shape_obj = await (await fetch(url)).json();
    return shape_obj
}
L.geoJson(load_shapefile()).addTo(map);
</script>
</body>
</html>

我进入 JS 控制台:

Uncaught Error: Invalid GeoJSON object.
    at De (GeoJSON.js:221)
    at i.addData (GeoJSON.js:117)
    at initialize (GeoJSON.js:92)
    at new i (Class.js:22)
    at Object.Ke (GeoJSON.js:439)
    at leaflet.html:21

如果可能,我不想使用jQuery。 感谢您的任何输入!

编辑:我用实际的 GeoJSON 文件替换了 url,谢谢@IvanSanchez!

如果你想提取 geojson 并在以后使用它,你需要创建另一个函数来等待结果,因为操作是异步的:

<html>

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" type="text/css" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
  <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
</head>

<body>
  <div id="my_map" style="height: 600px"></div>
  <script>
    const map = L.map('my_map')
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
    map.setView([37.8, -96], 4);

    async function load_shapefile() {
      let url = 'https://raw.githubusercontent.com/shawnbot/topogram/master/data/us-states.geojson';
      const response = await fetch(url)
      const shape_obj = await response.json();
      console.log(shape_obj);
      return shape_obj;
    }

    async function main() {
      const json = await load_shapefile();
      L.geoJson(json).addTo(map);
    }

    main();
  </script>
</body>

</html>

否则,如果您不想进一步使用 geojson 实例,请使用 then 获取数据并立即使用它们。

<html>

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" type="text/css" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
  <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
</head>

<body>
  <div id="my_map" style="height: 600px"></div>
  <script>
    const map = L.map('my_map')
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
    map.setView([37.8, -96], 4);

    let url = 'https://raw.githubusercontent.com/shawnbot/topogram/master/data/us-states.geojson';
    const response = fetch(url).then(response => response.json()).then(response => {
      L.geoJson(response).addTo(map);
    })
  </script>
</body>

</html>

@kboul's answer 已经指出了如何修复它,但没有解释 为什么它首先失败

原始代码失败,因为 async functions return Promise 的一个实例,并且 L.GeoJSON 构造函数需要一个静态数据结构。

所以不用

async function load_shapefile() {
    let url = 'https://raw.githubusercontent.com/shawnbot/topogram/master/data/us-states.geojson';
    let shape_obj = await (await fetch(url)).json();
    return shape_obj
}
L.geoJson(load_shapefile()).addTo(map);

你可以做到

load_shapefile().then(function(geojsonData){
    L.geoJson(load_shapefile()).addTo(map);
});

并稍微滥用 .then() 的语法来仅传递函数引用:

load_shapefile().then(L.geoJson).then(map.addLayer.bind(map));

<html>

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" type="text/css" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
  <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
</head>

<body>
  <div id="my_map" style="height: 600px"></div>
  <script>
    const map = L.map('my_map')
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
    map.setView([37.8, -96], 4);

    async function load_shapefile() {
      let url = 'https://raw.githubusercontent.com/shawnbot/topogram/master/data/us-states.geojson';
      const response = await fetch(url)
      const shape_obj = await response.json();
      console.log(shape_obj);
      return shape_obj;
    }

    load_shapefile().then(L.geoJson).then(map.addLayer.bind(map));
    
  </script>
</body>

</html>