nur Bahnhof

convert google location data from google takeout to owntracks native format

(moved over from https://git.h.oluflorenzen.de/finkregh/scratchpad/wiki/convert-google-location-data-from-google-takeout-to-owntracks-native-format)

Slightly modified from https://www.technowizardry.net/2024/01/migrating-from-google-location-history-to-owntracks/

Script to convert google location takeout to owntracks native format. No need for a MQTT connection, just dump the created files into the owntracks-recorder data dir.

 1#!/usr/bin/python
 2import pandas as pd
 3import json
 4import time
 5
 6# https://owntracks.org/booklet/features/tid/
 7tracker_id = 'ex' # A two-character identifier
 8df_gps = pd.read_json('Records.json', typ='frame', orient='records')
 9print('There are {:,} rows in the location history dataset'.format(len(df_gps)))
10
11df_gps = df_gps.apply(lambda x: x['locations'], axis=1, result_type='expand')
12df_gps['latitudeE7'] = df_gps['latitudeE7'] / 10.**7
13df_gps['longitudeE7'] = df_gps['longitudeE7'] / 10.**7
14
15# In some cases, Google appears to generate timestamps in two different formats.
16# Here we convert both types, then normalize it all into the timestamp Pandas dtype.
17try:
18    df_gps.loc[df_gps['timestamp'].str.len() == len('2013-12-16T05:42:25.711Z'), 'timestamp'] = pd.to_datetime(df_gps['timestamp'], format='mixed')
19except ValueError:
20    df_gps.loc[df_gps['timestamp'].str.len() == len('2013-12-16T05:42:25Z'), 'timestamp'] = pd.to_datetime(df_gps['timestamp'], format='%Y-%m-%dT%H:%M:%S%Z', utc=True)
21
22df_gps['timestamp'] = pd.to_datetime(df_gps['timestamp'])
23
24owntracks = df_gps.rename(columns={'latitudeE7': 'lat', 'longitudeE7': 'lon', 'accuracy': 'acc', 'altitude': 'alt', 'verticalAccuracy': 'vac'})
25owntracks['tst'] = (owntracks['timestamp'].astype(int) / 10**9)
26
27files = {}
28
29years = df_gps['timestamp'].dt.year.agg(['min', 'max'])
30
31for year in range(years['min'], years['max'] + 1):
32    for month in range(1, 13):
33        files[f"{year}-{month}"] = open(f"location/{year}-{str(month).rjust(2, '0')}.rec", 'w')
34
35try:
36    for index, row in owntracks.iterrows():
37        d = row.to_dict()
38        record = {
39            '_type': 'location',
40            'tid': tracker_id
41        }
42        record['tst'] = int(time.mktime(d['timestamp'].timetuple()))
43
44        for key in ['lat', 'lon']:
45            if key in row and not pd.isnull(row[key]):
46                record[key] = row[key]
47        for key in ['acc', 'alt', 'vac']:
48            if key in row and not pd.isnull(row[key]):
49                record[key] = int(row[key])
50
51        timestamp = row['timestamp'].strftime("%Y-%m-%dT%H:%M:%SZ")
52        line = f"{timestamp}\t*                 \t{json.dumps(record, separators=(',', ':'))}\n"
53        files[f"{d['timestamp'].year}-{d['timestamp'].month}"].write(line)
54finally:
55    for key, file in files.items():
56        file.flush()
57        file.close()

Comments

#google #location #owntracks #selfhosting

Reply to this post by email ↪