Implementing the bike-ride viewer

I recently bought an Android phone and my favorite app is called MyTracks which uses the phone's GPS to record where you've been. I mainly use it to keep a record of my cycling training rides. A similar app popular among cyclists is produced by Strava which integrates with their excellent website. However, their app did not seem to do a good job of acquiring and holding the GPS signal whereas I've had no problems with MyTracks. An added bonus of MyTracks is that it is all open source, giving me a chance to see the innards of a well-made Android app.

A nice feature of MyTracks is that when I finish a ride the data can be easily uploaded to a Google Spreadsheet and/or Fusion Table. I decided to try and write an app that would let a viewer of this site do a search to see where I'd been riding recently.

The goal:

    • Visitors to my site could select from a listbox how many days of track history to load.

    • All the relevant tracks would be loaded and displayed on a map.

    • The map could be interactive (panned/zoomed) and ride stats for each track could be seen (similar to the default maps created by MyTracks)

My data sources (updated by me after each ride):

    • A list of all tracks is stored in a Google Spreadsheet. This spreadsheet also contains summary statistics like ride duration, distance, and a link to a Google Map which displays the track.

    • Each track is stored in a Google Fusion table. These tables store the raw track data but none of the summary info.

I imagine there are many possible ways to achieve this. A few things I considered:

    • JavaScript - FusionTablesLayer on Google Maps.

      • Had the most examples in the API documentation and seemed most appropriate but I could not get the samples to work with Google Sites. There seem to be restrictions in using JavaScript on Google Sites, which is where I wanted to host the page.

      • For example, this site creates nice multi-layer maps and clean HTML, but it can’t be embedded in Sites:

      • A workaround seemed to be to embed a Custom Gadget to the site to wrap the JavaScript. This seems like the most flexible solution but I could not find an existing gadget that worked well and did not want to spend the time learning how to make my own. Also, the examples I did find did not display cleanly (the scripts were blocked by the browser for security reasons)

    • Each Fusion table provides a “Get embeddable link” option ( Maps > Visualize) that can be easily inserted (manually) into a Site (just edit HTML and paste). Using this didn't seem viable because:

      • Fusion Table API doesn't provide access to that code

      • I didn't want to redirect the visitor to another page (that I would dynamically generate which would contain the Fusion Table-provided maps. Some more discussion here.

    • Google Apps Script. This is the approach I finally took. I hadn't used (or really even been aware of) this service before. The concept reminds me of the MS Office VBA tools that I used years ago - it lets you automate your work by providing programmatic access to the application. This service provides an API to control many Google products, and the ones I am using are:

      • UI services to create the forms, respond to user events, display results

      • Maps services to generate a static map image

      • Spreadsheet services to query the spreadsheet data source

      • URLFetch services to query the fusion table data source

      • I also used the "experimental" Apps Script GUI Builder to create some UI elements. I hadn't donehttp://www.google.com/events/io/2011/sessions/enterprise-workflow-with-apps-script.html much Javascript programming so this was also an introduction to that language.

There are some problems with my implementation (mainly, it is slow - a ludicrous 20 seconds to load). And there are a few things that would have made my life easier:

    • I am querying both a spreadsheet and a fusion table because the spreadsheet provides summary info and the table provides a track. It would be nice if the fusion table contained everything I needed. Others agree with me.

    • I must examine each fusion table rather than query the API to return the tables of interest. Again, if MyTracks put all the data in a single table this might be solved.

    • The Google Apps Script documentation is quite poor. The videos and samples are very helpful.

    • When generating the paths on the static map I am running into the limit on allowable path length. I am currently decimating the input until it is below a threshold, but this creates problems, for example the map of my crit race on Sep 5 shows me cutting a lot of corners.

    • It took me too long to find this good Javascript reference. It also took me a while to find that CTRL-SHIFT-J in my chrome browser launches a Javascript interpreter which is very helpful in learning.

    • The online Google Apps Script editor is a real pain to work with. I'm used to my vi/emacs/eclipse keybindings, autocompletion, and general responsiveness - all of which this interface lacks.

    • I don't know the right way to develop in this environment and what I was doing couldn't possible be it. The save-reload page-examine spreadsheet log cycle got very tiresome. Some better testing functions would probably have helped a great deal. A way to dynamically play with the various APIs would also be very helpful.

TODO

    • Create some charts through Chart services API

    • Hopefully MyTracks will augment their Fusion Table output to alleviate some of my issues.