Changed parse_wrmap to corresponding to the new definition of wrmap and geojson.
authorphilipp <philipp@7aebc617-e5e2-0310-91dc-80fb5f6d2477>
Mon, 26 Aug 2013 20:49:20 +0000 (20:49 +0000)
committerphilipp <philipp@7aebc617-e5e2-0310-91dc-80fb5f6d2477>
Mon, 26 Aug 2013 20:49:20 +0000 (20:49 +0000)
git-svn-id: http://www.winterrodeln.org/svn/wrpylib/trunk@1527 7aebc617-e5e2-0310-91dc-80fb5f6d2477

tests/test_wrmwmarkup.py
wrpylib/wrmwmarkup.py

index d015722003bf022b65a9f95d8570d8c79831998d..5ebfe1f6980f0c4f512ddefa854654ace5b84278 100644 (file)
@@ -104,22 +104,22 @@ def test_parse_wrmap():
     </rodelbahn>
     </wrmap>
     '''
-    attributes, json = wrpylib.wrmwmarkup.parse_wrmap(wikitext)
-    assert attributes['lon'] == 11.21408895
-    assert attributes['lat'] == 47.2417134
-    assert attributes['zoom'] == 14
-    assert attributes['width'] == 700
-    assert attributes['height'] == 400
-    assert json['features'][0]['properties']['type'] == 'inn'
+    json = wrpylib.wrmwmarkup.parse_wrmap(wikitext)
+    assert json['properties']['lon'] == 11.21408895
+    assert json['properties']['lat'] == 47.2417134
+    assert json['properties']['zoom'] == 14
+    assert json['properties']['width'] == 700
+    assert json['properties']['height'] == 400
+    assert json['features'][0]['properties']['type'] == 'gasthaus'
     assert json['features'][0]['properties']['name'] == u'Rosskogelhütte'
     assert json['features'][0]['properties']['wiki'] == u'Rosskogelhütte'
     assert json['features'][0]['geometry']['coordinates'] == [11.190454, 47.240689]
-    assert json['features'][1]['properties']['type'] == 'carpark'
+    assert json['features'][1]['properties']['type'] == 'parkplatz'
     assert json['features'][1]['geometry']['coordinates'] == [11.238971, 47.245789]
-    assert json['features'][2]['properties']['type'] == 'busstop'
+    assert json['features'][2]['properties']['type'] == 'haltestelle'
     assert json['features'][2]['properties']['name'] == u'Oberperfuss Rangger Köpfl Lift'
     assert json['features'][2]['geometry']['coordinates'] == [11.238283, 47.245711]
-    assert json['features'][3]['properties']['type'] == 'sledrun'
+    assert json['features'][3]['properties']['type'] == 'rodelbahn'
     assert json['features'][3]['geometry']['coordinates'] == [
         [11.203360, 47.238587],
         [11.230868, 47.244951],
@@ -132,25 +132,25 @@ def test_create_wrmap():
         'type': 'FeatureCollection',
         'features':
             [{
-                'type': 'feature',
+                'type': 'Feature',
                 'geometry': {
                     'type': 'Point',
                     'coordinates': [11.190454, 47.240689]},
                 'properties': {'type': 'inn', 'name': u'Rosskogelhütte', 'wiki': u'Rosskogelhütte'}
             }, {
-                'type': 'feature',
+                'type': 'Feature',
                 'geometry': {
                     'type': 'Point',
                     'coordinates': [11.238971, 47.245789]},
                 'properties': {'type': 'carpark'}
             }, {
-                'type': 'feature',
+                'type': 'Feature',
                 'geometry': {
                     'type': 'Point',
                     'coordinates': [11.238283, 47.245711]},
                 'properties': {'type': 'busstop', 'name': u'Oberperfuss Rangger Köpfl Lift'}
             }, {
-                'type': 'feature',
+                'type': 'Feature',
                 'geometry': {
                     'type': 'LineString',
                     'coordinates': [
index c9aba4ffa40c5de9957f9ed053fe85dbfe7dbbba..a27525b292ad21ee3b4e03c53520beff36d34a04 100644 (file)
@@ -10,8 +10,14 @@ import formencode
 import wrpylib.wrvalidators
 import wrpylib.mwmarkup
 
-WRMAP_POINT_TYPE = {'gasthaus': 'inn', 'haltestelle': 'busstop', 'parkplatz': 'carpark', 'achtung': 'attention', 'punkt': 'point'}
-WRMAP_LINE_TYPE = {'rodelbahn': 'sledrun', 'gehweg': 'walk', 'alternative': 'alternative', 'lift': 'lift', 'linie': 'line'}
+WRMAP_POINT_TYPES = ['gasthaus', 'haltestelle', 'parkplatz', 'achtung', 'punkt']
+WRMAP_LINE_TYPE = ['rodelbahn', 'gehweg', 'alternative', 'lift', 'linie']
+
+
+class ParseError(RuntimeError):
+    """Exception used by some of the functions"""
+    pass
+
 
 def _conv(fnct, value, fieldname):
     """Internal function.
@@ -390,8 +396,8 @@ def parse_wrmap_coordinates(coords):
 
 def parse_wrmap(wikitext):
     """Parses the (unicode) u'<wrmap ...>content</wrmap>' of the Winterrodeln wrmap extension
-    out of a page. If wikitext does not contain the googlemaps extension text None is returned.
-    If the googlemap contains invalid formatted lines, a RuntimeError is raised.
+    out of a page. If wikitext does not contain the wrmap extension text None is returned.
+    If the wrmap contains invalid formatted lines, a ParseError is raised.
 
     :param wikitext: wikitext containing the template. Example:
 
@@ -407,91 +413,85 @@ def parse_wrmap(wikitext):
     </rodelbahn>
     </wrmap>
     '''
-    :returns: (attributes, GeoJSON as Python datatypes)
+    :returns: GeoJSON as nested Python datatype
     """
     # parse XML
     try:
         wrmap_xml = xml.etree.ElementTree.fromstring(wikitext.encode('utf-8'))
     except xml.etree.ElementTree.ParseError as e:
         row, column = e.position
-        raise RuntimeError("XML parse error on row {}, column {}: {}".format(row, column, e))
-    # assert(in_array($tagname, array('wrmap', 'wrgmap'))); # TODO
+        raise ParseError("XML parse error on row {}, column {}: {}".format(row, column, e))
+    if wrmap_xml.tag not in ['wrmap', 'wrgmap']:
+        raise ParseError('No valid tag name')
 
     # convert XML to geojson (http://www.geojson.org/geojson-spec.html)
     json_features = []
     for feature in wrmap_xml:
         # determine feature type
-        is_point = WRMAP_POINT_TYPE.has_key(feature.tag)
-        is_line = WRMAP_LINE_TYPE.has_key(feature.tag)
+        is_point = feature.tag in WRMAP_POINT_TYPE
+        is_line = feature.tag in WRMAP_LINE_TYPE
         if (not is_point and not is_line):
-            raise RuntimeError('Unknown element <{}>.'.format(feature.tag))
+            raise ParseError('Unknown element <{}>.'.format(feature.tag))
 
         # point
         if is_point:
-            properties = {'type': WRMAP_POINT_TYPE[feature.tag]}
+            properties = {'type': feature.tag}
             allowed_properties = set(['name', 'wiki'])
             wrong_properties = set(feature.attrib.keys()) - allowed_properties
             if len(wrong_properties) > 0:
-                raise RuntimeError("The attribute '{}' is not allowed at <{}>.".format(list(wrong_properties)[0], feature.tag))
+                raise ParseError("The attribute '{}' is not allowed at <{}>.".format(list(wrong_properties)[0], feature.tag))
             properties.update(feature.attrib)
             coordinates = parse_wrmap_coordinates(feature.text)
             if len(coordinates) != 1:
-                raise RuntimeError('The element <{}> has to have exactly one coordinate pair.'.format(feature.tag))
+                raise ParseError('The element <{}> has to have exactly one coordinate pair.'.format(feature.tag))
             json_features.append({
-                'type': 'feature',
+                'type': 'Feature',
                 'geometry': {'type': 'Point', 'coordinates': coordinates[0]},
                 'properties': properties})
 
         # line
         if is_line:
-            properties = {'type': WRMAP_LINE_TYPE[feature.tag]}
+            properties = {'type': feature.tag}
             allowed_properties = set(['farbe', 'dicke'])
             wrong_properties = set(feature.attrib.keys()) - allowed_properties
             if len(wrong_properties) > 0:
-                raise RuntimeError("The attribute '{}' is not allowed at <{}>.".format(list(wrong_properties)[0], feature.tag))
+                raise ParseError("The attribute '{}' is not allowed at <{}>.".format(list(wrong_properties)[0], feature.tag))
             if feature.attrib.has_key('farbe'): 
                 if not re.match('#[0-9a-fA-F]{6}$', feature.attrib['farbe']):
-                    raise RuntimeError('The attribute "farbe" has to have a format like "#a0bb43".')
+                    raise ParseError('The attribute "farbe" has to have a format like "#a0bb43".')
                 properties['strokeColor'] = feature.attrib['farbe'] # e.g. #a200b7
             if feature.attrib.has_key('dicke'):
                 try:
                     properties['strokeWidth'] = int(feature.attrib['dicke']) # e.g. 6
                 except ValueError:
-                    raise RuntimeError('The attribute "dicke" has to be an integer.')
+                    raise ParseError('The attribute "dicke" has to be an integer.')
             json_features.append({
-                'type': 'feature',
+                'type': 'Feature',
                 'geometry': {'type': 'LineString', 'coordinates': parse_wrmap_coordinates(feature.text)},
                 'properties': properties})
 
+    # attributes
+    properties = {}
+    for k, v in wrmap_xml.attrib.iteritems():
+        if k in ['lat', 'lon']:
+            try:
+                properties[k] = float(v)
+            except ValueError:
+                raise ParseError('Attribute "{}" has to be a float value.'.format(k))
+        elif k in ['zoom', 'width', 'height']:
+            try:
+                properties[k] = int(v)
+            except ValueError:
+                raise ParseError('Attribute "{}" has to be an integer value.'.format(k))
+        else:
+            raise ParseError('Unknown attribute "{}".'.format(k))
+
     geojson = {
         'type': 'FeatureCollection',
-        'features': json_features}
-
-    # attributes
-    attributes = {}
-    try:
-        attributes['lat'] = float(wrmap_xml.attrib.get('lat', 47.267648)) # center lat
-    except ValueError:
-        raise RuntimeError('Attribute "lat" has to be a float value.')
-    try:
-        attributes['lon'] = float(wrmap_xml.attrib.get('lon', 11.404655)) # center lon
-    except ValueError:
-        raise RuntimeError('Attribute "lon" has to be a float value.')
-    try:
-        attributes['zoom'] = int(wrmap_xml.attrib.get('zoom', 10)) # Google Zoom Level
-    except ValueError:
-        raise RuntimeError('Attribute "zoom" has to be an integer value.')
-    try:
-        attributes['width'] = int(wrmap_xml.attrib['width']) if wrmap_xml.attrib.has_key('width') else None # None corresponds to 100%
-    except ValueError:
-        raise RuntimeError('Attribute "width" has to be an integer value.')
-    try:
-        attributes['height'] = int(wrmap_xml.attrib.get('height', 450)) # map height in px
-    except ValueError:
-        raise RuntimeError('Attribute "height" has to be an integer value.')
-    # show_sledruns = (wrmap_xml.tag == 'wrgmap')
+        'features': json_features,
+        'properties': properties}
 
-    return attributes, geojson
+    return geojson
 
 
 def create_wrmap_coordinates(coords):