Merge branch 'master' of nano:src/igc2kmz

debian-sid
Tom Payne 15 years ago
commit 950c893784

@ -4,8 +4,12 @@ Check indexes in colored tracklogs
Check why balloons don't point at point
Clean up heirarchical altitude marks
Clean up global styles
Nice row backgrounds in tables
Use ExtendedData for tables
MEDIUM
Competition points
Aerial tour
Allow override of photo time
Add comments
Add nice thermal and glide icons

@ -137,7 +137,7 @@ def main(argv):
roots=roots,
tz_offset=options.tz_offset,
task=task)
kmz.write(options.output, debug=options.debug)
kmz.write(options.output, '2.2', debug=options.debug)
if __name__ == '__main__':

@ -16,7 +16,7 @@
import datetime
import math
from math import pi, sqrt
import operator
import os
import unicodedata
@ -70,9 +70,9 @@ class Stock(object):
def __init__(self):
self.kmz = kmz.kmz()
#
self.icon_scales = [math.sqrt(x) for x in [0.6, 0.5, 0.4, 0.3]]
self.icon_scales = [sqrt(x) for x in [0.6, 0.5, 0.4, 0.3]]
self.icons = [kml.Icon.palette(4, i) for i in [25, 25, 24, 24]]
self.label_scales = [math.sqrt(x) for x in [0.6, 0.5, 0.4, 0.3]]
self.label_scales = [sqrt(x) for x in [0.6, 0.5, 0.4, 0.3]]
#
list_style = kml.ListStyle(listItemType='radioFolder')
self.radio_folder_style = kml.Style(list_style)
@ -361,6 +361,29 @@ class Flight(object):
folder.add(placemark)
return kmz.kmz(folder)
def make_tour_folder(self, globals):
style_url = globals.stock.check_hide_children_style.url()
folder = kmz.kmz(kml.Folder(name='Tour', styleUrl=style_url))
dt = self.track.coords[0].dt
delta = datetime.timedelta(seconds=5 * 60)
coords = []
while dt < self.track.coords[-1].dt:
coords.append(self.track.coord_at(dt))
dt += delta
for i in xrange(0, len(coords)):
j = (i + 1) % len(coords)
point = kml.Point(coordinates=[coords[i]],
altitudeMode=self.altitude_mode)
heading = coords[i].initial_bearing_to_deg(coords[j])
camera = kml.Camera(altitude=coords[i].ele,
heading=heading,
latitude=coords[i].lat_deg,
longitude=coords[i].lon_deg,
tilt=75)
placemark = kml.Placemark(point, camera)
folder.add(placemark)
return folder
def make_placemark(self, globals, coord, altitudeMode=None, name=None,
style_url=None):
point = kml.Point(coordinates=[coord], altitudeMode=altitudeMode)
@ -442,9 +465,9 @@ class Flight(object):
name = kml.name('%.1fkm' % (distance / 1000.0))
if arrow:
bearing = coord1.initial_bearing_to(coord0)
coordinates = [coord1.coord_at(bearing - math.pi / 12.0, 400.0),
coordinates = [coord1.coord_at(bearing - pi / 12.0, 400.0),
coord1,
coord1.coord_at(bearing + math.pi / 12.0, 400.0)]
coord1.coord_at(bearing + pi / 12.0, 400.0)]
line_string = kml.LineString(coordinates=coordinates,
altitudeMode='clampToGround',
tessellate=1)
@ -587,7 +610,7 @@ class Flight(object):
'%dm' % total_dz_negative))
if title == 'thermal':
drift_speed = dp / dt
drift_direction = rad_to_compass(theta + math.pi)
drift_direction = rad_to_compass(theta + pi)
rows.append(('Drift', '%.1fkm/h %s'
% (3.6 * drift_speed, drift_direction)))
trs = ''.join('<tr><th align="right">%s</th><td>%s</td></tr>' % row
@ -692,6 +715,7 @@ class Flight(object):
folder.add(self.make_track_folder(globals))
folder.add(self.make_shadow_folder(globals))
folder.add(self.make_animation(globals))
folder.add(self.make_tour_folder(globals))
folder.add(self.make_photos_folder(globals))
folder.add(self.make_xc_folder(globals))
folder.add(self.make_altitude_marks_folder(globals))
@ -773,9 +797,9 @@ def make_task_folder(globals, task):
coord1 = tp1.coord.coord_at(theta, tp1.radius)
line_string1 = kml.LineString(coordinates=[coord0, coord1],
tessellate=1)
coords = [coord1.coord_at(theta - math.pi / 12.0, 400.0),
coords = [coord1.coord_at(theta - pi / 12.0, 400.0),
coord1,
coord1.coord_at(theta + math.pi / 12.0, 400.0)]
coord1.coord_at(theta + pi / 12.0, 400.0)]
line_string2 = kml.LineString(coordinates=coords, tessellate=1)
multi_geometry = kml.MultiGeometry(line_string1, line_string2)
folder.add(kml.Placemark(multi_geometry, styleUrl=style_url))
@ -832,7 +856,7 @@ def flights2kmz(flights, roots=[], tz_offset=0, task=None):
globals.graph_height = 300
result = kmz.kmz()
result.add_siblings(stock.kmz)
result.add_roots(*roots)
result.add_roots(kml.open(1), *roots)
if globals.task:
result.add_siblings(make_task_folder(globals, globals.task))
for flight in flights:

@ -28,10 +28,33 @@ def rad_to_compass(rad):
return compass[int(8 * rad / pi + 0.5) % 16]
class degreeattr(object):
def __init__(self, attr):
self.attr = attr
def __get__(self, obj, type=None):
return 180.0 * getattr(obj, self.attr) / pi
def __set__(self, obj, value):
setattr(obj, self.attr, pi * value / 180.0)
class degreemethod(object):
def __new__(cls, f):
def deg_f(*args, **kwargs):
return 180.0 * f(*args, **kwargs) / pi
return deg_f
class Coord(object):
__slots__ = ('lat', 'lon', 'ele', 'dt')
lat_deg = degreeattr('lat')
lon_deg = degreeattr('lon')
def __init__(self, lat, lon, ele, dt=None):
self.lat = lat
self.lon = lon
@ -42,6 +65,9 @@ class Coord(object):
def deg(cls, lat, lon, ele, dt=None):
return cls(pi * lat / 180.0, pi * lon / 180.0, ele, dt)
def dup(self):
return Coord(self.lat, self.lon, self.ele, self.dt)
def initial_bearing_to(self, other):
"""Return the initial bearing from self to other."""
y = sin(other.lon - self.lon) * cos(other.lat)
@ -49,6 +75,8 @@ class Coord(object):
- sin(self.lat) * cos(other.lat) * cos(other.lon - self.lon)
return atan2(y, x)
initial_bearing_to_deg = degreemethod(initial_bearing_to)
def distance_to(self, other):
"""Return the distance from self to other."""
d = sin(self.lat) * sin(other.lat) \

@ -173,6 +173,7 @@ class altitude(_SimpleElement): pass
class altitudeMode(_SimpleElement): pass
class BalloonStyle(_CompoundElement): pass
class begin(_SimpleElement): pass
class Camera(_CompoundElement): pass
class color(_SimpleElement):
@ -187,8 +188,7 @@ class color(_SimpleElement):
class coordinates(_SimpleElement):
def __init__(self, coords):
texts = ('%f,%f,%d' % (180.0 * c.lon / pi, 180.0 * c.lat / pi, c.ele)
for c in coords)
texts = ('%f,%f,%d' % (c.lon_deg, c.lat_deg, c.ele) for c in coords)
_SimpleElement.__init__(self, ' '.join(texts))
@classmethod
@ -208,6 +208,7 @@ class Document(_CompoundElement): pass
class end(_SimpleElement): pass
class extrude(_SimpleElement): pass
class Folder(_CompoundElement): pass
class heading(_SimpleElement): pass
class href(_SimpleElement): pass
@ -262,10 +263,12 @@ class kml(_CompoundElement):
class LabelStyle(_CompoundElement): pass
class latitude(_SimpleElement): pass
class LineString(_CompoundElement): pass
class LineStyle(_CompoundElement): pass
class ListStyle(_CompoundElement): pass
class listItemType(_SimpleElement): pass
class longitude(_SimpleElement): pass
class MultiGeometry(_CompoundElement): pass
class name(_SimpleElement): pass
class open(_SimpleElement): pass
@ -273,6 +276,7 @@ class overlayXY(_SimpleElement): pass
class Placemark(_CompoundElement): pass
class Point(_CompoundElement): pass
class PolyStyle(_CompoundElement): pass
class roll(_SimpleElement): pass
class scale(_SimpleElement): pass
class ScreenOverlay(_CompoundElement): pass
class screenXY(_SimpleElement): pass
@ -290,6 +294,7 @@ class Style(_CompoundElement):
class styleUrl(_SimpleElement): pass
class tessellate(_SimpleElement): pass
class text(_SimpleElement): pass
class tilt(_SimpleElement): pass
class TimeSpan(_CompoundElement): pass
class visibility(_SimpleElement): pass
class when(_SimpleElement): pass

@ -62,17 +62,17 @@ class kmz(object):
self.elements.append(kml.__dict__[key](value))
return self
def write(self, filename, debug=False):
def write(self, filename, version, debug=False):
date_time = datetime.datetime.now().timetuple()[:6]
zf = zipfile.ZipFile(filename, 'w')
document = kml.Document(open=1)
document = kml.Document()
document.add(*self.roots)
document.add(*self.elements)
string_io = StringIO()
if debug:
kml.kml('2.1', document).pretty_write(string_io)
kml.kml(version, document).pretty_write(string_io)
else:
kml.kml('2.1', document).write(string_io)
kml.kml(version, document).write(string_io)
zi = zipfile.ZipInfo('doc.kml')
zi.compress_type = zipfile.ZIP_DEFLATED
zi.date_time = date_time

Loading…
Cancel
Save