我创建了一个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文件都是相同的。在自己提供服务时,我需要做些什么来加载它? (我尝试了绝对和相对路径,我知道我使用的路径是正确的......)
我还在我的appserver的配置文件中添加了正确的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的docs中找到了这个:
Google Maps API支持用于显示地理信息的KML和GeoRSS数据格式。这些数据格式使用KmlLayer对象显示在地图上,该对象的构造函数采用可公开访问的KML或GeoRSS文件的URL。
所以我想我想要做的就是不可以在没有公开访问网址的情况下提供kml ...除非有人能证明不这样做
答案 0 :(得分:54)
KML无法访问,因为它位于您的本地计算机上而谷歌无法访问,因为它不知道如何访问localhost:8080
答案 1 :(得分:38)
不幸的是你不能使用“localhost”。你有两个选择:
选择#1可能不适合那些从事国防合同并处理敏感信息的人,因为kml会在后台发送到谷歌并在地图上呈现。
答案 2 :(得分:17)
此网站display-kml.appspot.com要求您将整个KML文件复制/粘贴到网站中。或者,您可以使用Dropbox使用公用文件夹托管KML文件。在公共Dropbox文件夹中,有一个右键单击上下文菜单,允许您复制URL。
更新:appspot网站有不稳定的历史。截至2019年1月,该网站似乎正在运作。
参考文献:答案 3 :(得分: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
});
创建标记,多边形,它们都是浏览器端的解析和渲染。
从下一个网络日志中可以看到, 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}
...