javascript - 使用多个图层中的 kmz 文件更新 Google map

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

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

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

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

这就是噩梦开始的地方。

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

第二个选项是有一个脚本:

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

我无法完成第 1 步。我尝试使用脚本在云端硬盘上解压缩我的 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

这是代码片段:

 $.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 文件。出现一个灰色 block 而不是 map ,或者如果我尝试同时绘制其他图层,其他图层将可见,但 gpx 图层不会。我想这与同源策略有关,因为我指向的 URL 是 Google,而我的 URL 是 Squarespace。

此时,在三种不同的解决方案上已经陷入了死胡同,并且经过多个小时的搜索和尝试,我看不到进一步的内容。我非常感谢有关此问题的任何帮助。由于旅程将于明年 9 月 9 日开始,我的日程安排很紧。再次强调,我们将不胜感激任何提示、建议或评论。

最佳答案

我已经找到解决办法了。

我依赖了多个来源,并以某种方式遇到了 Nesting KMZ files .

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

  1. 我使用this script用于自动将 .kmz 文件从 MotionX-GPS 上传到 Google 云端硬盘中的文件夹。
  2. 我在同一文件夹中有一个 file.kml 文件,该文件有一个嵌套结构,通过 NetworkLink 指向我的 .kmz 文件。
  3. 我有一个Chrome App它在云中运行脚本来同步 Dropbox 和 Google Drive。由于某种原因,Drive 中 file.kml 的永久链接不起作用,但 Dropbox 公共(public)文件夹中的永久链接却很不错。 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);

}

关于javascript - 使用多个图层中的 kmz 文件更新 Google map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25438355/

相关文章:

JavaScript - 拆分多个返回值

javascript - ltrim 与 jQuery?

php - 使用 PHP 和 MySQL 在 Google map 上显示多个标记

javascript - 尝试从外部 php 文件标记数据创建谷歌地图 api 集群

google-apps-script - 谷歌应用脚​​本: Assign zero for empty cells

google-apps-script - Gmail 附加组件 onTriggerFunction 每封电子邮件仅运行一次,即使再次打开电子邮件也是如此

javascript - 将标签和标记对齐在同一垂直线上(Highcharts)

javascript - 阻止访问使用 AJAX 的 php 脚本

javascript - 将 angular-google-maps 中的地址转换为纬度/经度

google-apps-script - Google Calendar App 脚本定期将数据拉入电子表格