2 # -*- coding: iso-8859-15 -*-
5 """This module contains winterrodeln specific functions that are prcocessing the MediaWiki markup.
8 import xml.etree.ElementTree
10 import wrpylib.wrvalidators
11 import wrpylib.mwmarkup
14 def _conv(fnct, value, fieldname):
16 Like one of the to_xxx functions (e.g. to_bool), but adds the field name to the error message"""
17 try: return fnct(value)
18 except formencode.Invalid as e: raise formencode.Invalid(u"Conversion error in field '%s': %s" % (fieldname, unicode(e)), e.value, e.state)
21 def rodelbahnbox_to_sledrun(wikitext, sledrun=None):
22 """Converts a sledrun wiki page containing the {{Rodelbahnbox}}
23 to a sledrun. sledrun may be an instance of WrSledrunCache or an "empty" class (object()) (default).
24 Raises a formencode.Invalid exception if the format is not OK or the Rodelbahnbox is not found.
25 :return: (start, end, sledrun) tuple of the Rodelbahnbox."""
27 class Sledrun(object): pass
31 start, end = wrpylib.mwmarkup.find_template(wikitext, u'Rodelbahnbox')
32 if start is None: raise formencode.Invalid(u"Rodelbahnbox nicht gefunden", wikitext, None)
33 template_title, properties = wrpylib.mwmarkup.split_template(wikitext[start:end])
36 for key, value in properties.iteritems():
37 if key == u'Position': sledrun.position_latitude, sledrun.position_longitude = _conv(wrpylib.wrvalidators.GeoNone().to_python, value, key) # '47.583333 N 15.75 E'
38 elif key == u'Position oben': sledrun.top_latitude, sledrun.top_longitude = _conv(wrpylib.wrvalidators.GeoNone().to_python, value, key) # '47.583333 N 15.75 E'
39 elif key == u'Höhe oben': sledrun.top_elevation = _conv(wrpylib.wrvalidators.UnsignedNone().to_python, value, key) # '2000'
40 elif key == u'Position unten': sledrun.bottom_latitude, sledrun.bottom_longitude = _conv(wrpylib.wrvalidators.GeoNone().to_python, value, key) # '47.583333 N 15.75 E'
41 elif key == u'Höhe unten': sledrun.bottom_elevation = _conv(wrpylib.wrvalidators.UnsignedNone().to_python, value, key) # '1200'
42 elif key == u'Länge': sledrun.length = _conv(wrpylib.wrvalidators.UnsignedNone().to_python, value, key) # 3500
43 elif key == u'Schwierigkeit': sledrun.difficulty = _conv(wrpylib.wrvalidators.GermanDifficulty().to_python, value, key) # 'mittel' elif key == u'Lawinen': sledrun.avalanches = _conv(wrpylib.wrvalidators.GermanAvalanches().to_python, value, key) # 'kaum'
44 elif key == u'Lawinen': sledrun.avalanches = _conv(wrpylib.wrvalidators.GermanAvalanches().to_python, value, key) # 'kaum'
45 elif key == u'Betreiber': sledrun.operator = _conv(wrpylib.wrvalidators.UnicodeNone().to_python, value, key) # 'Max Mustermann'
46 elif key == u'Öffentliche Anreise': sledrun.public_transport = _conv(wrpylib.wrvalidators.GermanPublicTransport().to_python, value, key) # 'Mittelmäßig'
47 elif key == u'Aufstieg möglich': sledrun.walkup_possible = _conv(wrpylib.wrvalidators.GermanBoolNone().to_python, value, key) # 'Ja'
48 elif key == u'Aufstieg getrennt': sledrun.walkup_separate, sledrun.walkup_separate_comment = _conv(wrpylib.wrvalidators.GermanTristateFloatComment().to_python, value, key) # 'Ja'
49 elif key == u'Gehzeit': sledrun.walkup_time = _conv(wrpylib.wrvalidators.UnsignedNone().to_python, value, key) # 90
50 elif key == u'Aufstiegshilfe': sledrun.lift, sledrun.lift_details = _conv(wrpylib.wrvalidators.GermanLift().to_python, value, key) # 'Gondel (unterer Teil)'
51 elif key == u'Beleuchtungsanlage': sledrun.night_light, sledrun.night_light_comment = _conv(wrpylib.wrvalidators.GermanTristateFloatComment().to_python, value, key)
52 elif key == u'Beleuchtungstage': sledrun.night_light_days, sledrun.night_light_days_comment = _conv(wrpylib.wrvalidators.UnsignedCommentNone(7).to_python, value, key) # '3 (Montag, Mittwoch, Freitag)'
53 elif key == u'Rodelverleih': sledrun.sled_rental, sledrun.sled_rental_comment = _conv(wrpylib.wrvalidators.SledRental().to_python, value, key) # 'Talstation Serlesbahnan'
54 elif key == u'Gütesiegel': sledrun.cachet = _conv(wrpylib.wrvalidators.GermanCachet().to_python, value, key) # 'Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'
55 elif key == u'Webauskunft': sledrun.information_web = _conv(wrpylib.wrvalidators.UrlNeinNone().to_python, value, key) # 'http://www.nösslachhütte.at/page9.php'
56 elif key == u'Telefonauskunft': sledrun.information_phone = _conv(wrpylib.wrvalidators.PhoneCommentListNeinLoopNone(comments_are_optional=False).to_python, value, key) # '+43-664-5487520 (Mitterer Alm)'
57 elif key == u'Bild': sledrun.image = _conv(wrpylib.wrvalidators.UnicodeNone().to_python, value, key)
58 elif key == u'In Übersichtskarte': sledrun.show_in_overview = _conv(wrpylib.wrvalidators.GermanBoolNone().to_python, value, key)
59 elif key == u'Forumid': sledrun.forum_id = _conv(wrpylib.wrvalidators.UnsignedNeinNone().to_python, value, key)
60 else: raise formencode.Invalid(u"Unbekannte Eigenschaft der Rodelbahnbox: '%s' (mit Wert '%s')" % (key, value), value, None)
61 return start, end, sledrun
64 def sledrun_to_rodelbahnbox(sledrun, version):
65 """Converts a sledrun class to the {{Rodelbahnbox}} representation.
66 The sledrun class has to have properties like position_latitude, ...
67 See the table sledruncache for field (column) values.
68 :param sledrun: an arbitrary class that contains the right properties
69 :param version: a string specifying the version of the rodelbahnbox zu produce.
70 Version '1.3' and '1.4' are supported."""
73 keys.append(u'Position')
74 values.append(wrpylib.wrvalidators.GeoNone().from_python((sledrun.position_latitude, sledrun.position_longitude)))
75 keys.append(u'Position oben')
76 values.append(wrpylib.wrvalidators.GeoNone().from_python((sledrun.top_latitude, sledrun.top_longitude)))
77 keys.append(u'Höhe oben')
78 values.append(wrpylib.wrvalidators.UnsignedNone().from_python(sledrun.top_elevation))
79 keys.append(u'Position unten')
80 values.append(wrpylib.wrvalidators.GeoNone().from_python((sledrun.bottom_latitude, sledrun.bottom_longitude)))
81 keys.append(u'Höhe unten')
82 values.append(wrpylib.wrvalidators.UnsignedNone().from_python(sledrun.bottom_elevation))
84 values.append(wrpylib.wrvalidators.UnsignedNone().from_python(sledrun.length))
85 keys.append(u'Schwierigkeit')
86 values.append(wrpylib.wrvalidators.GermanDifficulty().from_python(sledrun.difficulty))
87 keys.append(u'Lawinen')
88 values.append(wrpylib.wrvalidators.GermanAvalanches().from_python(sledrun.avalanches))
89 keys.append(u'Betreiber')
90 values.append(wrpylib.wrvalidators.UnicodeNone().from_python(sledrun.operator))
91 keys.append(u'Öffentliche Anreise')
92 values.append(wrpylib.wrvalidators.GermanPublicTransport().from_python(sledrun.public_transport))
94 keys.append(u'Aufstieg möglich')
95 values.append(wrpylib.wrvalidators.GermanBoolNone().from_python(sledrun.walkup_possible))
96 keys.append(u'Aufstieg getrennt')
97 values.append(wrpylib.wrvalidators.GermanTristateFloatComment().from_python((sledrun.walkup_separate, sledrun.walkup_separate_comment)))
98 keys.append(u'Gehzeit')
99 values.append(wrpylib.wrvalidators.UnsignedNone().from_python(sledrun.walkup_time))
100 keys.append(u'Aufstiegshilfe')
101 values.append(wrpylib.wrvalidators.GermanLift().from_python((sledrun.lift, sledrun.lift_details)))
102 keys.append(u'Beleuchtungsanlage')
103 values.append(wrpylib.wrvalidators.GermanTristateFloatComment().from_python((sledrun.night_light, sledrun.night_light_comment)))
104 keys.append(u'Beleuchtungstage')
105 values.append(wrpylib.wrvalidators.UnsignedCommentNone(max=7).from_python((sledrun.night_light_days, sledrun.night_light_days_comment)))
106 keys.append(u'Rodelverleih')
107 values.append(wrpylib.wrvalidators.SledRental().from_python((sledrun.sled_rental, sledrun.sled_rental_comment)))
108 keys.append(u'Gütesiegel')
109 values.append(wrpylib.wrvalidators.GermanCachet().from_python(sledrun.cachet))
110 keys.append(u'Webauskunft')
111 values.append(wrpylib.wrvalidators.UrlNeinNone().from_python(sledrun.information_web))
112 keys.append(u'Telefonauskunft')
113 values.append(wrpylib.wrvalidators.PhoneCommentListNeinLoopNone(comments_are_optional=False).from_python(sledrun.information_phone))
115 values.append(wrpylib.wrvalidators.UnicodeNone().from_python(sledrun.image))
116 keys.append(u'In Übersichtskarte')
117 values.append(wrpylib.wrvalidators.GermanBoolNone().from_python(sledrun.show_in_overview))
118 keys.append(u'Forumid')
119 values.append(wrpylib.wrvalidators.UnsignedNeinNone().from_python(sledrun.forum_id))
120 return wrpylib.mwmarkup.create_template(u'Rodelbahnbox', [], keys, values, True, 20)
123 def gasthausbox_to_inn(wikitext, inn=None):
124 """Converts a inn wiki page containing a {{Gasthausbox}} to an inn.
125 raises a formencode.Invalid exception if an error occurs.
126 :return: (start, end, inn) tuple."""
128 class Inn(object): pass
132 start, end = wrpylib.mwmarkup.find_template(wikitext, u'Gasthausbox')
133 if start is None: raise formencode.Invalid(u"No 'Gasthausbox' found", wikitext, None)
134 template_title, properties = wrpylib.mwmarkup.split_template(wikitext[start:end])
137 for key, value in properties.iteritems():
138 if key == u'Position': inn.position_latitude, inn.position_longitude = _conv(wrpylib.wrvalidators.GeoNone().to_python, value, key) # '47.583333 N 15.75 E'
139 elif key == u'Höhe': inn.position_elevation = _conv(wrpylib.wrvalidators.UnsignedNone().to_python, value, key)
140 elif key == u'Betreiber': inn.operator = _conv(wrpylib.wrvalidators.UnicodeNone().to_python, value, key)
141 elif key == u'Sitzplätze': inn.seats = _conv(wrpylib.wrvalidators.UnsignedNone().to_python, value, key)
142 elif key == u'Übernachtung': inn.overnight, inn.overnight_comment = _conv(wrpylib.wrvalidators.BoolUnicodeTupleValidator().to_python, value, key)
143 elif key == u'Rauchfrei': inn.nonsmoker_area, inn.smoker_area = _conv(wrpylib.wrvalidators.GermanTristateTuple().to_python, value, key)
144 elif key == u'Rodelverleih': inn.sled_rental, inn.sled_rental_comment = _conv(wrpylib.wrvalidators.BoolUnicodeTupleValidator().to_python, value, key)
145 elif key == u'Handyempfang': inn.mobile_provider = _conv(wrpylib.wrvalidators.ValueCommentListNeinLoopNone().to_python, value, key)
146 elif key == u'Homepage': inn.homepage = _conv(wrpylib.wrvalidators.UrlNeinNone().to_python, value, key)
147 elif key == u'E-Mail': inn.email_list = _conv(wrpylib.wrvalidators.EmailCommentListNeinLoopNone(allow_masked_email=True).to_python, value, key)
148 elif key == u'Telefon': inn.phone_list = _conv(wrpylib.wrvalidators.PhoneCommentListNeinLoopNone(comments_are_optional=True).to_python, value, key)
149 elif key == u'Bild': inn.image = _conv(wrpylib.wrvalidators.UnicodeNone().to_python, value, key)
150 elif key == u'Rodelbahnen': inn.sledding_list = _conv(wrpylib.wrvalidators.WikiPageListLoopNone().to_python, value, key)
151 else: raise formencode.Invalid(u"Unbekannte Eigenschaft der Gasthausbox: '%s' (mit Wert '%s')" % (key, value), value, None)
152 return start, end, inn
155 def inn_to_gasthausbox(inn):
156 """Converts the inn class to the {{Gasthausbox}} representation."""
159 keys.append(u'Position')
160 values.append(wrpylib.wrvalidators.GeoNone().from_python((inn.position_latitude, inn.position_longitude)))
162 values.append(wrpylib.wrvalidators.UnsignedNone().from_python(inn.position_elevation))
163 keys.append(u'Betreiber')
164 values.append(wrpylib.wrvalidators.UnicodeNone().from_python(inn.operator))
165 keys.append(u'Sitzplätze')
166 values.append(wrpylib.wrvalidators.UnsignedNone().from_python(inn.seats))
167 keys.append(u'Übernachtung')
168 values.append(wrpylib.wrvalidators.BoolUnicodeTupleValidator().from_python((inn.overnight, inn.overnight_comment)))
169 keys.append(u'Rauchfrei')
170 values.append(wrpylib.wrvalidators.GermanTristateTuple().from_python((inn.nonsmoker_area, inn.smoker_area)))
171 keys.append(u'Rodelverleih')
172 values.append(wrpylib.wrvalidators.BoolUnicodeTupleValidator().from_python((inn.sled_rental, inn.sled_rental_comment)))
173 keys.append(u'Handyempfang')
174 values.append(wrpylib.wrvalidators.ValueCommentListNeinLoopNone().from_python(inn.mobile_provider))
175 keys.append(u'Homepage')
176 values.append(wrpylib.wrvalidators.UrlNeinNone().from_python(inn.homepage))
177 keys.append(u'E-Mail')
178 values.append(wrpylib.wrvalidators.EmailCommentListNeinLoopNone(allow_masked_email=True).from_python(inn.email_list))
179 keys.append(u'Telefon')
180 values.append(wrpylib.wrvalidators.PhoneCommentListNeinLoopNone(comments_are_optional=True).from_python(inn.phone_list))
182 values.append(wrpylib.wrvalidators.UnicodeNone().from_python(inn.image))
183 keys.append(u'Rodelbahnen')
184 values.append(wrpylib.wrvalidators.WikiPageListLoopNone().from_python(inn.sledding_list))
185 result = [u'{{Gasthausbox']
186 return wrpylib.mwmarkup.create_template(u'Gasthausbox', [], keys, values, True)
189 def find_template_latlon_ele(wikitext, template_title):
190 """Finds the first occurance of the '{{template_title|47.076207 N 11.453553 E|1890}}' template
191 and returns the tuple (start, end, lat, lon, ele) or (None, None, None, None, None) if the
192 template was not found. If the template has no valid format, an exception is thrown."""
193 start, end = wrpylib.mwmarkup.find_template(wikitext, template_title)
194 if start is None: return (None,) * 5
195 title, params = wrpylib.mwmarkup.split_template(wikitext[start:end])
196 lat, lon = wrpylib.wrvalidators.GeoNone().to_python(params[u'1'].strip())
197 ele = wrpylib.wrvalidators.UnsignedNone().to_python(params[u'2'].strip())
198 return start, end, lat, lon, ele
201 def create_template_latlon_ele(template_title, lat, lon, ele):
202 geo = wrpylib.wrvalidators.GeoNone().from_python((lat, lon))
203 if len(geo) == 0: geo = u' '
204 ele = wrpylib.wrvalidators.UnsignedNone().from_python(ele)
205 if len(ele) == 0: ele = u' '
206 return wrpylib.mwmarkup.create_template(template_title, [geo, ele])
209 def find_template_PositionOben(wikitext):
210 """Same as find_template_latlon_ele with template '{{Position oben|47.076207 N 11.453553 E|1890}}'"""
211 return find_template_latlon_ele(wikitext, u'Position oben')
214 def create_template_PositionOben(lat, lon, ele):
215 return create_template_latlon_ele(u'Position, oben', lat, lon, ele)
218 def find_template_PositionUnten(wikitext):
219 """Same as find_template_latlon_ele with template '{{Position unten|47.076207 N 11.453553 E|1890}}'"""
220 return find_template_latlon_ele(wikitext, u'Position unten')
223 def find_template_unsigned(wikitext, template_title):
224 """Finds the first occurance of the '{{template_title|1890}}' template
225 and returns the tuple (start, end, unsigned_value) or (None, None, None) if the
226 template was not found. If the template has no valid format, an exception is thrown."""
227 start, end = wrpylib.mwmarkup.find_template(wikitext, template_title)
228 if start is None: return (None,) * 3
229 title, params = wrpylib.mwmarkup.split_template(wikitext[start:end])
230 unsigned_value = wrpylib.wrvalidators.UnsignedNone().to_python(params[u'1'].strip())
231 return start, end, unsigned_value
234 def create_template_unsigned(template_title, unsigned):
235 unsigned = wrpylib.wrvalidators.UnsignedNone().from_python(unsigned)
236 if len(unsigned) == 0: unsigned = u' '
237 return wrpylib.mwmarkup.create_template(template_title, [unsigned])
240 def find_template_Hoehenunterschied(wikitext):
241 """Same as find_template_unsigned with template '{{Höhenunterschied|350}}'"""
242 return find_template_unsigned(wikitext, u'Höhenunterschied')
245 def create_template_Hoehenunterschied(ele_diff):
246 return create_template_unsigned(u'Höhenunterschied', ele_diff)
249 def find_template_Bahnlaenge(wikitext):
250 """Same as find_template_unsigned with template '{{Bahnlänge|4500}}'"""
251 return find_template_unsigned(wikitext, u'Bahnlänge')
254 def create_template_Bahnlaenge(length):
255 return create_template_unsigned(u'Bahnlänge', length)
258 def find_template_Gehzeit(wikitext):
259 """Same as find_template_unsigned with template '{{Gehzeit|60}}'"""
260 return find_template_unsigned(wikitext, u'Gehzeit')
263 def create_template_Gehzeit(walkup_time):
264 return create_template_unsigned(u'Gehzeit', walkup_time)
267 def find_template_Forumlink(wikitext):
268 """Same as find_template_unsigned with template '{{Forumlink|26}}'"""
269 start, end = wrpylib.mwmarkup.find_template(wikitext, u'Forumlink')
270 if start is None: return (None,) * 3
271 title, params = wrpylib.mwmarkup.split_template(wikitext[start:end])
272 forumid = params[u'1'].strip()
273 if forumid == u'<nummer einfügen>': unsigned_value = None
274 else: unsigned_value = wrpylib.wrvalidators.UnsignedNone().to_python(forumid)
275 return start, end, unsigned_value
276 # return find_template_unsigned(wikitext, u'Forumlink')
279 def find_template_Parkplatz(wikitext):
280 """Same as find_template_latlon_ele with template '{{Parkplatz|47.076207 N 11.453553 E|1890}}'"""
281 return find_template_latlon_ele(wikitext, u'Parkplatz')
284 def find_template_Haltestelle(wikitext):
285 """Finds the first occurance of the '{{Haltestelle|Ortsname|Haltestellenname|47.076207 N 11.453553 E|1890}}' template
286 and returns the tuple (start, end, city, stop, lat, lon, ele) or (None, None, None, None, None, None, None) if the
287 template was not found. If the template has no valid format, an exception is thrown."""
288 start, end = wrpylib.mwmarkup.find_template(wikitext, u'Haltestelle')
289 if start is None: return (None,) * 7
290 title, params = wrpylib.mwmarkup.split_template(wikitext[start:end])
291 city = wrpylib.wrvalidators.UnicodeNone().to_python(params[u'1'].strip())
292 stop = wrpylib.wrvalidators.UnicodeNone().to_python(params[u'2'].strip())
293 lat, lon = wrpylib.wrvalidators.GeoNone().to_python(params[u'3'].strip())
294 ele = wrpylib.wrvalidators.UnsignedNone().to_python(params[u'4'].strip())
295 return start, end, city, stop, lat, lon, ele
298 def find_all_templates(wikitext, find_func):
299 """Returns a list of return values of find_func that searches for a template.
301 >>> find_all_tempaltes(wikitext, find_template_Haltestelle)
302 Returns an empty list if the template was not found at all.
305 result = find_func(wikitext)
306 start, end = result[:2]
307 while start is not None:
308 results.append(result)
309 result = find_func(wikitext[end:])
310 if result[0] is None:
313 start = result[0] + end
315 result = (start, end) + result[2:]
319 def parse_googlemap(wikitext):
320 """Parses the (unicode) u'<googlemap ...>content</googlemap>' of the googlemap extension
321 out of a page. If wikitext does not contain the googlemaps extension text None is returned.
322 If the googlemap contains invalid formatted lines, a RuntimeError is raised.
324 :param wikitext: wikitext containing the template. Example:
327 <googlemap version="0.9" lat="47.113291" lon="11.272337" zoom="15">
328 (Parkplatz)47.114958,11.266026
331 (Gasthaus) 47.114715, 11.266262, Alt Bärnbad (Gasthaus)
340 :returns: (attributes, GeoJSON as Python datatypes)
342 center, zoom, coords, paths = wrpylib.mwmarkup.parse_googlemap(wikitext)
347 lon, lat, symbol, title = point
348 properties = {'type': symbol}
349 if title: properties['name'] = title
350 json_features.append({
352 'geometry': {'type': 'Point', 'coordinates': [lon, lat]},
353 'properties': properties})
357 style, entries = path
358 properties = {'type': 'line'}
359 json_features.append({
362 'type': 'LineString',
363 'coordinates': [[lon, lat] for lon, lat, symbol, title in entries]},
364 'properties': properties})
366 json = {'type': 'FeatureCollection', 'features': json_features}
367 return {'lon': center[0], 'lat': center[1], 'zoom': zoom}, json
370 def parse_wrmap_coordinates(coords):
371 '''gets a string coordinates and returns an array of lon/lat coordinate pairs, e.g.
375 [[11.87, 47.12], [11.70, 47.13]]'''
378 for match in re.finditer(r'\s*(\d+\.?\d*)\s*N?\s+(\d+\.?\d*)\s*E?\s*', coords):
379 if match.start() != pos:
381 result.append([float(match.groups()[1]), float(match.groups()[0])])
384 if pos == len(coords):
386 raise RuntimeError('Wrong coordinate format: {}'.format(coords))
389 def parse_wrmap(wikitext):
390 """Parses the (unicode) u'<wrmap ...>content</wrmap>' of the Winterrodeln wrmap extension
391 out of a page. If wikitext does not contain the googlemaps extension text None is returned.
392 If the googlemap contains invalid formatted lines, a RuntimeError is raised.
394 :param wikitext: wikitext containing the template. Example:
397 <wrmap lat="47.2417134" lon="11.21408895" zoom="14" width="700" height="400">
398 <gasthaus name="Rosskogelhütte" wiki="Rosskogelhütte">47.240689 11.190454</gasthaus>
399 <parkplatz>47.245789 11.238971</parkplatz>
400 <haltestelle name="Oberperfuss Rangger Köpfl Lift">47.245711 11.238283</haltestelle>
408 :returns: (attributes, GeoJSON as Python datatypes)
412 wrmap_xml = xml.etree.ElementTree.fromstring(wikitext.encode('utf-8'))
413 except xml.etree.ElementTree.ParseError as e:
414 row, column = e.position
415 raise RuntimeError("XML parse error on row {}, column {}: {}".format(row, column, e))
416 # assert(in_array($tagname, array('wrmap', 'wrgmap'))); # TODO
418 # convert XML to geojson (http://www.geojson.org/geojson-spec.html)
420 point_type = {'gasthaus': 'inn', 'haltestelle': 'busstop', 'parkplatz': 'carpark', 'achtung': 'attention', 'punkt': 'point'}
421 line_type = {'rodelbahn': 'sledrun', 'gehweg': 'walk', 'alternative': 'alternative', 'lift': 'lift', 'linie': 'line'}
422 for feature in wrmap_xml:
423 # determine feature type
424 is_point = point_type.has_key(feature.tag)
425 is_line = line_type.has_key(feature.tag)
426 if (not is_point and not is_line):
427 raise RuntimeError('Unknown element <{}>.'.format(feature.tag))
431 properties = {'type': point_type[feature.tag]}
432 allowed_properties = set(['name', 'wiki'])
433 wrong_properties = set(feature.attrib.keys()) - allowed_properties
434 if len(wrong_properties) > 0:
435 raise RuntimeError("The attribute '{}' is not allowed at <{}>.".format(list(wrong_properties)[0], feature.tag))
436 properties.update(feature.attrib)
437 coordinates = parse_wrmap_coordinates(feature.text)
438 if len(coordinates) != 1:
439 raise RuntimeError('The element <{}> has to have exactly one coordinate pair.'.format(feature.tag))
440 json_features.append({
442 'geometry': {'type': 'Point', 'coordinates': coordinates[0]},
443 'properties': properties})
447 properties = {'type': line_type[feature.tag]}
448 allowed_properties = set(['farbe', 'dicke'])
449 wrong_properties = set(feature.attrib.keys()) - allowed_properties
450 if len(wrong_properties) > 0:
451 raise RuntimeError("The attribute '{}' is not allowed at <{}>.".format(list(wrong_properties)[0], feature.tag))
452 if feature.attrib.has_key('farbe'):
454 properties['strokeColor'] = feature.attrib['farbe'] # e.g. #a200b7
455 if feature.attrib.has_key('dicke'):
457 properties['strokeWidth'] = int(feature.attrib['dicke']) # e.g. 6
459 raise RuntimeError('The attribute "farbe" has to be an integer.')
460 json_features.append({
462 'geometry': {'type': 'LineString', 'coordinates': parse_wrmap_coordinates(feature.text)},
463 'properties': properties})
466 'type': 'FeatureCollection',
467 'features': json_features}
469 # attributes # TODO: check
471 attributes['lat'] = float(wrmap_xml.attrib.get('lat', 47.267648)) # center lat
472 attributes['lon'] = float(wrmap_xml.attrib.get('lon', 11.404655)) # center lon
473 attributes['zoom'] = int(wrmap_xml.attrib.get('zoom', 10)) # Google Zoom Level
474 attributes['width'] = int(wrmap_xml.attrib['width']) if wrmap_xml.attrib.has_key('width') else None # None corresponds to 100%
475 attributes['height'] = int(wrmap_xml.attrib.get('height', 450)) # map height in px
476 # show_sledruns = (wrmap_xml.tag == 'wrgmap')
478 return attributes, json
481 def create_wrmap(geojson):
482 """Creates a <wrmap> wikitext from geojson."""