【问题标题】:Update Google Maps with kmz files in several layers在多个图层中使用 kmz 文件更新 Google 地图
【发布时间】:2014-08-22 01:31:37
【问题描述】:

明年 9 月我将骑自行车旅行三个月。我将使用装有 Motion-X GPS 应用程序的 iPhone 来记录每天的轨迹。这次旅程旨在引起一些公众的注意,因此我正在使用 Squarespace 建立一个网站,我打算在其中将每天的骑行路线上传到谷歌地图上。我不能花太多时间处理文件或执行手动任务。一切都需要由单个事件触发。每天。到目前为止一切顺利。

Motion-X GPS 记录 GPS 轨迹并允许通过电子邮件共享它们。通过电子邮件发送的文件是一个 gpx 文件和一个 kmz 文件作为单个电子邮件正文中的附件。那是我的触发器。

在我的网站中,我设法加载了 Google 地图(使用 Google Maps Javascript Api)并绘制了航点和 KmlLayers。我还运行了一个 Google Drive 脚本,它自动下载带有 kmz 或 gpx 扩展名的电子邮件附件,并将它们保存在 Google Drive 文件夹中。我还可以通过另一个脚本检索这些文件的永久链接。我想我什至可以弄清楚每次将新的 KMZ 文件添加到文件夹时如何在网站上的 javascript 代码中添加一个新层,但我还没有走那么远。

噩梦从这里开始。

第一种方法。我可以使用 KmlLayer 在我的地图上绘制 KMZ 文件。没问题。但谷歌地图有大约 15-20 层的限制,旅程将持续大约 100 天,每天都会增加一个新层。这意味着当达到限制时,地图上有很多层,并且可能会出现停电。由于会有很多人访问该网站,我不希望这种情况发生。

第二种选择是有一个脚本:

  1. 解压缩 KMZ。
  2. 将解压后的 KML 保存在另一个文件夹中。
  3. 将所有 KML 合并到一个 KML 中。

我无法完成第 1 步。我尝试使用脚本在 Drive 上解压缩我的 KMZ 文件,但我无法完成。这是我测试时使用的代码:

function unZip() {

 var kmzs = DriveApp.getFilesByType('application/vnd.google-earth.kmz');
 while (kmzs.hasNext()){
  var kmz = kmzs.next();
  var zipBlob = kmz.getBlob();
  var unzipBlob = Utilities.unzip(zipBlob);
  var unzipBlobName = unzipBlob[1].getName();

  Logger.log(unzipBlobName);
 }
}

这会在“unzipBlob”上引发错误。除非我找到解压缩然后合并文件的选项,否则此路径到此结束。

我也尝试过 zipextractor,但它无法将 kmz 文件识别为可解压缩文件。我什至将 .kmz 文件重命名为 .zip,但没有成功。

https://github.com/googledrive/zipextractor

第三个选项是绘制 gpx 文件。经过数小时的谷歌搜索,我找到了在谷歌地图上绘制 gpx 文件的链接:

http://www.jacquet80.eu/blog/post/2011/02/Display-GPX-tracks-using-Google-Maps-API

这是代码sn-p:

 $.ajax({
    type: "GET",
    url: "URL to the GPX file",
    dataType: "xml",
    success: function(xml) {
    var points = [];
    var bounds = new google.maps.LatLngBounds ();
    $(xml).find("trkpt").each(function() {
      var lat = $(this).attr("lat");
      var lon = $(this).attr("lon");
      var p = new google.maps.LatLng(lat, lon);
      points.push(p);
      bounds.extend(p);
    });

    var poly = new google.maps.Polyline({
      // use your own style here
      path: points,
      strokeColor: "#FF00AA",
      strokeOpacity: .7,
      strokeWeight: 4
    });

    poly.setMap(map);

    // fit bounds to track
    map.fitBounds(bounds);
   }
   });

但是,我无法使用该代码绘制我的任何 Google Drive gpx 文件。出现灰色块而不是地图,或者如果我尝试同时绘制其他图层,其他图层将可见但 gpx 图层不会。我想这与同源策略有关,因为我指向的 URL 是 Google 而我的是 Squarespace。

此时,在三种不同的解决方案上已经走到了死胡同,经过数小时的搜索和尝试,我看不到更远的地方。我非常感谢有关此问题的任何帮助。自从明年 9 月 9 日旅程开始以来,我的日程安排很紧。同样,任何提示、建议或评论都将不胜感激。

【问题讨论】:

标签: javascript google-maps-api-3 google-apps-script google-drive-api kmz


【解决方案1】:

我找到了解决方案。

我依赖了几个来源,不知何故碰到了Nesting KMZ files

这给了我一个线索。我尝试了不同的文件和选项,但结果如下:

  1. 我使用 this script 自动将 MotionX-GPS 中的 .kmz 文件上传到 Google 驱动器中的文件夹。
  2. 我在同一个文件夹中有一个 file.kml 文件,它有一个嵌套结构,通过 NetworkLink 指向我的 .kmz 文件。
  3. 我有一个Chrome App,它在云中运行一个脚本来同步 Dropbox 和 Google Drive。出于某种原因,Drive 中指向 file.kml 的永久链接不起作用,但 Dropbox 的公共文件夹中的永久链接却很好用。 Google Maps Javascript API 中的 kmlLayer 链接到 Dropbox 中的 file.kml。
  4. 最后,我每小时运行一个独立的 Google 脚本,该脚本将 file.kml 的内容替换为基于驱动器文件夹中存在的任何 .kmz 的 kml 结构。我可以删除、添加或修改名称,但只要 kmz 文件位于我的曲目文件夹中,它们就会嵌套在 file.kml 中。

就是这样。这是我的脚本代码。用您的数据替换大写。可能有一种更简单或更聪明的方法可以做到这一点,但这就是完成工作。

//This function reads kmz files inside an specific folder in Google Drive and fills "file.kml" with a list of Networklinks for those files. The links refer to a mirror in a synced dropbox public folder
function kmlFileSetContent(){
    var contentHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><kml xmlns=\"http://www.opengis.net/kml/2.2\"><Document>"
    var contentFooter ="</Document></kml>";
    var fileHeader = "<NetworkLink> <Link><href>YOUR_DROPBOX_PERMALINK_FOR_PUBLIC_FOLDER";
    var fileFooter = "</href></Link></NetworkLink>"
    var kmzFolder = DriveApp.getFolderById("YOUR_FOLDER_ID");
    var kmzFiles = kmzFolder.getFilesByType('application/vnd.google-earth.kmz');
    while(kmzFiles.hasNext()){
        var kmzFile = kmzFiles.next();
        var fileName = kmzFile.getName();
        var networkLink = fileHeader+fileName+fileFooter;
        var networkLinkAll = networkLinkAll+ networkLink;
    }
    var newContent = contentHeader+networkLinkAll+contentFooter;
    Logger.log(newContent);
    var kmlFile = DriveApp.getFileById("YOUR_FILEKML_ID");
    kmlFile.setContent(newContent);

}

【讨论】:

    猜你喜欢
    • 2012-04-06
    • 1970-01-01
    • 1970-01-01
    • 2015-06-24
    • 2012-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多