Refactor XC handling.

debian-sid
Tom Payne 15 years ago
parent 58f8acf103
commit 582c14475a

@ -22,7 +22,7 @@ from __future__ import with_statement
import datetime
import fileinput
import logging
import optparse
from optparse import OptionParser
import os
import re
import sys
@ -33,51 +33,9 @@ except ImportError:
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from igc2kmz.coord import Coord
from igc2kmz.etree import tag
class RtePt(object):
def __init__(self):
self.name = None
self.lat = None
self.lon = None
self.dt = None
def togpx(self, tb):
with tag(tb, 'rtept', {'lat': str(self.lat), 'lon': str(self.lon)}):
with tag(tb, 'name'): tb.data(self.name)
with tag(tb, 'time'):
tb.data(self.dt.strftime('%Y-%m-%dT%H:%M:%SZ'))
with tag(tb, 'fix'): tb.data('2d')
return tb
class Rte(object):
def __init__(self):
self.league = None
self.name = None
self.distance = None
self.multiplier = None
self.score = None
self.circuit = None
self.rtepts = []
def togpx(self, tb):
with tag(tb, 'rte'):
with tag(tb, 'name'): tb.data(self.name)
with tag(tb, 'extensions'):
with tag(tb, 'league'): tb.data(self.league)
with tag(tb, 'distance'): tb.data(str(self.distance))
with tag(tb, 'multiplier'): tb.data('%.2f' % self.multiplier);
with tag(tb, 'score'): tb.data(str(self.score))
if self.circuit:
with tag(tb, 'circuit'):
pass
for rtept in self.rtepts:
rtept.togpx(tb)
return tb
from igc2kmz.xc import Route, Turnpoint, XC
DEBUG_DATE_RE = re.compile(r'DEBUG DATE (\d\d)(\d\d)(\d\d)\Z')
@ -98,80 +56,71 @@ PRETTY_NAME = {
CIRCUITS = set(['FREE_TRIANGLE', 'FAI_TRIANGLE'])
class XC(object):
def __init__(self, file, league, debug=False):
self.rtes = []
date = None
for line in file:
line = line.rstrip()
m = DEBUG_DATE_RE.match(line)
if m:
day, mon, year = map(int, m.groups())
date = datetime.date(year + 2000, mon,day)
continue
m = OUT_TYPE_RE.match(line)
if m:
rte = Rte()
rte.league = league
rte.name = PRETTY_NAME[m.group(1)]
rte.circuit = m.group(1) in CIRCUITS
self.rtes.append(rte)
last_time = None
continue
m = OUT_FLIGHT_KM_RE.match(line)
if m:
rte.distance = float(m.group(1))
continue
m = OUT_FLIGHT_POINTS_RE.match(line)
if m:
rte.score = float(m.group(1))
rte.multiplier = rte.score / rte.distance
continue
m = OUT_P_RE.match(line)
if m:
rtept = RtePt()
rtept.name = 'TP%d' % len(rte.rtepts) if rte.rtepts else 'Start'
rtept.lat = int(m.group(5)) + float(m.group(6)) / 60.0
if m.group(4) == 'S':
rtept.lat = -rtept.lat
rtept.lon = int(m.group(8)) + float(m.group(9)) / 60.0
if m.group(7) == 'W':
rtept.lon = -rtept.lon
time = datetime.time(*map(int, m.group(1, 2, 3)))
if not last_time is None and time < last_time:
date += datetime.timedelta(1)
rtept.dt = datetime.datetime.combine(date, time)
rte.rtepts.append(rtept)
last_time = time
continue
if debug:
logging.warning(line)
for rte in self.rtes:
rte.rtepts[-1].name = 'Finish'
def togpx(self, tb):
attrs = {'version': '1.1',
'creator': 'http://github.com/twpayne/igc2kmz/wikis'}
with tag(tb, 'gpx', attrs):
for rte in self.rtes:
rte.togpx(tb)
return tb
def main(argv):
parser = optparse.OptionParser(description='olc2002 to GPX converter')
parser = OptionParser(description='olc2002 to GPX converter')
parser.add_option('-l', '--league', metavar='STRING')
parser.add_option('-o', '--output', metavar='FILENAME')
parser.add_option('--debug', action='store_true')
parser.set_defaults(debug=False)
parser.set_defaults(league='OLC')
options, args = parser.parse_args(argv)
xc = XC(fileinput.input(args[1:]), options.league, debug=options.debug)
e = xc.togpx(TreeBuilder()).close()
#
routes = []
date = None
for line in fileinput.input(args[1:]):
line = line.rstrip()
m = DEBUG_DATE_RE.match(line)
if m:
day, mon, year = map(int, m.groups())
date = datetime.date(year + 2000, mon,day)
continue
m = OUT_TYPE_RE.match(line)
if m:
name = PRETTY_NAME[m.group(1)]
circuit = m.group(1) in CIRCUITS
route = Route(name, options.league, None, None, None, circuit, [])
routes.append(route)
last_time = None
continue
m = OUT_FLIGHT_KM_RE.match(line)
if m:
route.distance = float(m.group(1))
continue
m = OUT_FLIGHT_POINTS_RE.match(line)
if m:
route.score = float(m.group(1))
route.multiplier = route.score / route.distance
continue
m = OUT_P_RE.match(line)
if m:
name = 'TP%d' % len(route.tps) if route.tps else 'Start'
lat = int(m.group(5)) + float(m.group(6)) / 60.0
if m.group(4) == 'S':
lat = -lat
lon = int(m.group(8)) + float(m.group(9)) / 60.0
if m.group(7) == 'W':
lon = -lon
time = datetime.time(*map(int, m.group(1, 2, 3)))
if not last_time is None and time < last_time:
date += datetime.timedelta(1)
dt = datetime.datetime.combine(date, time)
coord = Coord(lat, lon, 0, dt)
tp = Turnpoint(name, coord)
route.tps.append(tp)
last_time = time
continue
if options.debug:
logging.warning(line)
for route in routes:
route.tps[-1].name = 'Finish'
xc = XC(routes)
attrs = {'version': '1.1',
'creator': 'http://github.com/twpayne/igc2kmz/wikis'}
with tag(TreeBuilder(), 'gpx', attrs) as tb:
element = xc.build_tree(tb).close()
output = open(options.output, 'w') if options.output else sys.stdout
output.write('<?xml version="1.0" encoding="UTF-8"?>')
ElementTree(e).write(output)
ElementTree(element).write(output)
if __name__ == '__main__':

@ -24,6 +24,7 @@ class tag(object):
def __enter__(self):
self.tb.start(self.name, self.attrs)
return self.tb
def __exit__(self, type, value, traceback):
self.tb.end(self.name)

@ -15,10 +15,16 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import with_statement
import datetime
import xml.etree.ElementTree
try:
from xml.etree.cElementTree import ElementTree, parse
except ImportError:
from xml.etree.ElementTree import ElementTree, parse
from coord import Coord
from etree import tag
class Turnpoint(object):
@ -27,6 +33,18 @@ class Turnpoint(object):
self.name = name
self.coord = coord
def build_tree(self, tb):
attrs = {'lat': str(self.coord.lat), 'lon': str(self.coord.lon)}
with tag(tb, 'rtept', attrs):
if self.coord.ele:
with tag(tb, 'ele'):
tb.data('%d' % ele)
with tag(tb, 'name'):
tb.data(self.name)
with tag(tb, 'time'):
tb.data(self.coord.dt.strftime('%Y-%m-%dT%H:%M:%SZ'))
return tb
@classmethod
def from_element(cls, rtept):
name = rtept.findtext('name').encode('utf_8')
@ -40,7 +58,7 @@ class Turnpoint(object):
return cls(name, coord)
class Rte(object):
class Route(object):
def __init__(self, name, league, distance, multiplier, score, circuit, tps):
self.name = name
@ -51,6 +69,26 @@ class Rte(object):
self.circuit = circuit
self.tps = tps
def build_tree(self, tb):
with tag(tb, 'rte'):
with tag(tb, 'name'):
tb.data(self.name)
with tag(tb, 'extensions'):
with tag(tb, 'league'):
tb.data(self.league)
with tag(tb, 'distance'):
tb.data(str(self.distance))
with tag(tb, 'multiplier'):
tb.data('%.2f' % self.multiplier)
with tag(tb, 'score'):
tb.data(str(self.score))
if self.circuit:
with tag(tb, 'circuit'):
pass
for tp in self.tps:
tp.build_tree(tb)
return tb
@classmethod
def from_element(cls, rte):
name = rte.findtext('name').encode('utf_8')
@ -68,12 +106,17 @@ class XC(object):
def __init__(self, routes):
self.routes = routes
def build_tree(self, tb):
for route in self.routes:
route.build_tree(tb)
return tb
@classmethod
def from_element(cls, element):
routes = map(Rte.from_element, element.findall('/rte'))
routes = map(Route.from_element, element.findall('/rte'))
return cls(routes)
@classmethod
def from_file(cls, file):
element = xml.etree.ElementTree.parse(file)
element = parse(file)
return cls.from_element(element)

Loading…
Cancel
Save