因此,我的目标是能够从OSM中提取给定的Way,以显示在Leaflet地图上。但是,当我尝试拉出给定的Way时,响应中的Node似乎没有正确排序。
import axios from 'axios'
import xml2js from 'xml2js'
let parser = new xml2js.Parser()
export default {
async getStpPolygon () {
let xml = await axios.get('https://www.openstreetmap.org/api/0.6/way/39394541/full')
return parseNodes(xml)
},
async getMplsPolygon () {
let xml = await axios.get('https://www.openstreetmap.org/api/0.6/way/93481561/full')
return parseNodes(xml)
}
}
async function parseNodes (xml) {
return new Promise((resolve, reject) => {
parser.parseString(xml.data, (err, data) => {
if (err) reject(err)
let output = data.osm.node.map((node) => {
return [
parseFloat(node.$.lat),
parseFloat(node.$.lon)
]
})
resolve(output)
})
})
}
以下是an example在官方OSM地图上显示的方式...
在此先感谢您的帮助!
答案 0 :(得分:4)
这是XML的样子:
System.IndexOutOfRangeException
请注意,OSM XML format中描述了两种信息:
节点是OpenStreetMap数据模型中的核心元素之一。它 由空间中的一个点组成,该点由其经度,纬度定义 和节点ID。
<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="CGImap 0.6.1 (18903 thorn-01.openstreetmap.org)" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/">
<node id="1083701880" visible="true" version="1" changeset="6873749" timestamp="2011-01-05T16:51:40Z" user="neuhausr" uid="16591" lat="44.9751170" lon="-93.2758411"/>
<node id="1083701882" visible="true" version="1" changeset="6873749" timestamp="2011-01-05T16:51:40Z" user="neuhausr" uid="16591" lat="44.9746502" lon="-93.2772842"/>
<node id="1083701938" visible="true" version="1" changeset="6873749" timestamp="2011-01-05T16:51:41Z" user="neuhausr" uid="16591" lat="44.9727679" lon="-93.2778367"/>
<node id="1083701987" visible="true" version="1" changeset="6873749" timestamp="2011-01-05T16:51:42Z" user="neuhausr" uid="16591" lat="44.9730222" lon="-93.2787594"/>
<node id="1083701993" visible="true" version="1" changeset="6873749" timestamp="2011-01-05T16:51:42Z" user="neuhausr" uid="16591" lat="44.9737736" lon="-93.2793709"/>
<node id="1083702026" visible="true" version="1" changeset="6873749" timestamp="2011-01-05T16:51:43Z" user="neuhausr" uid="16591" lat="44.9754130" lon="-93.2765707"/>
<way id="93481561" visible="true" version="1" changeset="6873749" timestamp="2011-01-05T16:51:43Z" user="neuhausr" uid="16591">
<nd ref="1083701993"/>
<nd ref="1083701987"/>
<nd ref="1083701938"/>
<nd ref="1083701880"/>
<nd ref="1083702026"/>
<nd ref="1083701882"/>
<nd ref="1083701993"/>
<tag k="amenity" v="university"/>
<tag k="name" v="University of St. Thomas"/>
</way>
</osm>
标签的有序列表。一种方式是节点[...]的有序列表
因此,要以正确的顺序获取坐标,您必须将解析函数修改为:
nd
还有一个演示
async function parseNodes (xml) {
return new Promise((resolve, reject) => {
parser.parseString(xml.data, (err, data) => {
if (err) reject(err)
//map node ids to their coordinates
const refs = {};
data.osm.node.forEach((node) => {
const attrs = node.$;
refs[attrs.id] = [+attrs.lat, +attrs.lon];
});
// return the coordinates in the correct order
const output = data.osm.way.nd.map((nd) => {
const id = nd.$.ref;
return refs[id];
});
resolve(output)
})
})
}
async function getStpPolygon () {
const resp = await axios.get('https://www.openstreetmap.org/api/0.6/way/93481561/full')
const json = xml2js(resp.data, {compact: true});
const refs = {};
json.osm.node.forEach((node) => {
const attrs = node._attributes;
refs[attrs.id] = [+attrs.lat, +attrs.lon];
});
return json.osm.way.nd.map((nd) => {
const id = nd._attributes.ref;
return refs[id];
});
};
var map = L.map('map').setView([44.97386, -93.27569], 15);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
getStpPolygon().then((points) => {
L.polyline(points).addTo(map);
});
#map { width: 100%; height:200px }