The Sports Tracker app for my awesome Nokia N9 is not receiving any updates and doesn’t look like things are going to change any time soon. Recently the development team at Sports Tracker published a status update post and sadly there’s no mention of N9 port at all. It’s really sad considering how incomplete the N9 port is at the moment (horrible GPS positioning, no pedometer to name a few).
Apparently I am not the only one who gets really frustrated with it, and Paoletto even wrote an app named meeTrainer to replace Sports Tracker. However, it doesn’t support the sending of training log to web services at the moment and only output information in a CSV file instead of GPX. While I am still looking for an alternative to Sports Tracker web interface, I decided to write a simple script to convert CSV files generated by meeTrainer to GPX.
While looking for information trying to figure out how does a GPX document looks like, I found this script that pulls data from Sports Tracker. While the project is not relevant to what I am about to achieve, but it still looks interesting though.
The script is written in PHP as the goal was to produce something quick and dirty to get the job done. However, due to my tendency to set unrealistic goals and my inability to code well, it took me much longer than I initially expected.
The data files
Ignoring comments that begins with a hash character, a CSV file generated by meeTrainer is consists of two different data, namely summary and time series log. So the script needs to be able to differentiate two different types of data while reading them line by line. Not wanting to softcode everything, I assume the first and third line (excluding comments) to be the header for each above mentioned type of data.
The summary section consist of general metadata of a workout, which includes start time, total time, etc. To my surprise, it also includes some other data such as age, weight, heart rate zones (which I pre-entered to the application settings). On the other hand, the time series log section records the coordinate, altitude, heart rate etc in the interval of 5 seconds (the interval can be changed in the settings).
The GPX format is surprisingly simple XML document (I was expecting a lot more magic), so I decided to generate one by referring to one of my running data. Basically a GPX file generated by the Sports Tracker web application is much simpler and do not contain as much information. A typical document also consist of two different segments, namely metadata (analogous to summary) and track info (time series log).
It’s coding time!
I haven’t been writing much code recently but I still remember how fun it is while learning clojure. Since PHP 5.3 introduced anonymous function and made it first class citizen, so I decided to write the script in FP-like way and minimize the use of assigning operator as much as possible. Due to my horrible FP skill, the code probably look like crap to most people. I really should stop abusing PHP to do things the way it is not designed for.
However, recursive functions do not really scale in PHP and a big CSV file would kill it (from my past experience working on my research project). Therefore, an uglier workaround also written just in case for bigger files (hardcoded to 1M).
SimpleXML looks nice but after spending some time with it I went back to DOMDocument. As long as it gets the job done, tool doesn’t really matter.
The script is published to bitbucket, and is (poorly-)tested to work (too lazy to write unit-test with it) with CSV generated by meeTrainer 0.2.2. I have not decide which license to use for now but most probably would be BSD License.