]> ToastFreeware Gitweb - philipp/winterrodeln/wradmin.git/commitdiff
Coordinate tool works again.
authorphilipp <philipp@7aebc617-e5e2-0310-91dc-80fb5f6d2477>
Sun, 30 Jul 2017 21:26:02 +0000 (21:26 +0000)
committerphilipp <philipp@7aebc617-e5e2-0310-91dc-80fb5f6d2477>
Sun, 30 Jul 2017 21:26:02 +0000 (21:26 +0000)
git-svn-id: http://www.winterrodeln.org/svn/wradmin/trunk@2692 7aebc617-e5e2-0310-91dc-80fb5f6d2477

wradmin/__init__.py
wradmin/controllers/coordtool.py
wradmin/templates/coordtool.html

index 1f7850b85eae98054a57561cee94f6097bfe1f23..780492872d8c54aa44ac2a640982b6da32a1328d 100644 (file)
@@ -8,6 +8,7 @@ from wradmin.genshi import render_genshi_template
 from wradmin.controllers.rodelbahn import RodelbahnController
 from wradmin.controllers.gasthaus import GasthausController
 from wradmin.controllers.bericht import BerichtController
+from wradmin.controllers.coordtool import CoordtoolController
 
 
 app = Flask(__name__)
@@ -99,4 +100,9 @@ def gasthaus_update():
 
 @app.route("/coordtool/index")
 def coordtool_index():
-    pass
+    return CoordtoolController().index()
+
+
+@app.route("/coordtool/convert", methods=['POST'])
+def coordtool_convert():
+    return CoordtoolController().convert()
index 1b77e06ba8f8a261f1c9e231efebb95f59c6f77e..1aefbc947dfca3618f61651279e68ebf19402c9c 100644 (file)
 #!/usr/bin/python3.4
-import logging
+import re
+import xml.dom.minidom as minidom
+from xml.parsers.expat import ExpatError
+from enum import IntEnum
+from flask import request, redirect, url_for, flash
+from wradmin.genshi import render_genshi_template, TemplateContext
 
-from pylons import request, response, session, url, tmpl_context as c
-from pylons.controllers.util import abort, redirect
-import formencode
 
-from wradmin.lib.base import BaseController, render
-import wrpylib.wrvalidators
+class MultiGeo(IntEnum):
+    """Formats multiple coordinates, even in multiple lines to [(latitude, longitude, elevation), ...] 
+    or [(latitude, longitude, None), ...] tuples."""
 
-log = logging.getLogger(__name__)
+    # Valid for input_format
+    FORMAT_GUESS = 0  # guesses the input format; default for input_format
+    FORMAT_NONE = -1  # indicates missing formats
 
-class CoordtoolController(BaseController):
+    # Valid for input_format and output_format
+    FORMAT_GEOCACHING = 1  # e.g. "N 47° 13.692 E 011° 25.535"
+    FORMAT_WINTERRODELN = 2  # e.g. "47.222134 N 11.467211 E"
+    FORMAT_GMAPPLUGIN = 3  # e.g. "47.232922, 11.452239"
+    FORMAT_GPX = 4  # e.g. "<trkpt lat="47.181289" lon="11.408827"><ele>1090.57</ele></trkpt>"
+
+
+def multigeo_from_string(value, input_format):
+    assert input_format in [MultiGeo.FORMAT_GUESS, MultiGeo.FORMAT_GEOCACHING, MultiGeo.FORMAT_WINTERRODELN,
+                            MultiGeo.FORMAT_GMAPPLUGIN, MultiGeo.FORMAT_GPX], "input_format %d is not recognized"
+    lines = [line.strip() for line in value.split("\n") if len(line.strip()) > 0]
+
+    result = []
+    for line in lines:
+        if input_format == MultiGeo.FORMAT_GUESS or input_format == MultiGeo.FORMAT_GEOCACHING:
+            r = re.match('N ?(\d+)° ?(\d+\.\d+) +E ?(\d+)° ?(\d+\.\d+)', line)
+            if r is not None:
+                g = r.groups()
+                result.append((float(g[0]) + float(g[1]) / 60, float(g[2]) + float(g[3]) / 60, None))
+                continue
+
+        if input_format == MultiGeo.FORMAT_GUESS or input_format == MultiGeo.FORMAT_WINTERRODELN:
+            r = re.match('(\d+\.\d+) N (\d+\.\d+) E', line)
+            if not r is None:
+                result.append((float(r.groups()[0]), float(r.groups()[1]), None))
+                continue
+
+        if input_format == MultiGeo.FORMAT_GUESS or input_format == MultiGeo.FORMAT_GMAPPLUGIN:
+            r = re.match('(\d+\.\d+), ?(\d+\.\d+)', line)
+            if r is not None:
+                result.append((float(r.groups()[0]), float(r.groups()[1]), None))
+                continue
+
+        if input_format == MultiGeo.FORMAT_GUESS or input_format == MultiGeo.FORMAT_GPX:
+            try:
+                xml = minidom.parseString(line)
+                coord = xml.documentElement
+                lat = float(coord.getAttribute('lat'))
+                lon = float(coord.getAttribute('lon'))
+                try:
+                    ele = float(coord.childNodes[0].childNodes[0].nodeValue)
+                except (IndexError, ValueError):
+                    ele = None
+                result.append((lat, lon, ele))
+                continue
+            except (ExpatError, IndexError, ValueError):
+                pass
+
+        raise ValueError("Coordinates '%s' have no known format" % line, value)
+    return result
+
+
+def multigeo_to_string(value, output_format):
+    result = []
+    for latitude, longitude, height in value:
+        if output_format == MultiGeo.FORMAT_GEOCACHING:
+            result.append(
+                'N %02d° %02.3f E %03d° %02.3f' % (latitude, latitude % 1 * 60, longitude, longitude % 1 * 60))
+
+        elif output_format == MultiGeo.FORMAT_WINTERRODELN:
+            result.append('%.6f N %.6f E' % (latitude, longitude))
+
+        elif output_format == MultiGeo.FORMAT_GMAPPLUGIN:
+            result.append('%.6f, %.6f' % (latitude, longitude))
+
+        elif output_format == MultiGeo.FORMAT_GPX:
+            if not height is None:
+                result.append(
+                    '<trkpt lat="%.6f" lon="%.6f"><ele>%.2f</ele></trkpt>' % (latitude, longitude, height))
+            else:
+                result.append('<trkpt lat="%.6f" lon="%.6f"/>' % (latitude, longitude))
+
+        else:
+            raise ValueError("output_format %d is not recognized" % output_format, value)
+
+    return "\n".join(result)
+
+
+class CoordtoolController:
 
     def index(self):
+        c = TemplateContext()
         c.result = None
-        return render('coordtool.html')
-    
+        return render_genshi_template('coordtool.html', c=c)
 
     def convert(self):
-        input = request.POST['input']
-        no_elevation = 'no_elevation' in request.POST
-        simplify = 'simplify' in request.POST
-        swap_latlon = 'swap_latlon' in request.POST
-        c.no_geoformat = 'no_geoformat' in request.POST
-        c.no_gpxformat = 'no_gpxformat' in request.POST
-        c.no_gmapsformat = 'no_gmapsformat' in request.POST
-        c.no_geocachingformat = 'no_geocachingformat' in request.POST
+        c = TemplateContext()
+        assert request.method == 'POST'
+        input = request.form['input']
+        no_elevation = 'no_elevation' in request.form
+        simplify = 'simplify' in request.form
+        swap_latlon = 'swap_latlon' in request.form
+        c.no_geoformat = 'no_geoformat' in request.form
+        c.no_gpxformat = 'no_gpxformat' in request.form
+        c.no_gmapsformat = 'no_gmapsformat' in request.form
+        c.no_geocachingformat = 'no_geocachingformat' in request.form
         
         if input is None or len(input.strip()) == 0: 
             c.result = None
-            return redirect(url(controller='coordtool', action='index'))
+            return redirect(url_for('coordtool_index'))
         
-        geo = wrpylib.wrvalidators.MultiGeo()
-        try: c.result = geo.to_python(input)
-        except formencode.Invalid as e:
-            session['flash'] = str(e)
-            session.save()
-            return redirect(url(controller='coordtool', action='index'))
+        try:
+            c.result = multigeo_from_string(input, MultiGeo.FORMAT_GUESS)
+        except ValueError as e:
+            flash(str(e))
+            return redirect(url_for('coordtool_index'))
         
         if swap_latlon:
             c.result = [(latitude, longitude, elevation) for (longitude, latitude, elevation) in c.result]
@@ -44,9 +128,9 @@ class CoordtoolController(BaseController):
         if no_elevation:
             c.result = [(longitude, latitude, None) for (longitude, latitude, elevation) in c.result]
         
-        c.geo_winterrodeln = wrpylib.wrvalidators.MultiGeo(output_format = geo.FORMAT_WINTERRODELN)
-        c.geo_gmapplugin = wrpylib.wrvalidators.MultiGeo(output_format = geo.FORMAT_GMAPPLUGIN)
-        c.geo_gpx = wrpylib.wrvalidators.MultiGeo(output_format = geo.FORMAT_GPX)
-        c.geo_geocaching = wrpylib.wrvalidators.MultiGeo(output_format = geo.FORMAT_GEOCACHING)
+        c.geo_winterrodeln = lambda value: multigeo_to_string(value, MultiGeo.FORMAT_WINTERRODELN)
+        c.geo_gmapplugin = lambda value: multigeo_to_string(value, MultiGeo.FORMAT_GMAPPLUGIN)
+        c.geo_gpx = lambda value: multigeo_to_string(value, MultiGeo.FORMAT_GPX)
+        c.geo_geocaching = lambda value: multigeo_to_string(value, MultiGeo.FORMAT_GEOCACHING)
         
-        return render('coordtool.html')
+        return render_genshi_template('coordtool.html', c=c)
index 6d1e6ede67c9b05f6d519a81df3431f991bd9651..3e5792ef4008eb9b4b2b00a881b0444a3589e17e 100644 (file)
 
 <h3 py:if="c.result and not c.no_geoformat">Winterrodeln-Format</h3>
 <p py:if="c.result and not c.no_geoformat">
-    <py:for each="line in c.result">${c.geo_winterrodeln.from_python([line])}<br/></py:for>
+    <py:for each="line in c.result">${c.geo_winterrodeln([line])}<br/></py:for>
 </p>
 
 <h3 py:if="c.result and not c.no_gmapsformat">Google Maps Plugin Format</h3>
 <p py:if="c.result and not c.no_gmapsformat">
-    <py:for each="line in c.result">${c.geo_gmapplugin.from_python([line])}<br/></py:for>
+    <py:for each="line in c.result">${c.geo_gmapplugin([line])}<br/></py:for>
 </p>
 
 <h3 py:if="c.result and not c.no_gpxformat">GPX Format</h3>
 <p py:if="c.result and not c.no_gpxformat">
-    <py:for each="line in c.result">${c.geo_gpx.from_python([line])}<br/></py:for>
+    <py:for each="line in c.result">${c.geo_gpx([line])}<br/></py:for>
 </p>
 
 <h3 py:if="c.result and not c.no_geocachingformat">Geocaching-Format</h3>
 <p py:if="c.result and not c.no_geocachingformat">
-    <py:for each="line in c.result">${c.geo_geocaching.from_python([line])}<br/></py:for>
+    <py:for each="line in c.result">${c.geo_geocaching([line])}<br/></py:for>
 </p>
 
 <form action="${h.url(controller='coordtool', action='convert')}" method="post">