OSM转换成Google地图多边形

5

我想使用多边形类和经纬度坐标数组在Google Maps上绘制城区范围。

OpenStreetMap提供了所有我需要的数据 - 如果我输入一些区域名称,我可以获得OSM XML格式的有用数据,例如拉脱维亚里加的“Vecmilgravis”地区的OSM绘制多边形以及其OSM XML格式的数据

问题是所有这些node节点都按某种奇怪的顺序排序,所以如果我只提取所有latlng对,并为Google Maps Polygon类创建一个坐标数组,我看到的不是我预期的结果:

enter image description here

标记显示正确,因为它们的坐标顺序对于它们来说并不重要,但是由于我从OSM数据复制粘贴错误的坐标顺序,多边形错乱了。

那么,我该如何提取(或手动排序)OSM节点坐标以正确的顺序呈现?


1
(边界)OSM中的关系路径组成。路径包含一个有序节点列表。为了对关系进行排序,您需要查看它们的第一个和最后一个节点来对路径进行排序。连续的路径将在其末尾和开头共享相同的节点。 - scai
@scai 谢谢您提供这么有用的解释! - artuska
2个回答

5

这可能是实现的“正确”方式:

  1. 遍历XML并保存带有其关联ID的节点
  2. 遍历“way”标记以在这些段内进行排序
  3. 按顺序将“way”路径端点连接起来(假定相邻路段有公共点)
  4. 使用完成的路径创建多边形

(可能有更高效的方法)

输出屏幕截图

代码片段:

var geocoder;
var map;
var centerPt;
var markers = [];

function initialize() {
  var map = new google.maps.Map(
    document.getElementById("map_canvas"), {
      center: new google.maps.LatLng(37.4419, -122.1419),
      zoom: 13,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });
  var path = [];
  var xmldata = xmlParse(xmlBoundaryData);
  var nodes = xmldata.getElementsByTagName("node");
  var bounds = new google.maps.LatLngBounds();
  var nodeArray = [];
  // get the coordinate data out of the "nodes"
  for (var i = 0; i < nodes.length; i++) {
    var pt = new google.maps.LatLng(nodes[i].getAttribute("lat"),
      nodes[i].getAttribute("lon"));
    path.push(pt);
    nodeArray[nodes[i].getAttribute("id")] = pt;
    var marker = new google.maps.Marker({
      position: pt,
      map: map,
      title: "" + i
    })
    markers.push(marker);
    bounds.extend(pt)
  }
  var waysArray = [];
  // get the ways, putting the "nodes" in "way" order
  var ways = xmldata.getElementsByTagName("way");
  for (var j = 0; j < ways.length; j++) {
    var waypath = [];
    var nd = ways[j].getElementsByTagName("nd");
    for (var i = 0; i < nd.length; i++) {
      waypath.push(nodeArray[nd[i].getAttribute("ref")]);
    }
    waysArray.push(waypath);
    var waypoly = new google.maps.Polyline({
      path: waypath,
      map: map,
      strokeColor: "#0000FF"
    })
  }
  // assemble the "ways" into a polygon by concatenating together at the common points
  console.log("number of ways="+waysArray.length);
  var polypath = [];
  for (var i = 0; i < waysArray.length; i++) {
    if (i == 0) {
      // first "way"
      console.log("way 0, ends at " + waysArray[i][0].toUrlValue(6));
      for (var j = 0; j < waysArray[i].length; j++) {
        polypath.push(waysArray[i][j]);
      }
    } else if (polypath[polypath.length - 1].equals(waysArray[i][0])) {
      console.log("way " + i + ", ends at " + waysArray[i][0].toUrlValue(6));
      for (var j = 1; j < waysArray[i].length; j++) {
        polypath.push(waysArray[i][j]);
      }
    } else if (polypath[polypath.length - 1].equals(waysArray[i][waysArray[i].length - 1])) {
      console.log("way " + i + " (rev), ends at " + waysArray[i][waysArray[i].length - 1].toUrlValue(6));
      for (var j = waysArray[i].length - 2; j >= 0; j--) {
        polypath.push(waysArray[i][j]);
      }
    } else {
      // not adjacent to the end, try again later (push it on to the end of the array)
      waysArray.push(waysArray[i]);
    }
  }
  var polygon = new google.maps.Polygon({
    map: map,
    path: polypath
  });
  map.fitBounds(bounds);
}

google.maps.event.addDomListener(window, "load", initialize);

function xmlParse(str) {
  if (typeof ActiveXObject != 'undefined' && typeof GetObject != 'undefined') {
    var doc = new ActiveXObject('Microsoft.XMLDOM');
    doc.loadXML(str);
    return doc;
  }

  if (typeof DOMParser != 'undefined') {
    return (new DOMParser()).parseFromString(str, 'text/xml');
  }

  return createElement('div', null);
}
var xmlBoundaryData = '<?xml version="1.0" encoding="UTF-8"?><osm version="0.6" generator="CGImap 0.4.0 (20233 thorn-01.openstreetmap.org)" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/"><node id="939092112" visible="true" version="3" changeset="9125708" timestamp="2011-08-25T22:47:10Z" user="Raitisx" uid="105318" lat="57.0408668" lon="24.0680754"><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></node><node id="956004391" visible="true" version="5" changeset="36231114" timestamp="2015-12-28T22:52:59Z" user="AkageMuk" uid="2012081" lat="57.0299437" lon="24.1089277"><tag k="name" v="Vecmīlgrāvis"/><tag k="name:de" v="Alt-Mühlgraben"/><tag k="name:lv" v="Vecmīlgrāvis"/><tag k="name:ru" v="Вецмилгравис"/><tag k="place" v="suburb"/><tag k="wikipedia" v="lv:Vecmīlgrāvis"/><tag k="wikipedia:ru" v="Вецмилгравис"/></node><node id="1412648728" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:50Z" user="Raitisx" uid="105318" lat="57.0237064" lon="24.1172858"/><node id="1412648732" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:50Z" user="Raitisx" uid="105318" lat="57.0237837" lon="24.1146783"/><node id="1412648733" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0239283" lon="24.1201001"/><node id="1412648734" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0239694" lon="24.1120189"/><node id="1412648735" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0244130" lon="24.1218642"/><node id="1412648741" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0252736" lon="24.1235470"/><node id="1412648742" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0252901" lon="24.1068387"/><node id="1412648745" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0259421" lon="24.0865922"/><node id="1412648749" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0267091" lon="24.1003177"/><node id="1412648750" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0272530" lon="24.0901290"/><node id="1412648753" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0272650" lon="24.1261230"/><node id="1412648754" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0277863" lon="24.0940634"/><node id="1412648755" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0277928" lon="24.0850352"/><node id="1412648760" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0298488" lon="24.1289978"/><node id="1412648766" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0322322" lon="24.0795026"/><node id="1412648767" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0324695" lon="24.1317941"/><node id="1412648768" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0336179" lon="24.1289290"/><node id="1412648769" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0342914" lon="24.1256628"/><node id="1412648770" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0346037" lon="24.1223190"/><node id="1412648771" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0348498" lon="24.1188739"/><node id="1412648772" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0348667" lon="24.0758427"/><node id="1412648775" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0353858" lon="24.1167861"/><node id="1412648783" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0377249" lon="24.1087940"/><node id="1412648786" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0382325" lon="24.0717365"/><node id="1412648787" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0383366" lon="24.1072823"/><node id="1412648788" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0398108" lon="24.1061825"/><node id="1412648789" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0403684" lon="24.1061945"/><node id="1412648792" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0418628" lon="24.1028049"/><node id="1412648793" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0425852" lon="24.0987029"/><node id="1412648798" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0430687" lon="24.0645903"/><node id="1412648799" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0438158" lon="24.0914262"/><node id="1412648807" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0457390" lon="24.0602339"/><node id="1412648809" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0473897" lon="24.0573897"/><node id="1412648814" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:54Z" user="Raitisx" uid="105318" lat="57.0485238" lon="24.0617057"/><node id="1412648815" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:54Z" user="Raitisx" uid="105318" lat="57.0489709" lon="24.0779074"/><node id="1412648819" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:54Z" user="Raitisx" uid="105318" lat="57.0492422" lon="24.0800514"/><node id="1412648821" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:54Z" user="Raitisx" uid="105318" lat="57.0493233" lon="24.0747645"/><node id="1412648822" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:54Z" user="Raitisx" uid="105318" lat="57.0493467" lon="24.0661118"/><node id="1412648828" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:54Z" user="Raitisx" uid="105318" lat="57.0497404" lon="24.0808749"/><node id="1412648829" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:54Z" user="Raitisx" uid="105318" lat="57.0501426" lon="24.0720512"/><node id="1412648830" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:54Z" user="Raitisx" uid="105318" lat="57.0501439" lon="24.0696934"/><node id="939092310" visible="true" version="3" changeset="9125708" timestamp="2011-08-25T22:47:11Z" user="Raitisx" uid="105318" lat="57.0299390" lon="24.0828947"><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></node><node id="2001673384" visible="true" version="2" changeset="27351748" timestamp="2014-12-09T09:08:56Z" user="AkageMuk" uid="2012081" lat="57.0379682" lon="24.1081640"/><node id="1412648777" visible="true" version="2" changeset="13788614" timestamp="2012-11-07T18:35:26Z" user="briedisUNrepshe" uid="780955" lat="57.0365649" lon="24.1126203"/><node id="1940326011" visible="true" version="2" changeset="27418924" timestamp="2014-12-12T11:12:48Z" user="AkageMuk" uid="2012081" lat="57.0454766" lon="24.0884690"/><way id="127683755" visible="true" version="3" changeset="13314024" timestamp="2012-09-30T19:10:18Z" user="iav" uid="80180"><nd ref="1412648789"/><nd ref="1412648792"/><nd ref="1412648793"/><nd ref="1412648799"/><nd ref="1940326011"/><nd ref="1412648828"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></way><way id="127683753" visible="true" version="2" changeset="9316551" timestamp="2011-09-16T14:24:13Z" user="Raitisx" uid="105318"><nd ref="1412648767"/><nd ref="1412648760"/><nd ref="1412648753"/><nd ref="1412648741"/><nd ref="1412648735"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></way><way id="127683754" visible="true" version="2" changeset="9316551" timestamp="2011-09-16T14:24:14Z" user="Raitisx" uid="105318"><nd ref="1412648735"/><nd ref="1412648733"/><nd ref="1412648728"/><nd ref="1412648732"/><nd ref="1412648734"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></way><way id="127683772" visible="true" version="2" changeset="9316551" timestamp="2011-09-16T14:24:15Z" user="Raitisx" uid="105318"><nd ref="1412648734"/><nd ref="1412648742"/><nd ref="1412648749"/><nd ref="1412648754"/><nd ref="1412648750"/><nd ref="1412648745"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></way><way id="127683719" visible="true" version="3" changeset="13788614" timestamp="2012-11-07T18:35:30Z" user="briedisUNrepshe" uid="780955"><nd ref="1412648789"/><nd ref="1412648788"/><nd ref="1412648787"/><nd ref="2001673384"/><nd ref="1412648783"/><nd ref="1412648777"/><nd ref="1412648775"/><nd ref="1412648771"/><nd ref="1412648770"/><nd ref="1412648769"/><nd ref="1412648768"/><nd ref="1412648767"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></way><way id="127683787" visible="true" version="2" changeset="9316551" timestamp="2011-09-16T14:24:16Z" user="Raitisx" uid="105318"><nd ref="1412648809"/><nd ref="1412648814"/><nd ref="1412648822"/><nd ref="1412648830"/><nd ref="1412648829"/><nd ref="1412648821"/><nd ref="1412648815"/><nd ref="1412648819"/><nd ref="1412648828"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></way><way id="80499981" visible="true" version="6" changeset="9316551" timestamp="2011-09-16T14:24:32Z" user="Raitisx" uid="105318"><nd ref="939092112"/><nd ref="1412648798"/><nd ref="1412648807"/><nd ref="1412648809"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></way><way id="80500002" visible="true" version="4" changeset="9316551" timestamp="2011-09-16T14:24:35Z" user="Raitisx" uid="105318"><nd ref="939092112"/><nd ref="1412648786"/><nd ref="1412648772"/><nd ref="1412648766"/><nd ref="939092310"/><nd ref="1412648755"/><nd ref="1412648745"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></way><relation id="1727775" visible="true" version="4" changeset="36231114" timestamp="2015-12-28T22:52:41Z" user="AkageMuk" uid="2012081"><member type="way" ref="127683755" role="outer"/><member type="way" ref="127683719" role="outer"/><member type="way" ref="127683753" role="outer"/><member type="way" ref="127683754" role="outer"/><member type="way" ref="127683772" role="outer"/><member type="way" ref="80500002" role="outer"/><member type="way" ref="80499981" role="outer"/><member type="way" ref="127683787" role="outer"/><member type="node" ref="956004391" role="admin_centre"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="name" v="Vecmīlgrāvis"/><tag k="name:de" v="Alt-Mühlgraben"/><tag k="name:lv" v="Vecmīlgrāvis"/><tag k="name:ru" v="Вецмилгравис"/><tag k="type" v="boundary"/></relation></osm>';
html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map_canvas"></div>


4

相关问题:

第二个问题增加了一个限制条件:

根据每个点相对于C的角度对顶点列表进行排序。您可以使用 atan2(point.y - C.y, point.x - C.x) 找到角度。如果两个或多个顶点具有相同的角度,则距离C更近的顶点应该先出现。

对于一个正多边形,一种选择是按照围绕中心的朝向对顶点进行排序:

for (var i = 0; i < nodes.length; i++) {
  var pt = new google.maps.LatLng(nodes[i].getAttribute("lat"),
                                  nodes[i].getAttribute("lon"));
  path.push(pt);
  var marker = new google.maps.Marker({
    position: pt,
    map: map,
    title: ""+i
  })
  bounds.extend(pt)
}
centerPt = bounds.getCenter();
var centerMark = new google.maps.Marker({map:map, title: "center", position: centerPt})
path = path.sort(sortFunc);
var polygon = new google.maps.Polygon({
  map:map,
  path: path
});

function sortFunc(a,b) {
  var bearA = google.maps.geometry.spherical.computeHeading(centerPt,a);
  var bearB = google.maps.geometry.spherical.computeHeading(centerPt,b);
  console.log(bearA +":"+ bearB);
  return (bearA - bearB);
}

使用您的数据,将一个离群值点留在多边形中间,这似乎没有意义(点编号为1)。

代码片段:

var geocoder;
var map;
var centerPt;

function initialize() {
  var map = new google.maps.Map(
    document.getElementById("map_canvas"), {
      center: new google.maps.LatLng(37.4419, -122.1419),
      zoom: 13,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });
  var xmldata = xmlParse(xmlBoundaryData);
  var nodes = xmldata.getElementsByTagName("node");
  console.log("nodes=" + nodes.length);
  var bounds = new google.maps.LatLngBounds();
  var path = [];
  for (var i = 0; i < nodes.length; i++) {
    var pt = new google.maps.LatLng(nodes[i].getAttribute("lat"),
      nodes[i].getAttribute("lon"));
    path.push(pt);
    var marker = new google.maps.Marker({
      position: pt,
      map: map,
      title: "" + i
    })
    bounds.extend(pt)
  }
  centerPt = bounds.getCenter();
  var centerMark = new google.maps.Marker({
    map: map,
    title: "center",
    position: centerPt
  })
  path = path.sort(sortFunc);
  var polygon = new google.maps.Polygon({
    map: map,
    path: path
  });
  map.fitBounds(bounds);
}

function sortFunc(a, b) {
  var bearA = google.maps.geometry.spherical.computeHeading(centerPt, a);
  var bearB = google.maps.geometry.spherical.computeHeading(centerPt, b);
  console.log(bearA + ":" + bearB);
  return (bearA - bearB);
}
google.maps.event.addDomListener(window, "load", initialize);

function xmlParse(str) {
  if (typeof ActiveXObject != 'undefined' && typeof GetObject != 'undefined') {
    var doc = new ActiveXObject('Microsoft.XMLDOM');
    doc.loadXML(str);
    return doc;
  }

  if (typeof DOMParser != 'undefined') {
    return (new DOMParser()).parseFromString(str, 'text/xml');
  }

  return createElement('div', null);
}
var xmlBoundaryData = '<?xml version="1.0" encoding="UTF-8"?><osm version="0.6" generator="CGImap 0.4.0 (20233 thorn-01.openstreetmap.org)" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/"><node id="939092112" visible="true" version="3" changeset="9125708" timestamp="2011-08-25T22:47:10Z" user="Raitisx" uid="105318" lat="57.0408668" lon="24.0680754"><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></node><node id="956004391" visible="true" version="5" changeset="36231114" timestamp="2015-12-28T22:52:59Z" user="AkageMuk" uid="2012081" lat="57.0299437" lon="24.1089277"><tag k="name" v="Vecmīlgrāvis"/><tag k="name:de" v="Alt-Mühlgraben"/><tag k="name:lv" v="Vecmīlgrāvis"/><tag k="name:ru" v="Вецмилгравис"/><tag k="place" v="suburb"/><tag k="wikipedia" v="lv:Vecmīlgrāvis"/><tag k="wikipedia:ru" v="Вецмилгравис"/></node><node id="1412648728" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:50Z" user="Raitisx" uid="105318" lat="57.0237064" lon="24.1172858"/><node id="1412648732" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:50Z" user="Raitisx" uid="105318" lat="57.0237837" lon="24.1146783"/><node id="1412648733" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0239283" lon="24.1201001"/><node id="1412648734" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0239694" lon="24.1120189"/><node id="1412648735" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0244130" lon="24.1218642"/><node id="1412648741" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0252736" lon="24.1235470"/><node id="1412648742" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0252901" lon="24.1068387"/><node id="1412648745" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0259421" lon="24.0865922"/><node id="1412648749" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0267091" lon="24.1003177"/><node id="1412648750" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0272530" lon="24.0901290"/><node id="1412648753" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0272650" lon="24.1261230"/><node id="1412648754" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0277863" lon="24.0940634"/><node id="1412648755" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0277928" lon="24.0850352"/><node id="1412648760" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:51Z" user="Raitisx" uid="105318" lat="57.0298488" lon="24.1289978"/><node id="1412648766" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0322322" lon="24.0795026"/><node id="1412648767" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0324695" lon="24.1317941"/><node id="1412648768" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0336179" lon="24.1289290"/><node id="1412648769" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0342914" lon="24.1256628"/><node id="1412648770" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0346037" lon="24.1223190"/><node id="1412648771" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0348498" lon="24.1188739"/><node id="1412648772" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0348667" lon="24.0758427"/><node id="1412648775" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0353858" lon="24.1167861"/><node id="1412648783" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0377249" lon="24.1087940"/><node id="1412648786" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:52Z" user="Raitisx" uid="105318" lat="57.0382325" lon="24.0717365"/><node id="1412648787" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0383366" lon="24.1072823"/><node id="1412648788" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0398108" lon="24.1061825"/><node id="1412648789" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0403684" lon="24.1061945"/><node id="1412648792" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0418628" lon="24.1028049"/><node id="1412648793" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0425852" lon="24.0987029"/><node id="1412648798" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0430687" lon="24.0645903"/><node id="1412648799" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0438158" lon="24.0914262"/><node id="1412648807" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0457390" lon="24.0602339"/><node id="1412648809" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:53Z" user="Raitisx" uid="105318" lat="57.0473897" lon="24.0573897"/><node id="1412648814" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:54Z" user="Raitisx" uid="105318" lat="57.0485238" lon="24.0617057"/><node id="1412648815" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:54Z" user="Raitisx" uid="105318" lat="57.0489709" lon="24.0779074"/><node id="1412648819" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:54Z" user="Raitisx" uid="105318" lat="57.0492422" lon="24.0800514"/><node id="1412648821" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:54Z" user="Raitisx" uid="105318" lat="57.0493233" lon="24.0747645"/><node id="1412648822" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:54Z" user="Raitisx" uid="105318" lat="57.0493467" lon="24.0661118"/><node id="1412648828" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:54Z" user="Raitisx" uid="105318" lat="57.0497404" lon="24.0808749"/><node id="1412648829" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:54Z" user="Raitisx" uid="105318" lat="57.0501426" lon="24.0720512"/><node id="1412648830" visible="true" version="1" changeset="9125708" timestamp="2011-08-25T22:45:54Z" user="Raitisx" uid="105318" lat="57.0501439" lon="24.0696934"/><node id="939092310" visible="true" version="3" changeset="9125708" timestamp="2011-08-25T22:47:11Z" user="Raitisx" uid="105318" lat="57.0299390" lon="24.0828947"><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></node><node id="2001673384" visible="true" version="2" changeset="27351748" timestamp="2014-12-09T09:08:56Z" user="AkageMuk" uid="2012081" lat="57.0379682" lon="24.1081640"/><node id="1412648777" visible="true" version="2" changeset="13788614" timestamp="2012-11-07T18:35:26Z" user="briedisUNrepshe" uid="780955" lat="57.0365649" lon="24.1126203"/><node id="1940326011" visible="true" version="2" changeset="27418924" timestamp="2014-12-12T11:12:48Z" user="AkageMuk" uid="2012081" lat="57.0454766" lon="24.0884690"/><way id="127683755" visible="true" version="3" changeset="13314024" timestamp="2012-09-30T19:10:18Z" user="iav" uid="80180"><nd ref="1412648789"/><nd ref="1412648792"/><nd ref="1412648793"/><nd ref="1412648799"/><nd ref="1940326011"/><nd ref="1412648828"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></way><way id="127683753" visible="true" version="2" changeset="9316551" timestamp="2011-09-16T14:24:13Z" user="Raitisx" uid="105318"><nd ref="1412648767"/><nd ref="1412648760"/><nd ref="1412648753"/><nd ref="1412648741"/><nd ref="1412648735"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></way><way id="127683754" visible="true" version="2" changeset="9316551" timestamp="2011-09-16T14:24:14Z" user="Raitisx" uid="105318"><nd ref="1412648735"/><nd ref="1412648733"/><nd ref="1412648728"/><nd ref="1412648732"/><nd ref="1412648734"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></way><way id="127683772" visible="true" version="2" changeset="9316551" timestamp="2011-09-16T14:24:15Z" user="Raitisx" uid="105318"><nd ref="1412648734"/><nd ref="1412648742"/><nd ref="1412648749"/><nd ref="1412648754"/><nd ref="1412648750"/><nd ref="1412648745"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></way><way id="127683719" visible="true" version="3" changeset="13788614" timestamp="2012-11-07T18:35:30Z" user="briedisUNrepshe" uid="780955"><nd ref="1412648789"/><nd ref="1412648788"/><nd ref="1412648787"/><nd ref="2001673384"/><nd ref="1412648783"/><nd ref="1412648777"/><nd ref="1412648775"/><nd ref="1412648771"/><nd ref="1412648770"/><nd ref="1412648769"/><nd ref="1412648768"/><nd ref="1412648767"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></way><way id="127683787" visible="true" version="2" changeset="9316551" timestamp="2011-09-16T14:24:16Z" user="Raitisx" uid="105318"><nd ref="1412648809"/><nd ref="1412648814"/><nd ref="1412648822"/><nd ref="1412648830"/><nd ref="1412648829"/><nd ref="1412648821"/><nd ref="1412648815"/><nd ref="1412648819"/><nd ref="1412648828"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></way><way id="80499981" visible="true" version="6" changeset="9316551" timestamp="2011-09-16T14:24:32Z" user="Raitisx" uid="105318"><nd ref="939092112"/><nd ref="1412648798"/><nd ref="1412648807"/><nd ref="1412648809"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></way><way id="80500002" visible="true" version="4" changeset="9316551" timestamp="2011-09-16T14:24:35Z" user="Raitisx" uid="105318"><nd ref="939092112"/><nd ref="1412648786"/><nd ref="1412648772"/><nd ref="1412648766"/><nd ref="939092310"/><nd ref="1412648755"/><nd ref="1412648745"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="source" v="Rīgas pilsētas teritorijas plānojums"/></way><relation id="1727775" visible="true" version="4" changeset="36231114" timestamp="2015-12-28T22:52:41Z" user="AkageMuk" uid="2012081"><member type="way" ref="127683755" role="outer"/><member type="way" ref="127683719" role="outer"/><member type="way" ref="127683753" role="outer"/><member type="way" ref="127683754" role="outer"/><member type="way" ref="127683772" role="outer"/><member type="way" ref="80500002" role="outer"/><member type="way" ref="80499981" role="outer"/><member type="way" ref="127683787" role="outer"/><member type="node" ref="956004391" role="admin_centre"/><tag k="admin_level" v="10"/><tag k="boundary" v="administrative"/><tag k="name" v="Vecmīlgrāvis"/><tag k="name:de" v="Alt-Mühlgraben"/><tag k="name:lv" v="Vecmīlgrāvis"/><tag k="name:ru" v="Вецмилгравис"/><tag k="type" v="boundary"/></relation></osm>';
html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map_canvas"></div>


1
你的方法可能适用于对任意顶点进行排序。然而,对于OSM,应该使用geocodezip的答案。(边界)OSM中的关系由道路组成。道路包含一个有序节点列表。为了对关系进行排序,必须通过查看它们的第一个和最后一个节点来对道路进行排序。连续的道路将在它们的末尾和开头共享相同的节点。 - scai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接