rpirena/datalogger/stratosflights2gpx.py

109 lines
3.5 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/python3
# encoding: UTF-8
import fileinput, math, sys, time
import numpy
out = sys.stdout
"""
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
$;00:01:09;09:27:10;14.07.2017;Y;06;53 55.42264 N;009 31.93766 E;0.013;0.0;;28.7;43.750;31.750;44.876;1012.739;9.4;1137
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#;Up-Time;UTC;Date;RMC Valid;Sats in use;Latitude;Longitude;Speed over Ground [knots];Speed over Ground [km/h];Course over Ground;Altitude NN [m];Board: Temp [C];Extern: Temp [C];Extern: Hum [perc];Extern: Press [hPa];Batt Voltage [V];Logger Status
"""
class datalog(dict):
header = "#;Up-Time;UTC;Date;RMC Valid;Sats in use;Latitude;Longitude;Speed over Ground [knots];Speed over Ground [km/h];Course over Ground;Altitude NN [m];Board: Temp [C];Extern: Temp [C];Extern: Hum [perc];Extern: Press [hPa];Batt Voltage [V];Logger Status"
def __init__(self, l, header=None):
if header is not None:
self.header = header
self.fields = [f.split('[')[0].strip() for f in self.header.split(';')]
l=l.strip()
if l[0]!='$':
raise ValueError("No $: "+l)
self.ff = l.split(';')
if len(self.ff) != len(self.fields):
print("%d data, %d fields" % (len(self.ff), len(self.fields)), file=sys.stderr)
for i,f in enumerate(self.fields):
self[f] = self.ff[i]
def gps_ccord(self, i):
if self["RMC Valid"]!='Y':
return None
ll = self[i].split()
deg = int(ll[0]) + float(ll[1])/60
if ll[2] in "SW":
deg = - deg
return deg
def longitude(self):
return self.gps_ccord('Longitude')
def latitude(self):
return self.gps_ccord('Latitude')
def time(self, i='UTC'):
ll = list(map(int, self[i].split(':')))
return 3600*ll[2] + 60*ll[1] + ll[0]
def iso_time(self):
dd = list(map(int, self['Date'].split('.')))
tt = list(map(int, self['UTC'].split(':')))
if tt[0]==24:
tt[0] = 0
dd[2] -= 1
r = "%04d-%02d-%02dT" % (dd[2], dd[1], dd[0])
r+= "%02d:%02d:%02dZ" % (tt[0], tt[1], tt[2])
return r
def elevation(self):
return float(self['Altitude NN'])
h = None
do_gpx = True
for l in fileinput.input():
if l[0:5]=='Name:':
if do_gpx:
out.write("""<?xml version="1.0" encoding="UTF-8" ?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1"
creator="stratosflights2gpx.py"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd ">
<trk>
<name><![CDATA[%s]]></name>
<trkseg>
""" % l[5:].strip())
do_gpx = False
continue
if l[0]=='#':
h = l
continue
try:
c = datalog(l, h)
except Exception as e:
sys.stderr.write(l+"\n"+str(e))
raise
lon = c.longitude()
lat = c.latitude()
if lon and lat:
out.write(' <trkpt lat="%.7f" lon="%.7f">\n' % (lat, lon))
e = c.elevation()
if e:
out.write(" <ele>%s</ele>\n" % e)
t = c.iso_time()
if t:
out.write(" <time>%s</time>\n" % t)
out.write(' </trkpt>\n')
out.write(""" </trkseg>
</trk>
</gpx>
""")