Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
This script converts JSON file obtained from Moves Export service into gpx files.
This is a simple code to convert Moves JSON file to gpx files.
Each day in JSON file will be converted into different gpx file,
one file for a single day.
If you think this behavior annoying, please feel free to rewrite the code:D
Usage: 1. Get JSON file from:
2. The file you've got may have some errors to be a valid JSON file,
so do some surgery to the file.
I did `s/,\+/,/g` in Vim to delete successive commas,
and `s/}{/},{/g` to add a comma between braces.
3. Feed the file to this code as an argument.
4. You get .gpx files! (hopefully.)
import argparse
import json
import datetime
from xml.dom.minidom import parseString
outputfilename = '{date}-moves-trackpoints.gpx'
# Prepare to convert Moves-style time format string.
timefmtstr = "%Y%m%dT%H%M%SZ" # Could not use %Z, so I had to set tz myself.
class UTC(datetime.tzinfo): #
def utcoffset(self, dt): return datetime.timedelta(0)
def tzname(self, dt): return "UTC"
def dst(self, dt): return datetime.timedelta(0)
utc = UTC()
def strptime(timestr):
return datetime.datetime.strptime(timestr, timefmtstr).replace(tzinfo=utc)
# A function to convert location to gpx trkpt string.
writetimefmtstr = "%FT%TZ"
def trkptstr(datetime_, lon, lat):
timestr = datetime_.strftime(writetimefmtstr)
writestr = '<trkpt lat="{lat}" lon="{lon}">'.format(lat=lat, lon=lon)
writestr += '<time>{timestr}</time></trkpt>'.format(timestr=timestr)
return writestr
def json2gpx(inputfile):
# Load json file.
locdata = json.loads(; # If fail, check validity of json file.
# 2013-11-01 Moves Export service has changed its output form, so I had to add
# the following line.
locdata = locdata['export']
# Dissolve the json file, and obtain all the lon-lat data.
# Moves data format has several days in a huge single array.
# Each item represents single day, so first of all,
# create a loop in which only single day exists.
for singleday in locdata:
# Each day has "date" and "segements".
# Here, we use "date" to create filename of GPX file.
date = datetime.datetime.strptime(singleday['date'], '%Y%m%d')
print('Processing: ' + date.strftime('%F'))
# Prepare output string.
outputstr = '<?xml version="1.0" encoding="UTF-8" standalone="no" ?>\n'
outputstr += '<gpx xmlns=""><trk><name>{date} Trackpoints from Moves Activity Tracker</name><trkseg>'.format(date=date.strftime("%F"))
# We use "segments" to obtain location data.
# each "segments" has several segment data, so create a loop for it.
# Sometimes, segments is 'null', so look for it.
if not singleday['segments']: continue
for segment in singleday['segments']:
# Segments have several "type"s. Each types contain a location info
# in a different way, so make conditions of them.
if segment['type'] == 'place':
# "place" type has a single location info, and start & end time.
# "place" has more infos than these, but I don't need them.
# If you are interested, please read the json file you've got.
starttime = strptime(segment['startTime'])
endtime = strptime(segment['endTime'])
location = segment['place']['location']
lon, lat = location['lon'], location['lat']
assert type(lon)==float and type(lat)==float
# print starttime, endtime, lon, lat # for debug.
outputstr += trkptstr(starttime, lon, lat)
outputstr += trkptstr(endtime, lon, lat)
elif segment['type'] == 'move':
# "move" type has "activities", which is an array of activities.
# An activity has "trackPoints", which is an array of time and loc.
for activity in segment['activities']:
for location in activity['trackPoints']:
time = strptime(location['time'])
lon, lat = location['lon'], location['lat']
assert type(lon)==float and type(lat)==float
# print time, lon, lat # for debug.
outputstr += trkptstr(time, lon, lat)
outputstr += '</trkseg></trk></gpx>'
# Basically you don't need to prettify an xml, but just in case.
outputstr = parseString(outputstr).toprettyxml(encoding="utf-8")
# Export to a file.
outputfile = open(outputfilename.format(date=date.strftime("%F")), 'w')
if __name__ == '__main__':
# create the parser
parser = argparse.ArgumentParser(
description='Convert Moves JSON file to gpx files.')
parser.add_argument('inputfile', type=argparse.FileType('r'))
args = parser.parse_args()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment