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.)