2

Next september I will be travelling during three months by bike. I will use an iPhone with Motion-X GPS app instaled to record everyday's track. The journey intends to draw some public attention thus I'm building a website with Squarespace where I intend to upload every day cycling strech on a Google map. I can't spend much time processing files or performing manual tasks. Everything needs to be triggered by a single event. Everyday. So far so good.

Motion-X GPS records GPS tracks and allows sharing them via email. The files sent by email are one gpx file and one kmz file as attachments in the body of a single email. That's my trigger.

In my website I have managed to load a Google Map (with the Google Maps Javascript Api) and plot waypoints and KmlLayers. I also have a Google Drive Script running that downloads the email attachments with kmz or gpx extensions automatically and saves them in a Google Drive folder. I can also retrieve the permalinks to those files through another Script. I guess I even could figure out how to add a new layer to my javascript code on the site everytime a new KMZ file is added to the folder, but I haven't gone that far.

Here's where the nightmare starts.

First approach. I'm able to plot a KMZ file on my map with KmlLayer. No problem with that. But Google Maps have a limit of around 15-20 layers and the journey is goint to last around 100 days, adding a new layer every day. That means many layers and probably a blackout on the map when the limit is reached. Since many people will be visiting the site, I don't want that to happen.

The second option would be to have a script that:

  1. Unzips the KMZ.
  2. Saves the unzipped KML in another folder.
  3. Merges all the KML's in one single KML.

I can't get over step 1. I've tried to unzip my KMZ files on Drive with a Script but I'm unable. This is the code I used when testing:

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);
 }
}

This throws an error on "unzipBlob". This path ends here unless I find the option to unzip and then to merge files.

I've also tried zipextractor, but it doesn't recognize kmz files as unzipable. I even renamed the .kmz files as .zip with no sucess.

https://github.com/googledrive/zipextractor

Third option would be to plot the gpx file. After hours of googling I found this link to plot a gpx file on a Google Map:

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

This is the code snippet:

 $.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);
   }
   });

BUT, I've been unable to plot any of my Google Drive gpx files with that code. A grey block appears instead of a map, or if I try to plot other layers at the same time, the other layers will be visible but the gpx layer wont. I guess this has something to do with the Same-origin policy since the URL I'm pointing at is Google and mine is Squarespace.

At this point, having reached a dead end on the three different solutions, and after many hours of search and try, I can't see further. I would really appreciate any help regarding this issue. I have a tight schedule since the journey starts next Sept. 9. Again, any hint, advice or comment would be much appreciated.

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Diego
  • 139
  • 1
  • 8
  • Still working on this, I've found this that is related: http://stackoverflow.com/questions/2109555/nesting-kmz-files – Diego Aug 22 '14 at 08:31

1 Answers1

2

I've found a solution.

I've relied on several sources and somehow bumped into Nesting KMZ files.

That gave me a clue. I tried with different files and options but the result is the following:

  1. I use this script for automatically uploading .kmz files from MotionX-GPS to a folder in Google drive.
  2. I have a file.kml file in the same folder that has a nested structure pointing to my .kmz files with NetworkLink.
  3. I have a Chrome App that runs a script in the cloud to sync Dropbox and Google Drive. For some reason, the permalink to file.kml in Drive didn't work, but the one in the public folder of Dropbox does it sweet. The kmlLayer in Google Maps Javascript API links to the file.kml in dropbox.
  4. Finally, I run a stand alone Google script every hour that replaces the content of file.kml with a kml structure based on whatever .kmz are present in my Drive Folder. I can erase, add or modify names but, as long as the kmz files are inside my tracks folder, they will be nested in file.kml.

And that's it. Here's my script code. Replace Upper Cases with your data. Probably there's an easier or more clever way to do it, but this get's the work done.

//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);

}
Community
  • 1
  • 1
Diego
  • 139
  • 1
  • 8