Merge branch 'master' of sol:src/igc2kmz
This commit is contained in:
commit
b2f2e667e0
|
@ -70,6 +70,10 @@ def main(argv):
|
|||
parser.add_option('-e', '--engine', metavar='URL', help='set engine')
|
||||
parser.add_option('-z', '--tz-offset', metavar='HOURS', type='int',
|
||||
help='set timezone offset')
|
||||
parser.add_option('-t', '--table-prefix', metavar='STRING',
|
||||
help='set table prefix')
|
||||
parser.add_option('-x', '--igc-suffix', metavar='STRING',
|
||||
help='set IGC file suffix')
|
||||
parser.add_option('--debug', action='store_true',
|
||||
help='enable pretty KML output')
|
||||
parser.set_defaults(output='igc2kmz.kmz')
|
||||
|
@ -79,6 +83,8 @@ def main(argv):
|
|||
parser.set_defaults(directory=DEFAULT_DIRECTORY)
|
||||
parser.set_defaults(engine=DEFAULT_ENGINE)
|
||||
parser.set_defaults(tz_offset=0)
|
||||
parser.set_defaults(table_prefix='leonardo_')
|
||||
parser.set_defaults(igc_suffix='.saned.full.igc')
|
||||
parser.set_defaults(debug=False)
|
||||
options, args = parser.parse_args(argv)
|
||||
#
|
||||
|
@ -97,7 +103,7 @@ def main(argv):
|
|||
ps.append('<a href="%(url)s">%(name)s</a>' % d)
|
||||
ps.append('Created by <a href="http://github.com/twpayne/igc2kmz/wikis">'
|
||||
'igc2kmz</a><br/>Copyright © Tom Payne, 2008')
|
||||
html = '<center>%s</center' % ''.join('<p>%s</p>' % p for p in ps)
|
||||
html = '<center>%s</center>' % ''.join('<p>%s</p>' % p for p in ps)
|
||||
description = kml.CDATA(html)
|
||||
balloon_style = kml.BalloonStyle(text=kml.CDATA('$[description]'))
|
||||
style = kml.Style(balloon_style)
|
||||
|
@ -105,11 +111,14 @@ def main(argv):
|
|||
style, Snippet=None, name=options.name, description=description)
|
||||
#
|
||||
metadata = MetaData(options.engine)
|
||||
pilots_table = Table('leonardo_pilots', metadata, autoload=True)
|
||||
flights_table = Table('leonardo_flights', metadata, autoload=True)
|
||||
flights_score_table = Table('leonardo_flights_score', metadata,
|
||||
autoload=True)
|
||||
photos_table = Table('leonardo_photos', metadata, autoload=True)
|
||||
pilots_table = Table(options.table_prefix + 'pilots', metadata,
|
||||
autoload=True)
|
||||
flights_table = Table(options.table_prefix + 'flights', metadata,
|
||||
autoload=True)
|
||||
flights_score_table = Table(options.table_prefix + 'flights_score',
|
||||
metadata, autoload=True)
|
||||
photos_table = Table(options.table_prefix + 'photos', metadata,
|
||||
autoload=True)
|
||||
#
|
||||
flights = []
|
||||
for flightID in args[1:]:
|
||||
|
@ -117,19 +126,26 @@ def main(argv):
|
|||
flight_row = select.execute().fetchone()
|
||||
if flight_row is None:
|
||||
raise KeyError, id
|
||||
igc_path_components = (flights_dir, flight_row.userID, 'flights',
|
||||
flight_row.DATE.year, flight_row.filename)
|
||||
if flight_row.userServerID:
|
||||
path = '%(userServerID)_%(userID)' % flight_row
|
||||
else:
|
||||
path = flight_row.userID
|
||||
igc_path_components = (flights_dir, path, 'flights',
|
||||
flight_row.DATE.year,
|
||||
flight_row.filename + options.igc_suffix)
|
||||
igc_path = os.path.join(*map(str, igc_path_components))
|
||||
track = IGC(open(igc_path)).track()
|
||||
flight = Flight(track)
|
||||
flight.glider_type = flight_row.glider
|
||||
flight.url = urljoin(options.url, SHOW_FLIGHT_URL % flight_row)
|
||||
#
|
||||
select = pilots_table.select(pilots_table.c.pilotID
|
||||
== flight_row.userID)
|
||||
select = pilots_table.select((pilots_table.c.pilotID
|
||||
== flight_row.userID) &
|
||||
(pilots_table.c.serverID
|
||||
== flight_row.userServerID))
|
||||
pilot_row = select.execute().fetchone()
|
||||
if pilot_row is None:
|
||||
raise KeyError, flight_row.userID
|
||||
raise KeyError, '(%(userID)s, %(userServerID)s)' % flight_row
|
||||
flight.pilot_name = '%(FirstName)s %(LastName)s' % pilot_row
|
||||
#
|
||||
routes = []
|
||||
|
|
106
igc2kmz/igc.py
106
igc2kmz/igc.py
|
@ -65,113 +65,133 @@ class Record(object):
|
|||
|
||||
class ARecord(Record):
|
||||
|
||||
def __init__(self, line, igc):
|
||||
@classmethod
|
||||
def parse(cls, line, igc):
|
||||
result = cls()
|
||||
m = A_RECORD_RE.match(line)
|
||||
if not m:
|
||||
raise SyntaxError, line
|
||||
self.value = m.group(1)
|
||||
igc.a = self.value
|
||||
result.value = m.group(1)
|
||||
igc.a = result.value
|
||||
return result
|
||||
|
||||
|
||||
class BRecord(Record):
|
||||
|
||||
__slots__ = ('dt', 'lat', 'lon', 'validity', 'alt', 'ele')
|
||||
|
||||
def __init__(self, line, igc):
|
||||
@classmethod
|
||||
def parse(cls, line, igc):
|
||||
result = cls()
|
||||
m = B_RECORD_RE.match(line)
|
||||
if not m:
|
||||
raise SyntaxError, line
|
||||
for key, value in igc.i.items():
|
||||
setattr(self, key, int(line[value]))
|
||||
setattr(result, key, int(line[value]))
|
||||
time = datetime.time(*map(int, m.group(1, 2, 3)))
|
||||
self.dt = datetime.datetime.combine(igc.hfdterecord.date, time)
|
||||
self.lat = int(m.group(4)) + int(m.group(5)) / 60000.0
|
||||
result.dt = datetime.datetime.combine(igc.hfdterecord.date, time)
|
||||
result.lat = int(m.group(4)) + int(m.group(5)) / 60000.0
|
||||
if 'lad' in igc.i:
|
||||
self.lat += int(line[igc.i['lad']]) / 6000000.0
|
||||
result.lat += int(line[igc.i['lad']]) / 6000000.0
|
||||
if m.group(6) == 'S':
|
||||
self.lat *= -1
|
||||
self.lon = int(m.group(7)) + int(m.group(8)) / 60000.0
|
||||
result.lat *= -1
|
||||
result.lon = int(m.group(7)) + int(m.group(8)) / 60000.0
|
||||
if 'lod' in igc.i:
|
||||
self.lon += int(line[igc.i['lod']]) / 6000000.0
|
||||
result.lon += int(line[igc.i['lod']]) / 6000000.0
|
||||
if m.group(9) == 'W':
|
||||
self.lon *= -1
|
||||
self.validity = m.group(10)
|
||||
self.alt = int(m.group(11))
|
||||
self.ele = int(m.group(12))
|
||||
igc.b.append(self)
|
||||
result.lon *= -1
|
||||
result.validity = m.group(10)
|
||||
result.alt = int(m.group(11))
|
||||
result.ele = int(m.group(12))
|
||||
igc.b.append(result)
|
||||
return result
|
||||
|
||||
|
||||
class CRecord(Record):
|
||||
|
||||
def __init__(self, line, igc):
|
||||
@classmethod
|
||||
def parse(cls, line, igc):
|
||||
result = cls()
|
||||
m = C_RECORD_RE.match(line)
|
||||
if not m:
|
||||
raise SyntaxError, line
|
||||
self.lat = int(m.group(1)) + int(m.group(2)) / 60000.0
|
||||
result.lat = int(m.group(1)) + int(m.group(2)) / 60000.0
|
||||
if m.group(3) == 'S':
|
||||
self.lat *= -1
|
||||
self.lon = int(m.group(4)) + int(m.group(5)) / 60000.0
|
||||
result.lat *= -1
|
||||
result.lon = int(m.group(4)) + int(m.group(5)) / 60000.0
|
||||
if m.group(6) == 'W':
|
||||
self.lon *= -1
|
||||
self.name = m.group(7)
|
||||
igc.c.append(self)
|
||||
result.lon *= -1
|
||||
result.name = m.group(7)
|
||||
igc.c.append(result)
|
||||
return result
|
||||
|
||||
|
||||
class GRecord(Record):
|
||||
|
||||
def __init__(self, line, igc):
|
||||
@classmethod
|
||||
def parse(cls, line, igc):
|
||||
result = cls()
|
||||
m = G_RECORD_RE.match(line)
|
||||
if not m:
|
||||
raise SyntaxError, line
|
||||
self.value = m.group(1)
|
||||
igc.g.append(self.value)
|
||||
result.value = m.group(1)
|
||||
igc.g.append(result.value)
|
||||
return result
|
||||
|
||||
|
||||
class HRecord(Record):
|
||||
|
||||
def __init__(self, line, igc):
|
||||
@classmethod
|
||||
def parse(cls, line, igc):
|
||||
result = cls()
|
||||
m = HFDTE_RECORD_RE.match(line)
|
||||
if m:
|
||||
self.source, self.type = m.group(1, 2)
|
||||
result.source, result.type = m.group(1, 2)
|
||||
day, month, year = map(int, m.group(3, 4, 5))
|
||||
try:
|
||||
self.date = datetime.date(2000 + year, month, day)
|
||||
result.date = datetime.date(2000 + year, month, day)
|
||||
except ValueError:
|
||||
raise SyntaxError, line
|
||||
igc.hfdterecord = self
|
||||
return
|
||||
igc.hfdterecord = result
|
||||
return result
|
||||
m = HFFXA_RECORD_RE.match(line)
|
||||
if m:
|
||||
self.source, self.type = m.group(1, 2)
|
||||
self.value = int(m.group(3))
|
||||
igc.h['fxa'] = self.value
|
||||
return
|
||||
result.source, result.type = m.group(1, 2)
|
||||
result.value = int(m.group(3))
|
||||
igc.h['fxa'] = result.value
|
||||
return result
|
||||
m = H_RECORD_RE.match(line)
|
||||
if m:
|
||||
self.source, self.key, self.value = m.groups()
|
||||
igc.h[self.key.lower()] = self.value
|
||||
return
|
||||
result.source, result.key, result.value = m.groups()
|
||||
igc.h[result.key.lower()] = result.value
|
||||
return result
|
||||
raise SyntaxError, line
|
||||
|
||||
|
||||
class IRecord(Record):
|
||||
|
||||
def __init__(self, line, igc):
|
||||
@classmethod
|
||||
def parse(cls, line, igc):
|
||||
result = cls()
|
||||
for i in xrange(0, int(line[1:3])):
|
||||
m = I_RECORD_RE.match(line, 3 + 7 * i, 10 + 7 * i)
|
||||
if not m:
|
||||
raise SyntaxError, line
|
||||
igc.i[m.group(3).lower()] = slice(int(m.group(1)),
|
||||
int(m.group(2)) + 1)
|
||||
return result
|
||||
|
||||
|
||||
class LRecord(Record):
|
||||
|
||||
def __init__(self, line, igc):
|
||||
@classmethod
|
||||
def parse(cls, line, igc):
|
||||
result = cls()
|
||||
m = L_RECORD_RE.match(line)
|
||||
if not m:
|
||||
raise SyntaxError, line
|
||||
igc.l.append(m.group(1))
|
||||
return result
|
||||
|
||||
|
||||
class IGC(object):
|
||||
|
@ -191,8 +211,10 @@ class IGC(object):
|
|||
for line in file:
|
||||
try:
|
||||
line = line.rstrip()
|
||||
if line[0] in class_by_letter:
|
||||
self.records.append(class_by_letter[line[0]](line, self))
|
||||
letter = line[0]
|
||||
if letter in class_by_letter:
|
||||
klass = class_by_letter[letter]
|
||||
self.records.append(klass.parse(line, self))
|
||||
else:
|
||||
logging.warning('%s: unknown record %s' \
|
||||
% (self.filename, repr(line)))
|
||||
|
|
Loading…
Reference in New Issue