Skip to content

Instantly share code, notes, and snippets.

@dimisjim
Created June 9, 2024 10:49
Show Gist options
  • Save dimisjim/173c78d01219bc767d1f373e48e6a28a to your computer and use it in GitHub Desktop.
Save dimisjim/173c78d01219bc767d1f373e48e6a28a to your computer and use it in GitHub Desktop.
jsonToCsvConverterGoogleTimeline
#!/usr/bin/python3
import json
import csv
import sys
import datetime
import os
def make_reader(in_json):
# Open location history data
with open(in_json) as f:
json_data = json.load(f)
print("JSON data loaded.")
# Process the JSON data
if 'timelineObjects' in json_data:
timeline_objects = json_data['timelineObjects']
else:
print("Expected 'timelineObjects' in JSON data.")
return
# Process placeVisit entries
for item in timeline_objects:
if 'placeVisit' in item:
visit = item['placeVisit']
location = visit['location']
duration = visit['duration']
try:
dt_start = datetime.datetime.strptime(duration['startTimestamp'], '%Y-%m-%dT%H:%M:%SZ')
except ValueError:
dt_start = datetime.datetime.strptime(duration['startTimestamp'], '%Y-%m-%dT%H:%M:%S.%fZ')
try:
dt_end = datetime.datetime.strptime(duration['endTimestamp'], '%Y-%m-%dT%H:%M:%SZ')
except ValueError:
dt_end = datetime.datetime.strptime(duration['endTimestamp'], '%Y-%m-%dT%H:%M:%S.%fZ')
longitude = location['longitudeE7'] / 10000000.0
latitude = location['latitudeE7'] / 10000000.0
place_id = location['placeId']
address = location.get('address', 'N/A')
location_confidence = location.get('locationConfidence', 'N/A')
yield [dt_start, dt_start.strftime('%Y-%m-%d'), dt_start.strftime('%H:%M:%S'),
dt_end, dt_end.strftime('%Y-%m-%d'), dt_end.strftime('%H:%M:%S'),
longitude, latitude, place_id, address, location_confidence, 'N/A', 'N/A']
# Process activitySegment entries
for item in timeline_objects:
if 'activitySegment' in item:
segment = item['activitySegment']
start_location = segment['startLocation']
end_location = segment['endLocation']
duration = segment['duration']
activity_type = segment['activityType']
distance = segment.get('distance', 0)
try:
dt_start = datetime.datetime.strptime(duration['startTimestamp'], '%Y-%m-%dT%H:%M:%SZ')
except ValueError:
dt_start = datetime.datetime.strptime(duration['startTimestamp'], '%Y-%m-%dT%H:%M:%S.%fZ')
try:
dt_end = datetime.datetime.strptime(duration['endTimestamp'], '%Y-%m-%dT%H:%M:%SZ')
except ValueError:
dt_end = datetime.datetime.strptime(duration['endTimestamp'], '%Y-%m-%dT%H:%M:%S.%fZ')
start_longitude = start_location['longitudeE7'] / 10000000.0
start_latitude = start_location['latitudeE7'] / 10000000.0
end_longitude = end_location['longitudeE7'] / 10000000.0
end_latitude = end_location['latitudeE7'] / 10000000.0
yield [dt_start, dt_start.strftime('%Y-%m-%d'), dt_start.strftime('%H:%M:%S'),
dt_end, dt_end.strftime('%Y-%m-%d'), dt_end.strftime('%H:%M:%S'),
start_longitude, start_latitude, 'N/A', 'N/A', 'N/A', 'N/A',
end_longitude, end_latitude, activity_type, distance]
def getFullPath(inPath):
if not os.path.isabs(inPath):
# we need to set up the absolute path
script_path = os.path.abspath(__file__)
path, file = os.path.split(script_path)
inPath = os.path.join(path, inPath)
return inPath
# Read the Parameters
if len(sys.argv) < 3:
print("Usage: script.py <input_json_file> <output_csv_file>")
sys.exit(1)
in_file = sys.argv[1]
out_file = sys.argv[2]
in_file = getFullPath(in_file)
out_file = getFullPath(out_file)
features = []
# add the Headers
features.append(['Start Datetime', 'Start Date', 'Start Time', 'End Datetime', 'End Date', 'End Time',
'Longitude', 'Latitude', 'Place ID', 'Address', 'Location Confidence',
'Start Longitude', 'Start Latitude', 'End Longitude', 'End Latitude', 'Activity Type', 'Distance'])
print("Reading {0}".format(in_file))
reader = make_reader(in_file)
record_count = 0
for r in reader:
print(r) # Print each record to see what is being processed
features.append(r)
record_count += 1
print(f'Read {record_count} Records')
# write this data
with open(out_file, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerows(features)
print(f'CSV output written to {out_file}')
@alexzmercury
Copy link

alexzmercury commented Jul 16, 2024

Hello,

I needed to download my Google Maps location history, and having it in a .csv would make it a lot more accessible.

I have never used this sort of function; could you let me know via a walkthrough how I can run this so that I may export my files to .csv?

@anselm
Copy link

anselm commented Sep 20, 2024

Works for me - for alexzmercury - basically you have to use a terminal shell window, and you need to have python3 installed - if you're not familiar with that it may be a bit of work but it isn't too hard. Then you download this above script into a file such as "convert.py" and then you can run it from your terminal shell with "python3 convert.py location-history.json myoutput.csv" ...

@rmnpch
Copy link

rmnpch commented Nov 27, 2024

This should only work for the old timeline exports only, right? The ones exported with Takeout, which would include a JSON file for each month of the year, and would include the timelineObjects array, and then divide into placeVisit and activitySegment. However, the new timeline export through the Android Location settings has a very different JSON structure, showing semanticSegments and more than the two children types. How do we parse this new JSON to CSV?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment