Skip to content

Instantly share code, notes, and snippets.

@hupili
Created December 16, 2020 10:05
Show Gist options
  • Select an option

  • Save hupili/600d6ad064de63945118ae1e4e23be9c to your computer and use it in GitHub Desktop.

Select an option

Save hupili/600d6ad064de63945118ae1e4e23be9c to your computer and use it in GitHub Desktop.
Scan a folder containing gpx files and detect potential tracking errors
import lxml
from bs4 import BeautifulSoup
# https://medium.com/@petehouston/calculate-distance-of-two-locations-on-earth-using-python-1501b1944d97
from math import radians, sin, cos, asin, sqrt
def haversine(lon1, lat1, lon2, lat2):
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2
return 2 * 6371 * asin(sqrt(a))
from dateutil import parser
normal_avg_ddist = 0.013137836943847864 * 50
normal_avg_dtime = 10.003996003996004 * 500
normal_avg_speed = 0.0016342546180846051 * 50
def detect_abnormal(fn):
# fn = "trailwatch/449905.gpx"
xml = BeautifulSoup(open(fn).read())
points = []
for trkpt in xml.findAll('trkpt'):
points.append((
float(trkpt.attrs['lon']),
float(trkpt.attrs['lat']),
parser.parse(trkpt.find('time').text)
))
# print(points)
speeds = []
ddists = []
dtimes = []
for p1, p2 in zip(points[: -1], points[1: ]):
ddist = haversine(p1[0], p1[1], p2[0], p2[1])
dtime = (p2[2] - p1[2]).total_seconds()
speed = ddist / dtime
# print(speed)
speeds.append(speed)
ddists.append(ddist)
dtimes.append(dtime)
if ddist > normal_avg_ddist:
print('ddst')
return True
if dtime > normal_avg_dtime:
print('dtime')
return True
if speed > normal_avg_speed:
print('speed')
return True
return False
# print('avg ddist:', sum(ddists) / len(ddists))
# print('avg dtime:', sum(dtimes) / len(dtimes))
# print('avg speed:', sum(speeds) / len(speeds))
# print(detect_abnormal(''))
# avg ddist: 0.013137836943847864
# avg dtime: 10.003996003996004
# avg speed: 0.0016342546180846051
import datetime
def display_key_info(fn):
xml = BeautifulSoup(open(fn).read())
track = xml.find('trk')
start_time = datetime.datetime.fromtimestamp(
float(track.find('time').text))
# print(start_time)
info = track.find('info').text
print(start_time, info, track.find('id').text, fn)
import os
for fn in os.listdir('trailwatch'):
path = os.path.join('trailwatch', fn)
if detect_abnormal(path):
display_key_info(path)
# print(path, detect_abnormal(path))
# display_key_info('trailwatch/222632.gpx')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment