How I converted Google MyTrack kmz/kml to Strava gpx (using Linux and GPSBabel).

My dad asked me to convert a bunch (somewhere between 10 and 100) of old rides he saved in Google MyTracks back in ~2011, to something that Strava can understand. The problem is MyTracks does not save per trackpoint timestamp info, just the trackpoints themselves, so Strava apparently can’t calculate its own segments etc., and as a result, will drop you an error when you try to upload a .gpx or .fit file you convert a MyTracks file to.

The solution is to somehow add timestamps to each trackpoint during conversion to .gpx.

As this needed a bit of tweaking I captured (ugly as it is) what I did so I (or you, reading this) can reproduce it later. This is basically a bunch of raw bash commands and I didn’t do anything to eyecandify them, sorry for that; I basically copypaste all my steps here, minus the reading and trial-and-error bit of course.

Get the kml source files and extract workout date/time info

Step 1. Input

My input was a bunch of .kmz files in a folder. These are actually zip files containing some images that nobody needs, plus a .kml file (without, sadly, trackpoint timestamps) named doc.kml.

Step 2. Rename .kmz files and extract them

(Sorry, I’m a pedantofile)

for i in *;do 
 mv "$i" "$i".zip;
 unzip "$i".zip -d "$i"_out;
done

(Step 3. We can remove the zip files, don’t need them anymore)

rm *.zip

Step 4. Move the kml files to one level up

for i in *; do 
 cp "$i"/doc.kml "$i"-doc.kml; 
done

(Step 5. We can remove the folders, don’t need them anymore)

rm -rf *.zip_out

Step 6. Get the datetime and remove dashes and spaces

We’ll need this for .gpx generation.

for file in *.kml; do 
 KMLDATETIME=`echo "$file" |awk '{print $1,substr($2,1,4)}'|sed 's/[- ]//g'`
 echo $KMLDATETIME
done

Convert kml to gpx and fake trackpoint timestamps

We’ll use the wonderful GPSBabel tool to convert our kmls to gpx. It is a tool that you can use to convert all kinds of gps file formats (there are many) to each other.

The tool is actually quite powerful, it can be used to tweak the gpx outut quite a bit (well beyond what we need it for now). We’ll need this to fake the missing trackpoint timestamps.

Step 7. Install the wonderful GPSBabel tool

sudo apt install gpsbabel

Step 8. Get average speeds from workouts and then think a little

To start with the conversion, I had to get an idea on the average speeds from the workouts:

for file in *.kml; do 
 KMLAVGSPEED=`grep "Average\ Moving\ Speed" "$file" |sed 's/.*Average\ Moving\ Speed\:\ //' |sed 's/\ km\/h.*//'`
 echo $KMLAVGSPEED
done

Here, I had a choice to make.

I could start calculating avg speed vs. number of timestamps in the file, start and end times, etc., and work with that… but while I understand on a concept level how I’d be doing this, I eventually decided to look at a kind of “super-average” of all workouts, and make a “good enough” guess to save some headache for myself. Using the very scientific “eyeball and calculator” method I saw that my dad’s “super-average” was around 19 kmph; I have to fake something close to this in the gpx files.

I could use GPSBabel’s “faketime” parameter to fake timestamps for each trackpoint. Using trial/error I calculated that ~19kmph comes to a “+6” value for these files, ie. adding 6 seconds per trackpoint.

(This is a very rudimentary value with multiple points of failure: trackpoints might be missing, more/less frequent, plus the super-average wasn’t exact, or eg. distance wighted in the first place. But luckily here the distance is more important than the speed, so in the interest of time and sanity I’m letting it go. I’m also guessing that the freuency of trackpoints for any given MyTracks kml will differ based on the phone, gps conditions, etc. So, do your own calculations, ymmv.)

From the GPSBabel documentation, the gpsbabel format I need to use is this:

gpsbabel -i kml -f [input file].kml -x track,faketime=f[timestamp]+[+seconds per trackpoint] -o gpx -F [output file].gpx

Step 9. The final gpsbabel command in my case

for file in *.kml; do 
 KMLDATETIME=`echo "$file" |awk '{print $1,substr($2,1,4)}'|sed 's/[- ]//g'`
 FAKETIMEIN=f"$KMLDATETIME"00+6
 gpsbabel -i kml -f "$file" -x track,faketime=$FAKETIMEIN -o gpx -F "$file"_strava.gpx
done

Step 10. Zip the outcome and send to dad for upload to Strava

The output is not nice, it’s a bunch of filenames with a .kmz.zip_out-doc.kml_strava.gpx extension, but who cares. Also, to stress again, the speeds will be quite random, but once again, who cares. (I hope not dad!)

In case this is not precise enough

If you’d prefer precision over automation, you can use another wonderful, but manual tool: the GOTOES Utilities for Strava site. This site can calculate and fake the trackpoint timestamps based on an average speed you enter, but you’ll have to upload the files and indicate the average speed manually.

For this though, it’s also easy to create a little ugly script to support your manual uplads (extracting the necessary info into ugly.html in this case):

for file in *.kml; do 
 KMLDATETIMEORIG=`echo "$file" |awk '{print $1,substr($2,1,4)}'`
 KMLDATETIME=`echo "$file" |awk '{print $1,substr($2,1,4)}'|sed 's/[- ]//g'`
 KMLAVGSPEED=`grep "Average\ Moving\ Speed" "$file" |sed 's/.*Average\ Moving\ Speed\:\ //' |sed 's/\ km\/h.*//'`
 FAKETIMEIN=f"$KMLDATETIME"00+6
 echo "$file" "<br />" >>ugly.html
 echo "Datum (YYYY-MM-DD hhmm): " $KMLDATETIMEORIG "<br />" >>ugly.html
 echo "Atlagsebesseg (km/h): "$KMLAVGSPEED "<br />" >>ugly.html
 echo "---- <br /><br />" >>ugly.html
done

So there.

As I used to say back in the days when I actually did this for a living (and knew what I was doing), mocskos ronda egy hack, de működik (or: “it’s an ugly fuck of a dirt hack but it does the job.)

Leave a Reply

Your email address will not be published. Required fields are marked *