OSM API方式节点排序错误

时间:2019-03-08 16:32:05

标签: javascript leaflet openstreetmap

因此,我的目标是能够从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地图上显示的方式... Official Map

,这是在我的传单地图上显示的方式。 My Map

在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:4)

这是XML的样子:

System.IndexOutOfRangeException

请注意,OSM XML format中描述了两种信息:

  

节点是OpenStreetMap数据模型中的核心元素之一。它   由空间中的一个点组成,该点由其经度,纬度定义   和节点ID。

  • a way公开了引用节点的<?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: '&copy; <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 }

提要:https://jsfiddle.net/mnf9eL3o/