--- /dev/null
+# German translations for wradmin.
+# Copyright (C) 2009 philipp.spitzer@winterrodeln.org
+# This file is distributed under the same license as the wradmin project.
+# Philipp Spitzer <philipp.spitzer@winterrodeln.org>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: wradmin 1.2.0\n"
+"Report-Msgid-Bugs-To: philipp.spitzer@winterrodeln.org\n"
+"POT-Creation-Date: 2009-12-09 20:12+0100\n"
+"PO-Revision-Date: 2009-12-09 20:37+0100\n"
+"Last-Translator: Philipp Spitzer <philipp.spitzer@winterrodeln.org>\n"
+"Language-Team: de <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9.4\n"
+
+#: wradmin/lib/wrgpx.py:137
+#, python-format
+msgid "Elevation of waypoint '%s' should be given."
+msgstr "Höhe des Wegpunktes '%s' sollte angegeben werden."
+
+#: wradmin/lib/wrgpx.py:138
+#, python-format
+msgid "Name of waypoint '%s' must be given."
+msgstr "Name des Wegpunktes '%s' muss angegeben werden."
+
+#: wradmin/lib/wrgpx.py:139
+#, python-format
+msgid "Type of waypoint '%s' must be given (Gasthaus, Bushaltestelle, ...)"
+msgstr ""
+"Typ des Wegpunktes '%s' muss angegeben werden (Gasthaus, Bushaltestelle, "
+"...)"
+
+#: wradmin/lib/wrgpx.py:140
+#, python-format
+msgid "Type of the waypoint '%s' has to be one of (Gasthaus, Bushaltestelle, ...)"
+msgstr "Typ des Wegpunktes '%s' muss Gasthaus, Bushaltestelle, ... sein."
+
+#: wradmin/lib/wrgpx.py:144
+msgid "GPX file has a 'rte' element. This is not used in WRGPX."
+msgstr ""
+"Die GPX Datei hat ein 'rte' Element. Dieses wird bei WRGPX nicht "
+"verwendet."
+
+#: wradmin/lib/wrgpx.py:161
+msgid "XML element extensions within XML element trkpt is not used by WRGPX."
+msgstr ""
+"Das XML Element 'extensions' im XML element 'trkpt' wird von WRGPX nicht "
+"benutzt."
+
+#: wradmin/lib/wrgpx.py:162
+#, python-format
+msgid "%d of %d track points have no elevation (%s)."
+msgstr "%d von %d Trackpunkte haben keine Höhe (%s)"
+
+#: wradmin/lib/wrgpx.py:163
+#, python-format
+msgid "track '%s' is empty."
+msgstr "Track '%s' ist leer."
+
+#: wradmin/lib/wrgpx.py:168
+msgid "GPX file has a 'extensions' element. This is not used in WRGPX."
+msgstr ""
+"Die GPX Datei hat ein 'extensions' Element. Dieses wird bei WRGPX nicht "
+"verwendet."
+
+#: wradmin/lib/wrgpx.py:170
+msgid "GPX file has a no metadata (like author, ...)."
+msgstr "Die GPX Datei hat keine Metadaten (z.B. Autor, ...)."
+
+#: wradmin/lib/wrgpx.py:178
+msgid "There is no 'Rodelbahn' type track in the GPX file."
+msgstr "Es gibt keinen Track mit dem Typ 'Rodelbahn' in der GPX Datei."
+
+#: wradmin/lib/wrgpx.py:182
+msgid "Track has no elevation data"
+msgstr "Track hat keine Höhendaten"
+
import datetime
import os
from lxml import etree
+import numpy as np
+import matplotlib
+matplotlib.use('Agg')
+import matplotlib.pyplot as plt
+import StringIO
+from pylons.i18n.translation import _
+
+
class MetaData:
- def __init__(self):
- self.name = None # name as string or None
- self.desc = None # description as string or None
- self.author = None # author as string or None
- self.author_email = None # email as string or None
- self.copyright_year = None # year of copyright as int or None
- self.license = None # link to license
- self.link = None # link as string or None
- self.time = None # datetime class or None
- self.minlat = None # float coordinate or None
- self.minlon = None # float coordinate or None
- self.maxlat = None # float coordinate or None
- self.maxlon = None # float coordinate or None
+ def __init__(self):
+ self.name = None # name as string or None
+ self.desc = None # description as string or None
+ self.author = None # author as string or None
+ self.author_email = None # email as string or None
+ self.copyright_year = None # year of copyright as int or None
+ self.license = None # link to license
+ self.link = None # link as string or None
+ self.time = None # datetime class or None
+ self.minlat = None # float coordinate or None
+ self.minlon = None # float coordinate or None
+ self.maxlat = None # float coordinate or None
+ self.maxlon = None # float coordinate or None
class Waypoint:
- def __init__(self):
- self.lat = None # float coordinate or None
- self.lon = None # float coordinate or None
- self.ele = None # height as float value or None
- self.name = None # name as string or None
- self.type = None # type as string or None
- def __repr__(self):
- return u"Waypoint %s" % unicode(self.name)
+ def __init__(self):
+ self.lat = None # float coordinate or None
+ self.lon = None # float coordinate or None
+ self.ele = None # height as float value or None
+ self.name = None # name as string or None
+ self.type = None # type as string or None
+ def __repr__(self):
+ return u"Waypoint %s" % unicode(self.name)
class Track:
- def __init__(self):
- self.name = None # name as string or None
- self.type = None # type as string or None
- self.points = [] # one point is a tuple (lat, lon, ele) or (lat, lon, None)
- def __repr__(self):
- return u"Track %s" % unicode(self.name)
+ def __init__(self):
+ self.name = None # name as string or None
+ self.type = None # type as string or None
+ self.points = [] # one point is a tuple (lat, lon, ele) or (lat, lon, None)
+ def __repr__(self):
+ return u"Track %s" % unicode(self.name)
class WrGpx:
- def __init__(self):
- self.metadata = MetaData()
- self.waypoints = []
- self.tracks = []
- def __repr__(self):
- return "WrGpx (%d waypoints; %d tracks)" % (len(self.waypoints), len(self.tracks))
+ def __init__(self):
+ self.metadata = MetaData()
+ self.waypoints = []
+ self.tracks = []
+ def __repr__(self):
+ return "WrGpx (%d waypoints; %d tracks)" % (len(self.waypoints), len(self.tracks))
class Hint:
- def __init__(self, message, level, line_nr=None):
- "level ... 0 informal information; 1 ... suggestion for improvement; 2 ... warning; 3 ... error"
- self.message = message
- self.level = level
- self.line_nr = line_nr
- def __repr__(self):
- return "Hint: %s" % self.message
+ def __init__(self, message, level, line_nr=None):
+ "level ... 0 informal information; 1 ... suggestion for improvement; 2 ... warning; 3 ... error"
+ self.message = message
+ self.level = level
+ self.line_nr = line_nr
+ def __repr__(self):
+ return "Hint: %s" % self.message
def parse_wrgpx(filename=None, string=None):
- """Parses a WRGPX file and returns a tuple of a data structure representing the content of the GPX file
- and a list of Hint classes. If the file is not well-formed or not an GPX 1.1 file, an etree.XMLSyntaxError exception is raised."""
- hints = []
- wrgpx = WrGpx()
-
- ns = '{http://www.topografix.com/GPX/1/1}'
-
- def parse_wpt(element):
- waypoint = Waypoint()
- waypoint.lat = float(element.attrib['lat'])
- waypoint.lon = float(element.attrib['lon'])
- for el in element:
- if el.tag == ns+'ele': waypoint.ele = float(el.text)
- elif el.tag == ns+'name': waypoint.name = el.text
- elif el.tag == ns+'desc': waypoint.desc = el.text
- elif el.tag == ns+'link': waypoint.link = el.attrib['href']
- elif el.tag == ns+'type': waypoint.type = el.text
- return waypoint
-
- schema = etree.XMLSchema(file=os.path.dirname(os.path.realpath(__file__)) + os.sep + 'gpx_1_1.xsd')
- parser = etree.XMLParser(schema=schema)
- if not string is None: root = etree.fromstring(string, parser)
- else:
- # xml = etree.parse(open(filename, 'rb'), parser)
- xml = etree.parse(filename, parser)
- root = xml.getroot()
- assert root.tag == ns + 'gpx' # Nothing else should be possible after validation
-
- wrgpx_has_metadata = False
- for element in root:
- # Metadata
- if element.tag == ns+'metadata':
- wrgpx_has_metadata = True
- for el in element:
- if el.tag == ns+'name': wrgpx.metadata.name = el.text
- elif el.tag == ns+'desc': wrgpx.metadata.desc = el.text
- elif el.tag == ns+'author':
- for e in el:
- if e.tag == ns+'name': wrgpx.metadata.author = e.text
- elif e.tag == ns+'email':
- wrgpx.metadata.author_email = e.attrib['id'] + '@' + e.attrib['domain']
- elif el.tag == ns+'copyright':
- for e in el:
- if e.tag == ns+'year': wrgpx.metadata.copyright_year = int(e.text)
- elif e.tag == ns+'license': wrgpx.metadata.license = e.text
- elif el.tag == ns+'link': wrgpx.metadata.link = el.attrib['href']
- elif el.tag == ns+'time':
- wrgpx.metadata.time = datetime.datetime.strptime(el.text, '%Y-%m-%dT%H:%M:%SZ') # '2008-11-10T20:44:52Z'
- elif el.tag == ns+'bounds':
- wrgpx.metadata.minlat = float(el.attrib['minlat'])
- wrgpx.metadata.minlon = float(el.attrib['minlon'])
- wrgpx.metadata.maxlat = float(el.attrib['maxlat'])
- wrgpx.metadata.maxlon = float(el.attrib['maxlon'])
- elif el.tag == ns+'extensions': hints.append(Hint("XML element extensions within XML element metadata is not used by WRGPX.", 1))
-
- # Waypoints
- elif element.tag == ns+'wpt':
- waypoint = parse_wpt(element)
- wrgpx.waypoints.append(waypoint)
- if waypoint.ele is None: hints.append(Hint(u"Elevation of waypoint '%s' should be given" % unicode(waypoint), 1))
-
- # Routes
- elif element.tag == ns+'rte':
- hints.append(Hint("GPX file has a 'rte' element. This is not used in WRGPX.", 1))
-
- # Tracks
- elif element.tag == ns+'trk':
- track = Track()
- for el in element:
- if el.tag == ns+'name': track.name = el.text
- elif el.tag == ns+'desc': track.desc = el.text
- elif el.tag == ns+'link': track.link = el.attrib['href']
- elif el.tag == ns+'type': track.type = el.text
- elif el.tag == ns+'trkseg':
- no_ele = 0
- for e in el:
- if e.tag == ns+'trkpt':
- trkpt = parse_wpt(e)
- track.points.append((trkpt.lat, trkpt.lon, trkpt.ele))
- if trkpt.ele is None: no_ele += 1
- elif e.tag == ns+'extensions': hints.append(Hint("XML element extensions within XML element trkpt is not used by WRGPX.", 1))
- if no_ele > 0: hints.append(Hint(u"%d of %d track points have not elevation (%s)" % (no_ele, len(track.points), unicode(track)), 1))
- wrgpx.tracks.append(track)
-
- # Extensions
- elif element.tag == ns+'extensions':
- hints.append(Hint("GPX file has a 'extensions' element. This is not used in WRGPX.", 1))
-
- if not wrgpx_has_metadata: hints.append(Hint("GPX file has a no metadata (like author, ...).", 2))
- return (wrgpx, hints)
-
-
+ """Parses a WRGPX file and returns a tuple of a data structure representing the content of the GPX file
+ and a list of Hint classes. If the file is not well-formed or not an GPX 1.1 file, an etree.XMLSyntaxError exception is raised."""
+ hints = []
+ wrgpx = WrGpx()
+
+ ns = '{http://www.topografix.com/GPX/1/1}'
+
+ def parse_wpt(element):
+ waypoint = Waypoint()
+ waypoint.lat = float(element.attrib['lat'])
+ waypoint.lon = float(element.attrib['lon'])
+ for el in element:
+ if el.tag == ns+'ele': waypoint.ele = float(el.text)
+ elif el.tag == ns+'name': waypoint.name = el.text
+ elif el.tag == ns+'desc': waypoint.desc = el.text
+ elif el.tag == ns+'link': waypoint.link = el.attrib['href']
+ elif el.tag == ns+'type': waypoint.type = el.text
+ return waypoint
+
+ schema = etree.XMLSchema(file=os.path.dirname(os.path.realpath(__file__)) + os.sep + 'gpx_1_1.xsd')
+ parser = etree.XMLParser(schema=schema)
+ if not string is None: root = etree.fromstring(string, parser)
+ else:
+ # xml = etree.parse(open(filename, 'rb'), parser)
+ xml = etree.parse(filename, parser)
+ root = xml.getroot()
+ assert root.tag == ns + 'gpx' # Nothing else should be possible after validation
+
+ wrgpx_has_metadata = False
+ for element in root:
+ # Metadata
+ if element.tag == ns+'metadata':
+ wrgpx_has_metadata = True
+ for el in element:
+ if el.tag == ns+'name': wrgpx.metadata.name = el.text
+ elif el.tag == ns+'desc': wrgpx.metadata.desc = el.text
+ elif el.tag == ns+'author':
+ for e in el:
+ if e.tag == ns+'name': wrgpx.metadata.author = e.text
+ elif e.tag == ns+'email':
+ wrgpx.metadata.author_email = e.attrib['id'] + '@' + e.attrib['domain']
+ elif el.tag == ns+'copyright':
+ for e in el:
+ if e.tag == ns+'year': wrgpx.metadata.copyright_year = int(e.text)
+ elif e.tag == ns+'license': wrgpx.metadata.license = e.text
+ elif el.tag == ns+'link': wrgpx.metadata.link = el.attrib['href']
+ elif el.tag == ns+'time':
+ wrgpx.metadata.time = datetime.datetime.strptime(el.text, '%Y-%m-%dT%H:%M:%SZ') # '2008-11-10T20:44:52Z'
+ elif el.tag == ns+'bounds':
+ wrgpx.metadata.minlat = float(el.attrib['minlat'])
+ wrgpx.metadata.minlon = float(el.attrib['minlon'])
+ wrgpx.metadata.maxlat = float(el.attrib['maxlat'])
+ wrgpx.metadata.maxlon = float(el.attrib['maxlon'])
+ elif el.tag == ns+'extensions': hints.append(Hint("XML element extensions within XML element metadata is not used by WRGPX.", 2))
+
+ # Waypoints
+ elif element.tag == ns+'wpt':
+ waypoint = parse_wpt(element)
+ wrgpx.waypoints.append(waypoint)
+ if waypoint.ele is None: hints.append(Hint(_(u"Elevation of waypoint '%s' should be given.") % unicode(waypoint), 1))
+ if waypoint.name is None: hints.append(Hint(_(u"Name of waypoint '%s' must be given.") % unicode(waypoint), 2))
+ if waypoint.type is None: hints.append(Hint(_(u"Type of waypoint '%s' must be given (Gasthaus, Bushaltestelle, ...)") % unicode(waypoint), 2))
+ if not waypoint.type in ['Gasthaus', 'Parkplatz', 'Bushaltestelle']: hints.append(Hint(_(u"Type of the waypoint '%s' has to be one of (Gasthaus, Bushaltestelle, ...)") % unicode(waypoint), 2))
+
+ # Routes
+ elif element.tag == ns+'rte':
+ hints.append(Hint(_("GPX file has a 'rte' element. This is not used in WRGPX."), 2))
+
+ # Tracks
+ elif element.tag == ns+'trk':
+ track = Track()
+ for el in element:
+ if el.tag == ns+'name': track.name = el.text
+ elif el.tag == ns+'desc': track.desc = el.text
+ elif el.tag == ns+'link': track.link = el.attrib['href']
+ elif el.tag == ns+'type': track.type = el.text
+ elif el.tag == ns+'trkseg':
+ no_ele = 0
+ for e in el:
+ if e.tag == ns+'trkpt':
+ trkpt = parse_wpt(e)
+ track.points.append((trkpt.lat, trkpt.lon, trkpt.ele))
+ if trkpt.ele is None: no_ele += 1
+ elif e.tag == ns+'extensions': hints.append(Hint(_("XML element extensions within XML element trkpt is not used by WRGPX."), 2))
+ if no_ele > 0: hints.append(Hint(_(u"%d of %d track points have no elevation (%s).") % (no_ele, len(track.points), unicode(track)), 1))
+ if len(track.points) == 0: hints.append(Hint(_(u"track '%s' is empty.") % unicode(track), 2))
+ wrgpx.tracks.append(track)
+
+ # Extensions
+ elif element.tag == ns+'extensions':
+ hints.append(Hint(_("GPX file has a 'extensions' element. This is not used in WRGPX."), 2))
+
+ if not wrgpx_has_metadata: hints.append(Hint(_("GPX file has a no metadata (like author, ...)."), 2))
+ return (wrgpx, hints)
+
+
+def height_profile(wrgpx):
+ "Create a elevation profile for the wrgpx class. Raises a RuntimError in case of an error, otherwise returns the PNG file as string."
+ proj_utm32 = mapnik.Projection("+proj=utm +zone=32 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")
+ bahntracks = [t for t in wrgpx.tracks if t.type=='Rodelbahn' and len(t.points) > 0]
+ if len(bahntracks) == 0: raise RuntimeError(_(u"There is no 'Rodelbahn' type track in the GPX file."))
+
+ # Descending order and check
+ for track in bahntracks:
+ if track.points[0][2] is None or track.points[-1][2] is None: raise RuntimeError(_(u'Track has no elevation data'))
+ if track.points[0][2] < track.points[-1][2]: track.points[:] = track.points[::-1]
+ bahntracks.sort(lambda x, y: -1 if x.points[0][2] > y.points[0][2] else 1)
+ points = []
+ for track in bahntracks: points.extend(track.points)
+
+ points = np.array(points)
+ for i in xrange(len(points)):
+ c = mapnik.Coord(points[i][1], points[i][0])
+ c = c.forward(proj_utm32)
+ points[i][0] = c.y
+ points[i][1] = c.x
+
+ # Calculate profile
+ s = np.sqrt(np.diff(points[:, 0]) ** 2 + np.diff(points[:, 1]) ** 2)
+ x = np.hstack((0, np.cumsum(s)))
+ h = points[:, 2]
+
+ # Plot
+ axxmin = 0
+ axxmax = x[-1]
+ axymin = np.floor_divide(min(h)-50, 100)*100
+ axymax = np.floor_divide(max(h)+150, 100)*100
+ f = plt.figure()
+ plt.fill(np.hstack((x, x[-1], x[0])), np.hstack((h, 0, 0)), fc='#014e9a', ec='none')
+ plt.plot(x, h, color='black')
+ plt.axis([axxmin, axxmax, axymin, axymax])
+ plt.grid()
+ plt.xlabel(u'Strecke in m [%d m Gesamtstrecke]' % round(x[-1], -1))
+ plt.ylabel(u'Höhe in m [%d m Differenz]' % round(h[0]-h[-1]))
+ plt.title(u'%s - Höhenprofil' % wrgpx.metadata.name)
+
+ width_px = 500
+ imgdata = StringIO.StringIO()
+ f.savefig(imgdata, dpi=width_px/plt.gcf().get_figwidth())
+ s = imgdata.getvalue()
+ imgdata.close()
+ return s