谷歌地图JavaScript API - 如何将多边形导出为KML文件?

3
我正在使用Google Maps JavaScript API 根据用户输入创建多边形(不使用Drawing库,只使用 v3)。我想将这些要素导出为KML格式。然而,在Javascript API中似乎没有我能够完成此操作的工具。

我知道Maps Engine Lite有一个“导出到KML”功能。

是否有某个Google库可以实现导出到KML的功能?我看到一些解决方案是将多边形的属性发送到文本区域中,并用它来生成KML,但我更喜欢使用现有的库而不是制作自己的KML文件。

1个回答

6

Blitz GMap编辑器允许您导出KML文件(使用绘图管理器创建和编辑它们,但您也可以使用自己的代码)。

示例

Blitz GMap编辑器导出KML代码。依赖于xmlwriter.js

this.toKML = function() {
  var result = mapToObject();
  var xw = new XMLWriter('UTF-8');
  xw.formatting = 'indented'; //add indentation and newlines
  xw.indentChar = ' '; //indent with spaces
  xw.indentation = 2; //add 2 spaces per level

  xw.writeStartDocument();
  xw.writeStartElement('kml');
  xw.writeAttributeString("xmlns", "http://www.opengis.net/kml/2.2");
  xw.writeStartElement('Document');

  for (var i = 0; i < result.overlays.length; i++) {
    xw.writeStartElement('Placemark');
    xw.writeStartElement('name');
    xw.writeCDATA(result.overlays[i].title);
    xw.writeEndElement();
    xw.writeStartElement('description');
    xw.writeCDATA(result.overlays[i].content);
    xw.writeEndElement();
    if (result.overlays[i].type == "marker") {

      xw.writeStartElement('Point');
      xw.writeElementString('extrude', '1');
      xw.writeElementString('altitudeMode', 'relativeToGround');
      xw.writeElementString('coordinates', result.overlays[i].position.lng.toString() + "," + result.overlays[i].position.lat.toString() + ",0");
      xw.writeEndElement();

    } else if (result.overlays[i].type == "polygon" || result.overlays[i].type == "rectangle" || result.overlays[i].type == "circle") {
      xw.writeStartElement('Polygon');
      xw.writeElementString('extrude', '1');
      xw.writeElementString('altitudeMode', 'relativeToGround');

      if (result.overlays[i].type == "rectangle") {
        //its a polygon
        xw.writeStartElement('outerBoundaryIs');
        xw.writeStartElement('LinearRing');
        xw.writeStartElement("coordinates");
        xw.writeString(result.overlays[i].bounds.sw.lng + "," + result.overlays[i].bounds.sw.lat + ",0");
        xw.writeString(result.overlays[i].bounds.ne.lng + "," + result.overlays[i].bounds.sw.lat + ",0");
        xw.writeString(result.overlays[i].bounds.ne.lng + "," + result.overlays[i].bounds.ne.lat + ",0");
        xw.writeString(result.overlays[i].bounds.sw.lng + "," + result.overlays[i].bounds.ne.lat + ",0");
        xw.writeEndElement();
        xw.writeEndElement();
        xw.writeEndElement();
      }
      if (result.overlays[i].type == "circle") {
        //its a polygon, approximate a circle by a circular 64 sided polygon.
        xw.writeStartElement('outerBoundaryIs');
        xw.writeStartElement('LinearRing');
        xw.writeStartElement("coordinates");
        var d2r = Math.PI / 180; // degrees to radians 
        var r2d = 180 / Math.PI; // radians to degrees 
        var earthsradius = 6378137; // 6378137 is the radius of the earth in meters
        var dir = 1; // clockwise

        var points = 64;

        // find the raidus in lat/lon 
        var rlat = (result.overlays[i].radius / earthsradius) * r2d;
        var rlng = rlat / Math.cos(result.overlays[i].center.lat * d2r);

        var extp = new Array();
        if (dir == 1) {
          var start = 0;
          var end = points + 1
        } // one extra here makes sure we connect the line
        else {
          var start = points + 1;
          var end = 0
        }
        for (var j = start;
          (dir == 1 ? j < end : j > end); j = j + dir) {
          var theta = Math.PI * (j / (points / 2));
          ey = result.overlays[i].center.lng + (rlng * Math.cos(theta)); // center a + radius x * cos(theta) 
          ex = result.overlays[i].center.lat + (rlat * Math.sin(theta)); // center b + radius y * sin(theta) 
          xw.writeString(ey + "," + ex + ",0");
        }
        xw.writeEndElement();
        xw.writeEndElement();
        xw.writeEndElement();
      } else {
        for (var j = 0; j < result.overlays[i].paths.length; j++) {
          if (j == 0) {
            xw.writeStartElement('outerBoundaryIs');
          } else {
            xw.writeStartElement('innerBoundaryIs');
          }
          xw.writeStartElement('LinearRing');
          xw.writeStartElement("coordinates");
          for (var k = 0; k < result.overlays[i].paths[j].length; k++) {
            xw.writeString(result.overlays[i].paths[j][k].lng + "," + result.overlays[i].paths[j][k].lat + ",0");
          }
          xw.writeEndElement();
          xw.writeEndElement();
          xw.writeEndElement();
        }
      }
      xw.writeEndElement();

    } else if (result.overlays[i].type == "polyline") {
      xw.writeStartElement('LineString');
      xw.writeElementString('extrude', '1');
      xw.writeElementString('altitudeMode', 'relativeToGround');
      xw.writeStartElement("coordinates");
      for (var j = 0; j < result.overlays[i].path.length; j++) {
        xw.writeString(result.overlays[i].path[j].lng + "," + result.overlays[i].path[j].lat + ",0");
      }
      xw.writeEndElement();
      xw.writeEndElement();

    }

    xw.writeEndElement(); // END PlaceMarker
  }

  xw.writeEndElement();
  xw.writeEndElement();
  xw.writeEndDocument();

  var xml = xw.flush(); //generate the xml string
  xw.close(); //clean the writer
  xw = undefined; //don't let visitors use it, it's closed
  //set the xml
  document.getElementById('kmlString').value = xml;
}

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