Skip to content

Instantly share code, notes, and snippets.

@TimSC
Created November 22, 2017 01:55
Show Gist options
  • Save TimSC/f31899070dcd3cd81992888a666a6362 to your computer and use it in GitHub Desktop.
Save TimSC/f31899070dcd3cd81992888a666a6362 to your computer and use it in GitHub Desktop.
Interpolate missing positions in gpx
import xml.etree.ElementTree as ET
import dateutil.parser
from datetime import timedelta
class Interpolate(object):
def __init__(self, knownWpts):
self.knownWpts = knownWpts[:]
self.knownWpts.sort()
#for wpt in self.knownWpts:
# print wpt
def Predict(self, wpt):
besti = None
for i in range(len(self.knownWpts)-1):
if wpt[0] >= self.knownWpts[i][0] and wpt[0] < self.knownWpts[i+1][0]:
besti = i
dt = self.knownWpts[besti+1][0] - self.knownWpts[besti][0]
frac = (wpt[0] - self.knownWpts[besti][0]).total_seconds() / dt.total_seconds()
lat1, lat2 = self.knownWpts[besti][1], self.knownWpts[besti+1][1]
lon1, lon2 = self.knownWpts[besti][2], self.knownWpts[besti+1][2]
latp = lat1 + frac * (lat2 - lat1)
lonp = lon1 + frac * (lon2 - lon1)
#dt2 = timedelta(seconds=frac * dt.total_seconds())
return latp, lonp
if __name__=="__main__":
tree = ET.parse('20171121wpts.gpx')
root = tree.getroot()
out = ET.Element("gpx")
knownWpts = []
unknownWpts = []
for wpt in root:
try:
lat, lon = map(float, (wpt.attrib["lat"], wpt.attrib["lon"]))
except ValueError:
lat, lon = None, None
timeNode = wpt.find("{http://www.topografix.com/GPX/1/0}time")
nameNode = wpt.find("{http://www.topografix.com/GPX/1/0}name")
nameText = None
if nameNode is not None:
nameText = nameNode.text
if timeNode is not None:
timestamp = dateutil.parser.parse(timeNode.text)
if lat is not None:
knownWpts.append((timestamp, lat, lon, nameText))
else:
unknownWpts.append((timestamp, nameText))
interpolate = Interpolate(knownWpts)
for wpt in unknownWpts:
lat, lon = interpolate.Predict(wpt)
wptNode = ET.SubElement(out, 'wpt')
wptNode.attrib["lat"] = str(lat)
wptNode.attrib["lon"] = str(lon)
wptName = ET.SubElement(wptNode, 'name')
wptName.text = wpt[1]
for wpt in knownWpts:
wptNode = ET.SubElement(out, 'wpt')
wptNode.attrib["lat"] = str(wpt[1])
wptNode.attrib["lon"] = str(wpt[2])
wptName = ET.SubElement(wptNode, 'name')
wptName.text = wpt[3]
fi = open("out.gpx", "wt")
ET.ElementTree(out).write(fi, encoding="utf-8")
fi.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment