传单:如何从 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 function
s 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>
我尝试从 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 function
s 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>