Last active
November 13, 2024 05:29
-
-
Save devdattaT/c9dcae2107622215ff2e798dd185087e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json | |
import csv | |
import sys | |
from datetime import datetime | |
import os | |
def has_keys(dictionary, keys): | |
return all(key in dictionary for key in keys) | |
def make_reader(in_json): | |
# Open location history data | |
json_data = json.loads(open(in_json).read()) | |
#Will read the following keys | |
keys_to_check = ['timestamp', 'longitudeE7', 'latitudeE7', 'accuracy'] | |
# Get the easy fields | |
for item in json_data['locations']: | |
if has_keys(item, keys_to_check): | |
timestamp = item['timestamp'] | |
if ('.' in timestamp): | |
date = datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%fZ').date() | |
else: | |
date = datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ').date() | |
tm = timestamp.split('T')[1].split('Z')[0] | |
longitude = item['longitudeE7']/10000000.0 | |
latitude = item['latitudeE7']/10000000.0 | |
accuracy = item['accuracy'] | |
yield [date, tm, longitude, latitude, accuracy] | |
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 | |
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(['Date', 'Time', 'Longitude', 'Latitude', 'Accuracy']) | |
print("Reading {0}".format(in_file)) | |
reader = make_reader(in_file) | |
for r in reader: | |
features.append(r) | |
print('Read {0} Records'.format(len(features)-1)) | |
# write this data | |
with open(out_file, 'w', newline='')as f: | |
writer = csv.writer(f) | |
writer.writerows(features) |
I made a minor adjustment using ChatGPT (not a coder at all, so please check) and it worked!
please replace path in/out with the relevant details.. the file that was released was kepler compatible for me! Maybe someone with more coding experience can adjust, improve it?
import json
import csv
from datetime import datetime
import os
def make_reader(in_json):
# Open location history data
with open(in_json, 'r') as file:
json_data = json.load(file)
for item in json_data:
end_time = item.get('endTime', 'Unknown')
start_time = item.get('startTime', 'Unknown')
if '.' in end_time:
end_date = datetime.strptime(end_time, '%Y-%m-%dT%H:%M:%S.%f%z').date()
else:
end_date = datetime.strptime(end_time, '%Y-%m-%dT%H:%M:%S%z').date()
end_tm = end_time.split('T')[1].split('+')[0]
if '.' in start_time:
start_date = datetime.strptime(start_time, '%Y-%m-%dT%H:%M:%S.%f%z').date()
else:
start_date = datetime.strptime(start_time, '%Y-%m-%dT%H:%M:%S%z').date()
start_tm = start_time.split('T')[1].split('+')[0]
# Extract location details
location = 'Unknown Location'
lat, lon = None, None
if 'visit' in item:
placeLocation = item['visit'].get('topCandidate', {}).get('placeLocation', 'Unknown')
if 'geo:' in placeLocation:
location = placeLocation.split('geo:')[1]
lat, lon = location.split(',')
elif 'activity' in item:
placeLocation = item['activity'].get('start', 'Unknown')
if 'geo:' in placeLocation:
location = placeLocation.split('geo:')[1]
lat, lon = location.split(',')
yield [end_date, end_tm, start_date, start_tm, lat, lon]
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
# Hard-coded file paths
in_file = 'path/to/your/input.json' # Replace with your input JSON file path
out_file = 'path/to/your/output.csv' # Replace with your desired output CSV file path
in_file = getFullPath(in_file)
out_file = getFullPath(out_file)
features = []
# add the Headers
features.append(['End Date', 'End Time', 'Start Date', 'Start Time', 'Latitude', 'Longitude'])
print("Reading {0}".format(in_file))
reader = make_reader(in_file)
for r in reader:
features.append(r)
print('Read {0} Records'.format(len(features) - 1))
# write this data
with open(out_file, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerows(features)
@dinilj007 - I do a decent amount of python coding but for small things like this I use GPT also. Yours didn't work for my timeline export, so I fed GPT a sample of some of mine, followed by your script and the error message and it gave me a working script. Took less than 2 mins, which is why I didn't figure it out myself haha:
import json
import csv
from datetime import datetime
import os
def make_reader(in_json):
# Open location history data
with open(in_json, 'r') as file:
json_data = json.load(file)
# Access the "semanticSegments" list
segments = json_data.get("semanticSegments", [])
for segment in segments:
start_time = segment.get('startTime', 'Unknown')
end_time = segment.get('endTime', 'Unknown')
# Process the start and end times
if start_time != 'Unknown':
if '.' in start_time:
start_date = datetime.strptime(start_time, '%Y-%m-%dT%H:%M:%S.%f%z').date()
else:
start_date = datetime.strptime(start_time, '%Y-%m-%dT%H:%M:%S%z').date()
start_tm = start_time.split('T')[1].split('-')[0]
else:
start_date = 'Unknown'
start_tm = 'Unknown'
if end_time != 'Unknown':
if '.' in end_time:
end_date = datetime.strptime(end_time, '%Y-%m-%dT%H:%M:%S.%f%z').date()
else:
end_date = datetime.strptime(end_time, '%Y-%m-%dT%H:%M:%S%z').date()
end_tm = end_time.split('T')[1].split('-')[0]
else:
end_date = 'Unknown'
end_tm = 'Unknown'
# Extract location details from "visit" or "timelinePath"
lat, lon = None, None
if 'visit' in segment:
placeLocation = segment['visit'].get('topCandidate', {}).get('placeLocation', {}).get('latLng', None)
if placeLocation:
lat, lon = [float(coord.strip('°')) for coord in placeLocation.split(", ")]
elif 'timelinePath' in segment:
# Extract the first point from timelinePath if it exists
if len(segment['timelinePath']) > 0:
point = segment['timelinePath'][0].get('point', None)
if point:
lat, lon = [float(coord.strip('°')) for coord in point.split(", ")]
# Yield the extracted data
yield [end_date, end_tm, start_date, start_tm, lat, lon]
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
# Hard-coded file paths
in_file = 'input.json' # Replace with your input JSON file path
out_file = 'output.csv' # Replace with your desired output CSV file path
in_file = getFullPath(in_file)
out_file = getFullPath(out_file)
features = []
# add the Headers
features.append(['End Date', 'End Time', 'Start Date', 'Start Time', 'Latitude', 'Longitude'])
print("Reading {0}".format(in_file))
reader = make_reader(in_file)
for r in reader:
features.append(r)
print('Read {0} Records'.format(len(features) - 1))
# write this data
with open(out_file, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerows(features)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@GitMae99 @devdattaT I'm running into the same problem, and it looks like the location-history.json file from Google is in a different format. There is no "locations" array in the json file. It has a "semanticSegments" array at the top. I assume this is because of Google's change to the timeline. I probably only have access to the Semantic Location History information, and not the Raw Location History data.