56

我创建了一个 hello world 程序来加载本地 kml 文件(借用自 google 的文档):

var ctaLayer = new google.maps.KmlLayer("http://localhost:8080/kml/cta.kml");

这不起作用(没有加载任何内容)。

但是,当我将该行更改为:

  var ctaLayer = new google.maps.KmlLayer("http://gmaps-samples.googlecode.com/svn/trunk/ggeoxml/cta.kml");

它正确加载。两个 kml 文件是相同的。自己上菜时,我需要做什么才能加载它?(我尝试了绝对路径和相对路径,我知道我使用的路径是正确的......)

我还在我的应用服务器的配置文件中添加了正确的 mime 类型:

<mime-mapping>
    <extension>kml</extension>
<mime-type>application/vnd.google-earth.kml+xml</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>kmz</extension>
    <mime-type>application/vnd.google-earth.kmz</mime-type>
</mime-mapping>

但它仍然没有加载。

我在谷歌的文档中找到了这个:

Google Maps API 支持用于显示地理信息的 KML 和 GeoRSS 数据格式。这些数据格式使用 KmlLayer 对象显示在地图上,其构造函数采用可公开访问的 KML 或 GeoRSS 文件的 URL。

所以我想如果不从可公开访问的 url 提供 kml,我想我要做的事情是不可能的......除非有人可以证明不是这样

4

4 回答 4

61

无法访问 KML,因为它位于您的本地计算机上,而 google 无法访问它,因为它不知道如何访问 localhost:8080

于 2010-08-18T18:35:02.670 回答
42

不幸的是,您不能使用“localhost”。你有两个选择:

  1. 将 kml 放在公开可用的域上。(如果谷歌无法访问它,它将无法工作)
  2. 使用geoxml3,它基本上可以完成谷歌的工作,但允许您自己下载和托管解析器JS文件。它将允许您加载 LOCALHOST KML 并为您解析它(可通过 JSON 访问的对象)(http://code.google.com/p/geoxml3/)。

对于那些从事国防合同和处理敏感信息的人来说,选择#1 可能不是一个选项,因为 kml 在后台发送到谷歌并呈现在地图上。

于 2010-10-08T13:55:24.013 回答
18

此网站display-kml.appspot.com要求您将整个 KML 文件复制/粘贴到网站中。或者,您可以使用Dropbox通过您的公共文件夹托管 KML 文件。在公共 Dropbox 文件夹中,有一个右键单击上下文菜单,可让您复制 URL。

更新:

apppot 网站有不稳定的历史。截至 2019 年 1 月,该网站似乎正在运行。

参考:
  1. http://display-kml.appspot.com/
  2. https://www.dropbox.com/
于 2011-10-18T15:08:09.740 回答
1

当然,Google Maps KmlLayer 专为您将数据发送给他们而设计。 https://developers.google.com/maps/documentation/javascript/kml

看看下面的日志。

//console
var src = 'https://developers.google.com/maps/documentation/javascript/examples/kml/westcampus.kml';

var kmlLayer = new google.maps.KmlLayer(src, {
  suppressInfoWindows: true,
  preserveViewport: false,
  map: your_gmap_object
});

创建Marker、Polygon都是浏览器端解析和渲染

正如您从下一个网络日志中看到的那样,KmlLayer 类将源 URL 发送到 Google Server以对其进行解析并(在它们的末尾做一些事情)并将解析的结果发送回您的浏览器进行渲染。

//REQUEST from browser

https://maps.googleapis.com/maps/api/js/KmlOverlayService.GetOverlays?1shttps%3A%2F%2Fdevelopers.google.com%2Fmaps%2Fdocumentation%2Fjavascript%2Fexamples%2Fkml%2Fwestcampus.kml&callback=_xdc_._lidt3k&key=AIzaSyBeLTP20qMgxsQFz1mwLlzNuhrS5xD_a_U&token=103685

//RESPONSE from google server

/**/_xdc_._lidt3k && _xdc_._lidt3k( [0,"kml:cXOw0bjKUSmlnTN2l67v0Sai6WfXhSSWuyNaDD0mAzh6xfi2fYnBo78Y2Eg","|ks:;dc:tg;ts:51385071|kv:3|api:3",...
["KmlFile"],[[37.423017,-122.0927],[37.424194,-122.091498]],[["g74cf1503d602f2e5"],["g58e8cf8fd6da8d29"],["ge39d22e72437b02e"]],1,[["client","2"]],-21505,[["ks",";dc:tg;ts:51385071"],["kv","3"],["api","3"]]] )

正如上面提到的@capdragon,最好自己解析KML

更新

这是紧凑的 KML 解析器代码。这仅适用于 google.maps 标记和多边形。

html

<input type='file' accept=".kml,.kmz" onchange="fileChanged()">

脚本,我使用了打字稿,但它与 javascript 几乎相同

  file: any
  fileChanged(e) {
    this.file = e.target.files[0]
    this.parseDocument(this.file)
  }
  parseDocument(file) {
    let fileReader = new FileReader()
    fileReader.onload = async (e: any) => {
      let result = await this.extractGoogleCoords(e.target.result)

      //CREATE MARKER OR POLYGON WITH result here
      console.log(result)

    }
    fileReader.readAsText(file)
  }

  async extractGoogleCoords(plainText) {
    let parser = new DOMParser()
    let xmlDoc = parser.parseFromString(plainText, "text/xml")
    let googlePolygons = []
    let googleMarkers = []

    if (xmlDoc.documentElement.nodeName == "kml") {

      for (const item of xmlDoc.getElementsByTagName('Placemark') as any) {
        let placeMarkName = item.getElementsByTagName('name')[0].childNodes[0].nodeValue.trim()
        let polygons = item.getElementsByTagName('Polygon')
        let markers = item.getElementsByTagName('Point')

        /** POLYGONS PARSE **/        
        for (const polygon of polygons) {
          let coords = polygon.getElementsByTagName('coordinates')[0].childNodes[0].nodeValue.trim()
          let points = coords.split(" ")

          let googlePolygonsPaths = []
          for (const point of points) {
            let coord = point.split(",")
            googlePolygonsPaths.push({ lat: +coord[1], lng: +coord[0] })
          }
          googlePolygons.push(googlePolygonsPaths)
        }

        /** MARKER PARSE **/    
        for (const marker of markers) {
          var coords = marker.getElementsByTagName('coordinates')[0].childNodes[0].nodeValue.trim()
          let coord = coords.split(",")
          googleMarkers.push({ lat: +coord[1], lng: +coord[0] })
        }
      }
    } else {
      throw "error while parsing"
    }

    return { markers: googleMarkers, polygons: googlePolygons }

  }

输出

markers: Array(3)
0: {lat: 37.42390182131783, lng: -122.0914977709329}
...

polygons: Array(1)
0: Array(88)
0: {lat: -37.79825999283025, lng: 144.9165994157198}
...
于 2018-11-07T01:59:05.940 回答