Last active
August 21, 2019 16:23
-
-
Save grigory-rechistov/fb7597e9cc7dd26010c3042abcf20b9b to your computer and use it in GitHub Desktop.
Randomize GPX trajectory in space and time
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
#!/usr/bin/python | |
# TODO: port to Python3 | |
# Take an input GPX track and generate a series of identical tracks | |
# shifted in time and with noise added to individual points' coordinates and | |
# timestamps. | |
import xml.etree.ElementTree as ET | |
from sys import argv | |
from random import random | |
from datetime import datetime | |
from datetime import timedelta | |
from dateutil import parser as date_parser | |
from dateutil.rrule import DAILY, rrule, MO, TU, WE, TH, FR | |
def daterange(start_date, end_date): | |
# return only working days in the region | |
# I did not work much on Fridays, so exclude it | |
return rrule(DAILY, dtstart=start_date, until=end_date, byweekday=(MO,TU,WE,TH)) # FR | |
def get_noise(percentage = 0.5): | |
return 1.0 + (random() - 0.5) * percentage / 100.0 | |
# TODO only the last register_namespace takes effect? | |
ET.register_namespace('', "http://www.topografix.com/GPX/1/1") | |
ET.register_namespace('', "http://www.topografix.com/GPX/1/0") | |
ET.register_namespace("xsi", "http://www.w3.org/2001/XMLSchema-instance") | |
et = ET.parse(argv[1]) | |
root = et.getroot() | |
script = open("batch-upload.sh", "w") | |
script.write("#!/bin/sh\n") | |
script.write("set -e\n") | |
# morning track | |
start_date = datetime(2019, 2, 1, 8, 00, 00) | |
end_date = datetime(2019, 8, 20, 8, 45, 00) | |
# evening track | |
#start_date = datetime(2018, 2, 1, 16, 30, 00) | |
#end_date = datetime(2019, 8, 20, 16, 45, 00) | |
for new_date in daterange(start_date, end_date): | |
global_time_shift = (random() - 0.5) * 3600 # plus minus half hour | |
first_time = None | |
for item in root.iter(): | |
if item.tag.find("name") != -1: | |
item.text = "Commute " + new_date.isoformat() | |
print "Working with", item.text | |
if item.tag.find("trkpt") != -1: # tag contains stupid namespace prefix | |
lat = float(item.attrib['lat']) | |
lon = float(item.attrib['lon']) | |
lat *= get_noise(0.0001) | |
lon *= get_noise(0.0001) | |
item.attrib['lat'] = str(lat) | |
item.attrib['lon'] = str(lon) | |
if item.tag.find("ele") != -1: | |
ele = float(item.text) | |
ele *= get_noise(5.0) | |
item.text = str(ele) | |
if item.tag.find("time") != -1: | |
old_time = date_parser.parse(item.text) | |
if first_time is None: | |
first_time = old_time | |
path_delta = old_time - first_time | |
local_shift = (random() - 0.5) * 0.05 | |
noise_delta = (timedelta(seconds=global_time_shift) + | |
timedelta(seconds=local_shift)) | |
new_time = new_date + path_delta + noise_delta | |
item.text = new_time.isoformat() | |
# Write back to file | |
newfname = "commute-" + new_date.strftime("%s") + ".gpx" | |
et.write(newfname) | |
script.write("~/workspace/stravacli/stravaup.py --no-popup --xml-desc --activity-type ride %s\n" % (newfname)) | |
script.write("sleep 3\n") | |
script.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment