2 # vim: set fileencoding=utf-8 encoding=utf-8 et :
3 # txt2osm, an UnofficialMapProject .txt to OpenStreetMap .osm converter.
4 # Copyright (C) 2008 Mariusz Adamski, rhn
5 # Copyright (C) 2009 Andrzej Zaborowski
7 # This program is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU General Public License
9 # as published by the Free Software Foundation; either version 2
10 # of the License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 from xml
.sax
import saxutils
30 0x1: [ "highway", "motorway" ],
31 0x2: [ "highway", "trunk" ],
32 0x3: [ "highway", "primary" ],
33 0x4: [ "highway", "secondary" ],
34 0x5: [ "highway", "tertiary" ],
35 0x6: [ "highway", "residential" ],
36 0x7: [ "highway", "living_street", "note", "FIXME: select one of: living_street, service, residential" ],
37 0x8: [ "highway", "primary_link" ],
38 0x9: [ "highway", "secondary_link" ],
39 0xa: [ "highway", "unclassified" ],
40 0xb: [ "highway", "trunk_link" ],
41 0xc: [ "junction", "roundabout" ],
42 0xd: [ "highway", "cycleway" ],
43 0xe: [ "highway", "service", "tunnel", "yes" ],
44 0x14: [ "railway", "rail" ],
45 0x16: [ "highway", "pedestrian" ],
46 0x18: [ "waterway", "stream" ],
47 0x19: [ "_rel", "restriction" ],
48 0x1a: [ "route", "ferry" ],
49 0x1b: [ "route", "ferry" ],
50 0x1c: [ "boundary", "administrative", "admin_level", "8" ],
51 0x1d: [ "boundary", "administrative", "admin_level", "4" ],
52 0x1e: [ "boundary", "administrative", "admin_level", "2" ],
53 0x1f: [ "waterway", "canal" ],
54 0x20: [ "barrier", "wall" ],
55 0x21: [ "barrier", "wall" ],
56 0x22: [ "barrier", "city_wall" ],
57 0x23: [ "highway", "track", "note", "fixme" ],
58 0x24: [ "highway", "road" ],
59 0x25: [ "barrier", "retaining_wall" ],
60 0x26: [ "waterway", "drain" ],
61 0x27: [ "aeroway", "runway" ],
62 0x28: [ "man_made", "pipeline" ],
63 0x29: [ "power", "line", "barrier", "retaining_wall",
64 "note", "fixme: choose one" ],
65 0x2a: [ "note", "fixme" ],
66 0x2c: [ "boundary", "historical", "admin_level", "2" ],
67 0x2f: [ "_rel", "lane_restriction" ],
68 0x44: [ "boundary", "administrative", "admin_level", "9" ],
69 0x4b: [ "note", "fixme" ],
71 0xe00: [ "highway", "footway", "ref", "Czerwony szlak",
72 "marked_trail_red", "yes" ],
73 0xe01: [ "highway", "footway", "ref", "Żółty szlak",
74 "marked_trail_yellow", "yes" ],
75 0xe02: [ "highway", "footway", "ref", "Zielony szlak",
76 "marked_trail_green", "yes" ],
77 0xe03: [ "highway", "footway", "ref", "Niebieski szlak",
78 "marked_trail_blue", "yes" ],
79 0xe04: [ "highway", "footway", "ref", "Czarny szlak",
80 "marked_trail_black", "yes" ],
81 0xe07: [ "highway", "footway", "ref", "Szlak", "note", "FIXME" ],
82 0xe08: [ "highway", "cycleway", "ref", "Czerwony szlak",
83 "marked_trail_red", "yes" ],
84 0xe09: [ "highway", "cycleway", "ref", "Żółty szlak",
85 "marked_trail_yellow", "yes" ],
86 0xe0a: [ "highway", "cycleway", "ref", "Zielony szlak",
87 "marked_trail_green", "yes" ],
88 0x1e0a:[ "highway", "cycleway", "ref", "Zielony szlak",
89 "marked_trail_green", "yes" ],
90 0xe0b: [ "highway", "cycleway", "ref", "Niebieski szlak",
91 "marked_trail_blue", "yes" ],
92 0xe0c: [ "highway", "cycleway", "ref", "Czarny szlak",
93 "marked_trail_black", "yes" ],
94 0xe0d: [ "highway", "cycleway", "ref", "Zielony szlak z liściem",
95 "marked_trail_green", "yes" ],
96 0xe0f: [ "highway", "cycleway", "ref", "Szlak", "note", "FIXME" ],
98 0xe10: [ "railway", "tram" ],
99 0xe11: [ "railway", "abandoned" ],
101 0xe12: [ "highway", "construction" ], # TODO
102 0xe13: [ "railway", "construction" ], # TODO
104 0x6701: [ "highway", "path" ],
105 0x6702: [ "highway", "track" ],
106 0x6707: [ "highway", "path", "ref", "Niebieski szlak", "bicycle", "yes",
107 "marked_trail_blue", "yes" ],
109 0x10e00: [ "highway", "path", "ref", "Czerwony szlak",
110 "marked_trail_red", "yes" ],
111 0x10e01: [ "highway", "path", "ref", "Żółty szlak",
112 "marked_trail_yellow", "yes" ],
113 0x10e02: [ "highway", "path", "ref", "Zielony szlak",
114 "marked_trail_green", "yes" ],
115 0x10e03: [ "highway", "path", "ref", "Niebieski szlak",
116 "marked_trail_blue", "yes" ],
117 0x10e04: [ "highway", "path", "ref", "Czarny szlak",
118 "marked_trail_black", "yes" ],
119 0x10e07: [ "highway", "path", "ref", "Szlak", "note", "FIXME" ],
120 0x10e08: [ "highway", "cycleway", "ref", "Czerwony szlak",
121 "marked_trail_red", "yes" ],
122 0x10e09: [ "highway", "cycleway", "ref", "Żółty szlak",
123 "marked_trail_yellow", "yes" ],
124 0x10e0a: [ "highway", "cycleway", "ref", "Zielony szlak",
125 "marked_trail_green", "yes" ],
126 0x10e0b: [ "highway", "cycleway", "ref", "Niebieski szlak",
127 "marked_trail_blue", "yes" ],
128 0x10e0c: [ "highway", "cycleway", "ref", "Czarny szlak",
129 "marked_trail_black", "yes" ],
130 0x10e0d: [ "highway", "cycleway", "ref", "Szlak",
131 "marked_trail_black", "yes", "note", "FIXME" ],
132 0x10e0f: [ "highway", "cycleway", "ref", "Szlak", "note", "FIXME" ],
134 0x10e10: [ "railway", "tram" ],
135 0x10e11: [ "railway", "abandoned" ],
137 0x10e12: [ "highway", "construction" ], # TODO
138 0x10e13: [ "railway", "construction" ], # TODO
141 0x1: [ "landuse", "residential" ],
142 0x2: [ "landuse", "residential" ],
143 0x3: [ "highway", "pedestrian", "area", "yes" ],
144 0x4: [ "landuse", "military" ],
145 0x5: [ "amenity", "parking" ],
146 0x6: [ "amenity", "parking", "building", "garage" ],
147 0x7: [ "building", "terminal", "fixme", "Tag manually!" ],
148 0x8: [ "landuse", "retail", "building", "shops", "shop", "fixme",
149 "fixme", "Tag manually!" ],
150 0x9: [ "leisure", "marina" ], # a wild guess
151 0xa: [ "amenity", "school", "building", "hall" ],
152 0xb: [ "amenity", "hospital", "building", "hall" ],
153 0xc: [ "landuse", "industrial" ], # a wild guess
154 0xd: [ "landuse", "construction" ],
155 0xe: [ "aeroway", "aerodrome" ],
156 0x13: [ "building", "yes" ],
157 0x14: [ "natural", "wood" ], # sometimes landuse=military
158 0x15: [ "natural", "wood" ],
159 0x16: [ "natural", "wood" ],
160 0x17: [ "leisure", "park" ],
161 0x18: [ "leisure", "pitch", "sport", "tennis" ],
162 0x19: [ "leisure", "pitch" ], # or stadium...
163 0x1a: [ "landuse", "cemetery" ],
164 0x1e: [ "landuse", "forest", "leisure", "nature_reserve" ],
165 0x1f: [ "landuse", "forest", "leisure", "nature_reserve" ],
166 0x20: [ "tourism", "attraction" ], # a wild guess (forest?)
167 0x28: [ "natural", "coastline" ],
168 0x29: [ "natural", "water" ],
169 0x32: [ "natural", "coastline" ],
170 0x3b: [ "natural", "water" ], # how does this differ from 0x40?
171 0x3c: [ "natural", "water" ], # how does this differ from 0x40?
172 0x3d: [ "natural", "water" ], # how does this differ from 0x40?
173 0x3e: [ "natural", "water" ], # how does this differ from 0x40?
174 0x3f: [ "natural", "water" ], # how does this differ from 0x40?
175 0x40: [ "natural", "water" ],
176 0x41: [ "natural", "water", "amenity", "fountain" ],
177 0x42: [ "landuse", "reservoir" ], # how does this differ from 0x40?
178 0x43: [ "landuse", "reservoir" ], # how does this differ from 0x40?
179 0x44: [ "landuse", "reservoir" ], # how does this differ from 0x40?
180 0x45: [ "landuse", "reservoir" ], # how does this differ from 0x40?
181 0x46: [ "waterway", "riverbank" ],
182 0x47: [ "waterway", "riverbank" ], # how does this differ from 0x46?
183 0x48: [ "waterway", "riverbank" ], # how does this differ from 0x46?
184 0x49: [ "waterway", "riverbank" ], # how does this differ from 0x46?
185 0x4a: [ "highway", "residential", "oneway", "yes" ],
186 0x4c: [ "natural", "water" ], # how does this differ from 0x40?
187 0x4d: [ "natural", "glacier" ],
188 0x4e: [ "landuse", "allotments" ],
189 0x4f: [ "natural", "scrub" ],
190 0x50: [ "natural", "wood" ],
191 0x51: [ "natural", "wetland" ],
192 0x52: [ "leisure", "garden", "tourism", "zoo" ],
193 0x53: [ "landuse", "landfill" ],
195 0x2d0a: [ "leisure", "stadium" ],
198 0x04: [ "place", "city" ],
199 0x05: [ "place", "city" ],
200 0x06: [ "place", "city" ],
201 0x07: [ "place", "city" ],
202 0x08: [ "place", "town" ],
203 0x08: [ "place", "town" ],
204 0x09: [ "place", "town" ],
205 0x0a: [ "place", "town" ],
206 0x0b: [ "place", "town" ],
207 0x0c: [ "place", "village" ],
208 0x0d: [ "place", "village" ],
209 0x0e: [ "place", "village" ],
210 0x2d: [ "amenity", "townhall" ],
212 0x0100: [ "place", "city" ], # Also used for voivodeships, regions
213 0x0200: [ "place", "city" ],
214 0x0300: [ "place", "city" ], # Also used for country nodes, seas
215 0x0400: [ "place", "city" ],
216 0x0500: [ "place", "city" ],
217 0x0600: [ "place", "city" ],
218 0x0700: [ "place", "city" ],
219 0x0800: [ "place", "city" ],
220 0x0900: [ "place", "city" ],
221 0x0a00: [ "place", "town" ],
222 0x0b00: [ "place", "town" ],
223 0x0c00: [ "place", "town" ],
224 0x0d00: [ "place", "town" ],
225 0x0e00: [ "place", "village" ],
226 0x0f00: [ "place", "village" ],
227 0x1000: [ "place", "village" ],
228 0x1100: [ "place", "village" ],
229 0x1150: [ "landuse", "construction" ],
230 0x1200: [ "bridge", "yes" ],
231 0x1500: [ "place", "locality" ],
232 0x1600: [ "man_made", "lighthouse" ],
233 0x1602: [ "note", "fixme" ],
234 0x1605: [ "amenity", "citymap_post", "tourism", "information" ],
235 0x1606: [ "man_made", "beacon", "mark_type", "buoy" ],
236 0x1607: [ "man_made", "beacon", "mark_type", "safe_water" ],
237 0x1608: [ "man_made", "beacon", "mark_type", "lateral_left" ],
238 0x1609: [ "man_made", "beacon", "mark_type", "lateral_right" ],
239 0x160a: [ "man_made", "beacon", "mark_type", "isolated_danger" ],
240 0x160b: [ "man_made", "beacon", "mark_type", "special" ],
241 0x160c: [ "man_made", "beacon", "mark_type", "cardinal" ],
242 0x160d: [ "man_made", "beacon", "mark_type", "other" ],
243 0x160e: [ "amenity", "signpost" ],
244 0x160f: [ "man_made", "beacon", "mark_type", "white" ],
245 0x1610: [ "man_made", "beacon", "mark_type", "red" ],
246 0x1611: [ "man_made", "beacon", "mark_type", "green" ],
247 0x1612: [ "man_made", "beacon", "mark_type", "yellow" ],
248 0x1613: [ "man_made", "beacon", "mark_type", "orange" ],
249 0x1614: [ "man_made", "beacon", "mark_type", "magenta" ],
250 0x1615: [ "man_made", "beacon", "mark_type", "blue" ],
251 0x1616: [ "man_made", "beacon", "mark_type", "multicolored" ],
252 0x1708: [ "shop", "fixme" ],
253 0x1709: [ "bridge", "yes" ],
254 0x170b: [ "shop", "verify!" ],
255 0x1710: [ "barrier", "gate" ],
256 0x17105:[ "highway", "stop" ],
257 0x1711: [ "note", "FIXME" ],
258 0x1712: [ "landuse", "construction" ],
259 0x170a: [ "note", "FIXME: verify" ],
260 0x170d: [ "note", "FIXME" ],
261 0x180c: [ "man_made", "beacon", "mark_type", "grounded-red" ], # TODO
262 0x180c: [ "man_made", "beacon", "mark_type", "grounded-green" ], # TODO
263 0x180c: [ "man_made", "beacon", "mark_type", "grounded-yellow" ], # TODO
264 0x180c: [ "man_made", "beacon", "mark_type", "cardinal-north" ],
265 0x190c: [ "man_made", "beacon", "mark_type", "cardinal-south" ],
266 0x1a0c: [ "man_made", "beacon", "mark_type", "cardinal-east" ],
267 0x1b0c: [ "man_made", "beacon", "mark_type", "cardinal-west" ],
268 0x190b: [ "highway", "construction" ],
269 0x1a0b: [ "man_made", "beacon" ],
270 0x1a10: [ "man_made", "beacon" ],
271 0x1b00: [ "note", "fixme" ],
272 0x1b02: [ "natural", "peak" ],
273 0x1b05: [ "amenity", "signpost" ],
274 0x1b0f: [ "aeroway", "taxiway" ],
275 0x1c00: [ "barrier", "obstruction" ],
276 0x1c01: [ "man_made", "ship_wreck" ],
277 0x1c07: [ "barrier", "obstruction", "visibility", "no" ],
278 0x1c09: [ "note", "fixme" ],
279 0x1e00: [ "place", "region" ],
280 0x1f00: [ "place", "region" ],
281 0x2000: [ "highway", "motorway_junction" ],
282 0x2100: [ "highway", "motorway_junction", "amenity", "parking" ],
283 0x2110: [ "highway", "motorway_junction", "amenity", "parking" ],
284 0x2200: [ "highway", "motorway_junction" ],
285 0x2400: [ "amenity", "weigh_station" ],
286 0x2500: [ "highway", "motorway_junction", "barrier", "toll_booth" ],
287 0x2600: [ "bridge", "yes" ],
288 0x2700: [ "highway", "motorway_junction" ],
289 0x2800: [ "place", "region" ], # Seems to be used villages though
290 0x2900: [ "landuse", "commercial" ],
291 0x2a: [ "amenity", "restaurant" ],
292 0x2a00: [ "amenity", "restaurant" ],
293 0x2a01: [ "amenity", "restaurant", "cuisine", "american" ],
294 0x2a02: [ "amenity", "restaurant", "cuisine", "asian" ],
295 0x2a025:[ "amenity", "restaurant", "cuisine", "sushi" ],
296 0x2a03: [ "amenity", "restaurant", "cuisine", "barbecue" ],
297 0x2a030:[ "amenity", "restaurant", "cuisine", "barbecue" ],
298 0x2a031:[ "amenity", "restaurant", "cuisine", "grill" ],
299 0x2a032:[ "amenity", "restaurant", "cuisine", "kebab" ],
300 0x2a04: [ "amenity", "restaurant", "cuisine", "chinese" ],
301 0x2a05: [ "shop", "bakery" ],
302 0x2a06: [ "amenity", "pub" ],
303 0x2a07: [ "amenity", "fast_food", "cuisine", "burger" ],
304 0x2a08: [ "amenity", "restaurant", "cuisine", "italian" ],
305 0x2a09: [ "amenity", "restaurant", "cuisine", "mexican" ],
306 0x2a0a: [ "amenity", "restaurant", "cuisine", "pizza" ],
307 0x2a0b: [ "amenity", "restaurant", "cuisine", "sea_food" ],
308 0x2a0c: [ "amenity", "restaurant", "cuisine", "grill" ],
309 0x2a0d: [ "amenity", "restaurant", "cuisine", "bagel" ], # bagle?
310 0x2a0e: [ "amenity", "cafe" ],
311 0x2a0f: [ "amenity", "restaurant", "cuisine", "french" ],
312 0x2a10: [ "amenity", "restaurant", "cuisine", "german" ],
313 0x2a11: [ "amenity", "restaurant", "cuisine", "british" ],
314 0x2a12: [ "amenity", "fast_food", "cuisine", "greek" ],
315 0x2a125:[ "amenity", "fast_food", "cuisine", "lebanese" ],
316 0x2a13: [ "amenity", "restaurant", "cuisine", "international" ],
317 0x2a14: [ "amenity", "restaurant", "cuisine", "regional" ],
318 0x2b00: [ "tourism", "hostel" ],
319 0x2b01: [ "tourism", "hotel" ],
320 0x2b015:[ "tourism", "motel" ],
321 0x2b02: [ "tourism", "hostel" ],
322 0x2b03: [ "tourism", "camp_site" ],
323 0x2b04: [ "tourism", "hotel" ],
324 0x2c00: [ "tourism", "attraction" ],
325 0x2c005:[ "tourism", "viewpoint" ],
326 0x2c01: [ "tourism", "attraction", "leisure", "park" ],
327 0x2c015:[ "leisure", "playground" ],
328 0x2c02: [ "tourism", "museum" ],
329 0x2c025:[ "tourism", "museum", "amenity", "arts_centre" ],
330 0x2c03: [ "amenity", "library" ],
331 0x2c04: [ "historic", "castle" ],
332 0x2c040:[ "historic", "castle", "castle_type", "dworek" ],
333 0x2c041:[ "historic", "castle", "castle_type", "palace" ],
334 0x2c042:[ "historic", "castle", "castle_type", "fortress" ],
335 0x2c043:[ "historic", "castle", "castle_type", "fortress" ],
336 0x2c05: [ "amenity", "school" ],
337 0x2c055:[ "amenity", "university" ],
338 0x2c056:[ "amenity", "kindergarten", "note", "Przedszkole" ],
339 0x2c057:[ "amenity", "kindergarten", "note", "Żłobek" ],
340 0x2c06: [ "leisure", "park" ],
341 0x2c07: [ "tourism", "zoo" ],
342 0x2c08: [ "leisure", "sports_centre" ],
343 0x2c080:[ "leisure", "pitch" ],
344 0x2c081:[ "leisure", "stadium" ],
345 0x2c09: [ "amenity", "theatre", "note", "concert_hall" ],
346 0x2c0a: [ "amenity", "restaurant", "cuisine", "wine_bar" ],
347 0x2c0b: [ "amenity", "place_of_worship" ],
348 0x2c0c: [ "natural", "spring", "amenity", "spa" ],
349 0x2d00: [ "leisure", "track" ],
350 0x2d01: [ "amenity", "theatre" ],
351 0x2d02: [ "amenity", "fast_food" ],
352 0x2d03: [ "amenity", "cinema" ],
353 0x2d04: [ "amenity", "nightclub" ],
354 0x2d045:[ "amenity", "casino" ],
355 0x2d05: [ "sport", "golf", "leisure", "golf_course" ],
356 0x2d06: [ "sport", "skiing" ],
357 0x2d07: [ "sport", "9pin" ],
358 0x2d08: [ "sport", "skating" ],
359 0x2d09: [ "sport", "swimming" ],
360 0x2d0a: [ "leisure", "stadium" ],
361 0x2d0a0:[ "leisure", "sports_centre", "sport", "fitness" ],
362 0x2d0a1:[ "leisure", "sports_centre", "sport", "tennis" ],
363 0x2d0a2:[ "leisure", "sports_centre", "sport", "skating" ],
364 0x2d0b: [ "sport", "sailing" ],
365 0x2e: [ "shop", "stationery" ],
366 0x2e00: [ "shop", "mall" ],
367 0x2e01: [ "shop", "department_store" ],
368 0x2e02: [ "shop", "grocery" ],
369 0x2e025:[ "amenity", "marketplace" ],
370 0x2e03: [ "shop", "supermarket" ],
371 0x2e04: [ "shop", "mall" ],
372 0x2e05: [ "amenity", "pharmacy" ],
373 0x2e06: [ "shop", "convenience" ],
374 0x2e07: [ "shop", "clothes" ],
375 0x2e08: [ "shop", "garden_centre" ],
376 0x2e09: [ "shop", "furniture" ],
377 0x2e0a: [ "shop", "outdoor" ],
378 0x2e0a5:[ "shop", "bicycle" ],
379 0x2e0b: [ "shop", "computer" ],
380 0x2e0c: [ "shop", "pets" ],
381 0x2f00: [ "amenity", "miscellaneous" ],
382 0x2f01: [ "amenity", "fuel" ],
383 0x2f02: [ "amenity", "car_rental" ],
384 0x2f03: [ "shop", "car_repair" ],
385 0x2f030:[ "shop", "car" ],
386 0x2f04: [ "aeroway", "aerodrome" ],
387 0x2f05: [ "amenity", "post_office" ],
388 0x2f050:[ "amenity", "post_office", "type", "courier" ],
389 0x2f051:[ "amenity", "post_office", "type", "courier", "operator", "dhl" ],
390 0x2f052:[ "amenity", "post_office", "type", "courier", "operator", "ups" ],
391 0x2f06: [ "amenity", "bank" ], # Also used with amenity=bureau_de_change
392 0x2f061:[ "amenity", "bank", "atm", "yes" ],
393 0x2f062:[ "amenity", "atm" ],
394 0x2f07: [ "shop", "car" ],
395 0x2f08: [ "amenity", "bus_station" ],
396 0x2f080:[ "highway", "bus_stop" ],
397 0x2f081:[ "railway", "tram_stop" ],
398 0x2f082:[ "railway", "station", "operator", "metro" ],
399 0x2f083:[ "highway", "bus_stop", "operator", "PKS" ],
400 0x2f084:[ "railway", "station", "operator", "PKP" ],
402 0x2f09: [ "waterway", "boatyard" ],
403 0x2f0a: [ "shop", "car_wrecker" ],
404 0x2f0b: [ "amenity", "parking" ],
405 0x2f0c: [ "amenity", "toilets" ],
406 0x2f0c5:[ "tourism", "information" ],
407 0x2f0d: [ "amenity", "automobile_club" ],
408 0x2f0e: [ "shop", "car_wash" ],
409 0x2f0f: [ "shop", "outdoor", "operator", "Garmin" ],
410 0x2f10: [ "amenity", "personal_service" ],
411 0x2f104:[ "amenity", "personal_service", "shop", "hairdresser" ],
412 0x2f105:[ "amenity", "personal_service", "shop", "tattoo" ],
413 0x2f106:[ "amenity", "personal_service", "shop", "optician" ],
414 0x2f11: [ "amenity", "public_building" ],
415 0x2f115:[ "landuse", "industrial", "amenity", "factory" ],
416 0x2f116:[ "landuse", "commercial" ],
417 0x2f12: [ "amenity", "wifi" ],
418 0x2f13: [ "shop", "bicycle" ],
419 0x2f14: [ "amenity", "public_building", ],
420 0x2f144:[ "amenity", "public_building", "type", "social" ],
421 0x2f145:[ "amenity", "personal_service", "shop", "laundry" ],
422 0x2f15: [ "amenity", "public_building" ],
423 0x2f16: [ "amenity", "parking", "truck_stop", "yes" ],
424 0x2f17: [ "amenity", "travel_agency" ],
425 0x3000: [ "amenity", "public_building" ],
426 0x3001: [ "amenity", "police" ],
427 0x3002: [ "amenity", "hospital" ],
428 0x30025:[ "amenity", "doctors" ],
429 0x30026:[ "amenity", "veterinary" ],
430 0x30027:[ "shop", "dentist" ],
431 0x3003: [ "amenity", "public_building" ],
432 0x3004: [ "amenity", "courthouse" ],
433 0x3005: [ "amenity", "nightclub" ],
434 0x3006: [ "amenity", "border_station" ],
435 0x3007: [ "amenity", "townhall" ],
436 0x3008: [ "amenity", "fire_station" ],
437 0x4000: [ "leisure", "golf_course" ],
438 0x4100: [ "landuse", "reservoir" ],
439 0x4200: [ "man_made", "ship" ],
440 0x4300: [ "leisure", "marina" ],
441 0x4400: [ "amenity", "fuel" ],
442 0x4500: [ "amenity", "restaurant" ],
443 0x4600: [ "amenity", "fast_food" ],
444 0x4800: [ "tourism", "camp_sire" ],
445 0x4900: [ "leisure", "park" ],
446 0x4700: [ "waterway", "dock" ],
447 0x4701: [ "waterway", "boat_ramp" ],
448 0x4a00: [ "tourism", "picnic_site" ],
449 0x4b00: [ "amenity", "hospital" ],
450 0x4c00: [ "tourism", "information" ],
451 0x4d00: [ "amenity", "parking" ],
452 0x4e00: [ "amenity", "toilets" ],
453 0x5700: [ "amenity", "police_car" ], # Fixme
454 0x5000: [ "amenity", "drinking_water" ],
455 0x5100: [ "amenity", "telephone" ],
456 0x5200: [ "tourism", "viewpoint" ],
457 0x5300: [ "sport", "skiing" ],
458 0x5400: [ "sport", "swimming" ],
459 0x5500: [ "waterway", "dam" ], # Map_Features requires a way
460 0x5600: [ "barrier", "gate" ],
461 0x56001:[ "danger", "photoradar", "type", "fake" ],
462 0x56002:[ "danger", "photoradar", "type", "portable" ],
463 0x56003:[ "danger", "photoradar", "type", "permanent" ],
464 0x56004:[ "danger", "police_control" ],
465 0x56005:[ "danger", "police_control;photoradar" ],
466 0x5700: [ "danger", "yes" ],
467 0x57000:[ "danger", "photoradar" ],
468 0x57001:[ "danger", "radar" ],
469 0x57002:[ "danger", "yes" ],
470 0x57003:[ "danger", "speed_limit" ],
471 0x57004:[ "danger", "level_crossing" ],
472 0x5800: [ "amenity", "prison" ],
473 0x5900: [ "aeroway", "aerodrome" ],
474 0x5901: [ "aeroway", "aerodrome" ],
475 0x5902: [ "aeroway", "aerodrome" ],
476 0x5903: [ "aeroway", "aerodrome" ],
477 0x5904: [ "aeroway", "helipad" ],
478 0x5905: [ "aeroway", "aerodrome" ],
479 0x593f: [ "aeroway", "aerodrome" ],
480 0x5a00: [ "amenity", "signpost" ],
481 0x5c00: [ "place", "hamlet" ],
482 0x5d00: [ "tourism", "information" ],
483 0x5f00: [ "natural", "scree" ],
484 0x6100: [ "amenity", "shelter", "building", "residential" ],
485 0x6101: [ "building", "industrial" ],
486 0x6200: [ "depth", "_name" ],
487 0x6300: [ "ele", "_name" ],
488 0x6400: [ "historic", "monument", "note", "FIXME" ],
489 0x6401: [ "bridge", "yes" ],
490 0x6402: [ "landuse", "industrial" ],
491 0x6403: [ "landuse", "cemetery" ],
492 0x6404: [ "amenity", "place_of_worship", "religion", "christian" ],
493 0x6405: [ "amenity", "public_building" ],
494 0x6406: [ "amenity", "ferry_terminal" ],
495 0x6407: [ "waterway", "dam" ], # Map_Features requires a way
496 0x6408: [ "amenity", "hospital" ],
497 0x6409: [ "man_made", "water_works" ], # random pick from Map_Features
498 0x640a: [ "amenity", "signpost" ],
499 0x640b: [ "landuse", "military" ],
500 0x640c: [ "landuse", "industrial", "amenity", "mine" ],
501 0x640d: [ "man_made", "works", "waterway", "oil_platform" ],
502 0x640e: [ "leisure", "park" ],
503 0x6410: [ "amenity", "school" ],
504 0x6411: [ "man_made", "tower" ],
505 0x64110:[ "man_made", "tower", "height", "short" ],
506 0x64111:[ "man_made", "tower", "height", "tall" ],
507 0x6412: [ "highway", "marked_trail", "note", "fixme" ],
508 0x6413: [ "tunnel", "yes", "layer", "-1" ],
509 0x64135:[ "natural", "cave_entrance" ],
510 0x6414: [ "amenity", "drinking_water" ],
511 0x6415: [ "historic", "ruins", "building", "fortress" ],
512 0x64155:[ "historic", "ruins", "building", "bunker" ],
513 0x6416: [ "tourism", "hotel" ],
514 0x6500: [ "waterway", "other" ],
515 0x6502: [ "highway", "ford" ],
516 0x6503: [ "natural", "bay" ],
517 0x6504: [ "natural", "water", "waterway", "bend" ],
518 0x6505: [ "waterway", "lock_gate" ],
519 0x6507: [ "natural", "spring", "man_made", "water_works" ],
520 0x6508: [ "waterway", "waterfall" ],
521 0x6509: [ "amenity", "fountain", "note", "fixme" ],
522 0x650a: [ "natural", "glacier" ],
523 0x650b: [ "waterway", "dock" ],
524 0x650c: [ "natural", "land" ], # Island as a POI
525 0x650d: [ "natural", "water" ], # Lake as a POI
526 0x650e: [ "natural", "spring" ], # geyser -> spring or volcano?
527 0x650f: [ "natural", "water" ], # Pond as a POI
528 0x650f5:[ "amenity", "toilets" ],
529 0x6511: [ "natural", "spring" ],
530 0x6512: [ "waterway", "stream" ],
531 0x6513: [ "natural", "water" ], # Swamp as a POI
532 0x6600: [ "place", "locality", "note", "fixme (kurhan?)" ],
533 0x6601: [ "barrier", "sally_port" ],
534 0x6602: [ "landuse", "commetcial" ],
535 0x6603: [ "natural", "bay" ],
536 0x6604: [ "natural", "beach" ],
537 0x6605: [ "lock", "yes" ],
538 0x6606: [ "place", "locality", "locality_type", "cape" ],
539 0x6607: [ "natural", "cliff" ], # Cliff as a POI
540 0x6608: [ "natural", "peak" ],
541 0x6609: [ "natural", "plain" ],
542 0x660a: [ "natural", "tree" ],
543 0x660b: [ "place", "locality", "note", "fixme" ],
544 0x660e: [ "natural", "volcano" ],
545 0x660f: [ "amenity", "signpost" ],
546 0x6610: [ "mountain_pass", "yes" ],
547 0x6611: [ "man_made", "tower" ],
548 0x6612: [ "amenity", "watersports_rental" ],
549 0x6613: [ "natural", "peak", "place", "region" ],
550 0x6614: [ "natural", "scree" ],
551 0x6615: [ "natural", "peak", "place", "locality", "note", "fixme", "sport", "ski" ],
552 0x6616: [ "natural", "peak" ],
553 0x6617: [ "place", "locality", "natural", "valley" ],
554 0x6618: [ "natural", "wood" ], # Wood as a POI
556 0x6701: [ "highway", "footway", "ref", "Zielony szlak",
557 "marked_trail_green", "yes" ],
558 0x6702: [ "highway", "footway", "ref", "Czerwony szlak",
559 "marked_trail_red", "yes" ],
560 0x6703: [ "highway", "footway", "ref", "Niebieski szlak",
561 "marked_trail_blue", "yes" ],
562 0x6704: [ "highway", "footway", "ref", "Żółty szlak",
563 "marked_trail_yellow", "yes" ],
564 0x6705: [ "highway", "footway", "ref", "Czarny szlak",
565 "marked_trail_black", "yes" ],
566 0x6707: [ "highway", "cycleway", "ref", "Żółty szlak",
567 "marked_trail_yellow", "yes" ],
568 0x6708: [ "highway", "cycleway", "ref", "Czerwony szlak",
569 "marked_trail_red", "yes" ],
570 0x6709: [ "highway", "cycleway", "ref", "Niebieski szlak",
571 "marked_trail_blue", "yes" ],
572 0x670a: [ "highway", "cycleway", "ref", "Zielony szlak",
573 "marked_trail_green", "yes" ],
574 0x670b: [ "highway", "cycleway", "ref", "Czarny szlak",
575 "marked_trail_black", "yes" ],
577 interp_types
= { "o": "odd", "e": "even", "b": "all" }
578 levels
= { 1: "residential", 2: "tertiary", 3: "secondary", 4: "trunk" }
580 '0': '8', '1': '20', '2': '40', '3': '56',
581 '4': '72', '5': '93', '6': '108', '7': '128',
584 'emergency', # Found nothing better in Map_Features
588 'taxi', # Found nothing better in Map_Features
596 0x1d: 'loc_name', # Abbrevations
598 0x2a: 'int_ref', # FIXME: should differentate the types
606 class Mylist(object):
612 def __getitem__(self
, key
):
617 def index(self
, value
):
619 def __setitem__(self
, key
, value
): #
621 del self
.k
[self
.v
[key
]] #
622 self
.k
[value
] = key
#
623 self
.v
[key
] = value
#
624 def __contains__(self
, value
):
625 return value
in self
.k
626 def append(self
, value
):
627 self
.v
.append(value
) #
628 self
.k
[value
] = len(self
.k
)
630 return self
.v
.__iter
__() #
631 return self
.k
.__iter
__()
632 # Lines with a # above can be removed to save half of the memory used
633 # (but some look-ups will be slower)
641 turnrestrictions
= []
642 # FIXME: should use the timestamp of the cvs checkout from src/CVS
643 source
= "http://ump.waw.pl/ retrieved " + time
.strftime('%X %x')
649 class Features
: # fake enum
650 poi
, polyline
, polygon
, ignore
= range(4)
652 class ParsingError(Exception):
655 def index_to_nodeid(index
):
658 def index_to_wayid(index
):
659 return index_to_nodeid(len(points
) + index
)
661 def index_to_relationid(index
):
662 return index_to_wayid(len(ways
) + index
)
665 return saxutils
.escape(str, { '\'': ''' })
667 def print_point(point
, index
, argv
):
668 """Prints a pair of coordinates and their ID as XML"""
669 if '_out' in pointattrs
[index
]:
671 head
= ''.join(("<node id='", str(index_to_nodeid(index
)),
672 "' visible='true' lat='", str(point
[0]),
673 "' lon='", str(point
[1]), "'>"))
675 src
= pointattrs
[index
].pop('_src')
676 for key
in pointattrs
[index
]:
678 print("\t<tag k='%s' v='%s' />" % \
679 (key
, xmlize(pointattrs
[index
][key
])))
681 sys
.stderr
.write("converting key " + key
+ ": " +
682 str(pointattrs
[index
][key
]) + " failed\n")
683 print("\t<tag k='source' v='%s (%s)' />" % (source
, argv
[src
]))
686 def print_way(way
, index
, argv
):
687 """Prints a way given by way together with its ID to stdout as XML"""
688 if way
.pop('_c') <= 0:
690 print("<way id='%d' visible='true'>" % index_to_wayid(index
))
691 for nindex
in way
.pop('_nodes'):
692 print("\t<nd ref='%d' />" % index_to_nodeid(nindex
))
694 src
= way
.pop('_src')
696 print("\t<tag k='%s' v='%s' />" % (key
, xmlize(way
[key
])))
697 print("\t<tag k='source' v='%s (%s)' />" % (source
, argv
[src
]))
700 def print_relation(rel
, index
, argv
):
701 """Prints a relation given by rel together with its ID to stdout as XML"""
702 if rel
.pop('_c') <= 0:
704 if not rel
.has_key("_members"):
705 sys
.stderr
.write( "warning: Unable to print relation not having memebers: %r\n" % (rel
,) )
707 print("<relation id='%i' visible='true'>" % index_to_relationid(index
))
708 for role
, (type, members
) in rel
.pop('_members').items():
709 for member
in members
:
711 id = index_to_nodeid(member
)
713 id = index_to_wayid(member
)
715 id = index_to_relationid(member
)
716 print("\t<member type='%s' ref='%i' role='%s' />" % \
719 src
= rel
.pop('_src')
721 print("\t<tag k='%s' v='%s' />" % (key
, xmlize(rel
[key
])))
722 print("\t<tag k='source' v='%s (%s)' />" % (source
, argv
[src
]))
725 def points_append(node
, attrs
):
731 borders
= [ lat
, lon
, lat
, lon
]
741 elif borders
is None or \
742 lat
< borders
[0] or lon
< borders
[1] or \
743 lat
> borders
[2] or lon
> borders
[3]:
746 attrs
['_src'] = srcidx
748 maxtypes
.append(0x100)
749 pointattrs
.append(attrs
)
751 def prepare_line(nodes_str
, closed
):
752 """Appends new nodes to the points list"""
754 for element
in nodes_str
.split(','):
755 element
= element
.strip('()')
756 nodes
.append(element
)
761 nodes
= zip(lats
, longs
)
764 if node
not in points
:
765 points_append(node
, {})
767 node_indices
= map(points
.index
, nodes
)
771 raise ParsingError('Can\'t map node indices')
773 for node
in node_indices
:
774 if '_out' not in pointattrs
[node
]:
777 node_indices
.append(node_indices
[0])
778 return (pts
, node_indices
)
781 for key
, value
in zip(pairs
[::2], pairs
[1::2]):
784 def convert_tag(way
, key
, value
, feat
):
785 if key
.lower() in [ 'label', 'lable', 'lablel' ]:
787 refpos
= label
.find("~[")
790 ## refstr, sep, right = label[refpos + 2:].partition(' ') # py_ver >= 2.5 version
791 label_split
= label
[refpos
+ 2:].split(' ',1) # above line in py_ver = 2.4
792 if len(label_split
) == 2:
793 refstr
,right
= label
[refpos
+ 2:].split(' ',1)
795 refstr
= label_split
[0]
798 code
, ref
= refstr
.split(']')
799 label
= (label
[:refpos
] + right
).strip(' \t')
800 way
[reftype
[int(code
, 0)]] = ref
.replace("/", ";")
802 if code
.lower() == '0x06':
804 elif code
.lower() == '0x1b':
805 way
['loc_name'] = right
806 elif code
.lower() == '0x1c':
807 way
['loc_name'] = ref
809 raise ParsingError('Problem parsing label ' + value
)
811 if 'name' not in way
and label
!= "":
813 elif key
.lower() in [ 'label2', 'lanel2', 'lable2', 'level2', 'lbel2' ]:
815 elif key
.lower() == 'label3':
816 way
['loc_name'] = value
817 elif key
== 'DirIndicator':
818 way
['oneway'] = value
819 elif key
in [ 'Data0', 'Data1', 'Data2', 'Data3', 'Data4' ]:
821 count
, way
['_nodes'] = prepare_line(value
, feat
== Features
.polygon
)
826 # way['layer'] = num ??
827 elif key
.startswith('_Inner'):
828 count
, nodes
= prepare_line(value
, feat
== Features
.polygon
)
829 if '_innernodes' not in way
:
830 way
['_innernodes'] = []
831 if feat
!= Features
.polygon
:
833 way
['_innernodes'].append(nodes
)
839 if feat
== Features
.polygon
:
840 tag(way
, shape_types
[int(value
, 0)])
841 elif feat
== Features
.polyline
:
842 tag(way
, pline_types
[int(value
, 0)])
844 tag(way
, poi_types
[int(value
, 0)])
845 elif key
in [ 'EndLevel', 'Level', 'Levles' ]:
846 # if 'highway' not in way:
847 # way['highway'] = levels[int(value, 0)]
848 # way['layer'] = str(value) ??
850 elif key
.lower() == 'miasto' or key
.lower() == 'miato':
851 way
['addr:city'] = value
852 elif key
== 'StreetDesc':
853 way
['addr:street'] = value
854 elif key
== 'RouteParam':
855 params
= value
.split(',')
857 way
['maxspeed'] = maxspeeds
[params
[0]] # Probably useless
859 way
['oneway'] = 'yes'
862 for i
, val
in enumerate(params
[4:]):
864 way
[exceptions
[i
]] = 'no'
865 elif key
== 'RestrParam':
866 params
= value
.split(',')
868 for i
, val
in enumerate(params
[4:]):
870 excpts
.append(exceptions
[i
])
871 way
['except'] = ','.join(excpts
)
872 elif key
== 'HLevel0':
873 if feat
!= Features
.polyline
:
874 raise ParsingError('HLevel0 used on a polygon')
878 for level
in value
.split(')'):
881 pair
= level
.strip(', ()').split(',')
882 start
= int(pair
[0], 0)
883 level
= int(pair
[1], 0)
884 if start
> curnode
and level
!= curlevel
:
885 list.append((curnode
, start
, curlevel
))
888 list.append((curnode
, -1, curlevel
))
889 way
['_levels'] = list
892 for colour
in value
.split(','):
893 if colour
.lower() == 'zolty':
894 ref
.append('Żółty szlak')
895 way
['marked_trail_yellow'] = 'yes'
896 elif colour
.lower() == 'zielony':
897 ref
.append('Zielony szlak')
898 way
['marked_trail_green'] = 'yes'
899 elif colour
.lower() == 'czerwony':
900 ref
.append('Czerwony szlak')
901 way
['marked_trail_red'] = 'yes'
902 elif colour
.lower() == 'niebieski':
903 ref
.append('Niebieski szlak')
904 way
['marked_trail_blue'] = 'yes'
907 sys
.stderr
.write("warning: Unknown 'Szlak' colour: " +
909 way
['ref'] = ";".join(ref
)
910 elif key
.startswith('NumbersExt'):
911 sys
.stderr
.write("warning: " + key
+ " tag discarded\n")
912 elif key
.startswith('Numbers'):
913 unused
= int(key
[7:], 0)
914 value
= value
.split(',')
916 raise ParsingError("Bad address info specification")
917 if '_addr' not in way
:
919 way
['_addr'][int(value
[0], 0)] = value
[1:]
920 elif key
.lower() == 'rampa':
921 way
['bridge'] = 'yes'
922 elif key
== 'Highway':
924 elif key
.startswith('Exit'):
925 way
[key
.lower()] = value
926 elif key
== 'OvernightParking':
927 way
['overnight_parking'] = 'yes'
930 elif key
== 'HouseNumber':
931 way
['addr:housenumber'] = value
932 elif key
== 'KodPoczt':
933 way
['addr:postcode'] = value
935 way
['hour_on'] = value
936 elif key
== 'ForceClass' or key
== 'ForceSpeed':
937 fclass
= int(value
) # Routing helper
938 # Ignore it for the moment, seems to be used mainly for temporary setups
941 way
['maxspeed'] = value
942 elif key
== 'Height_m':
943 way
['maxheight'] = value
944 elif key
in [ 'Nod0', 'Nod1' ]:
945 # TODO: what does this do?
948 if key
.lower() in [ 'levels', 'lavels', 'city', 'typ', 'plik' ]:
951 raise ParsingError("Unknown key " + key
+ " in polyline / polygon")
955 lat
= math
.radians(lat
)
956 return math
.degrees(math
.log(math
.tan(lat
) + 1.0 / math
.cos(lat
)))
957 def projlon(lat
, lon
):
959 def unproj(lat
, lon
):
960 lat
= math
.radians(lat
)
961 return (math
.degrees(math
.atan(math
.sinh(lat
))), lon
)
962 #def unproj(lat, lon):
963 # return (lat, lon / math.cos(lat / 180.0 * math.pi))
966 #def projlon(lat, lon):
967 # return lon * math.cos(lat / 180.0 * math.pi)
969 def add_addrinfo(nodes
, addrs
, street
, city
, right
, count
):
972 attrs
= { 'addr:street': street
}
974 attrs
['addr:city'] = city
975 for n
, node
in enumerate(nodes
[:-1]):
976 if n
in addrs
and node
!= nodes
[n
+ 1]:
977 type = addrs
[n
][right
* 3 + 0].lower()
978 if type not in interp_types
:
980 type = interp_types
[type]
981 low
= addrs
[n
][right
* 3 + 1]
982 hi
= addrs
[n
][right
* 3 + 2]
984 dist
= 0.0002 # degrees
985 lat
= projlat(float(points
[node
][0]))
986 lon
= projlon(lat
, float(points
[node
][1]))
987 nlat
= projlat(float(points
[nodes
[n
+ 1]][0]))
988 nlon
= projlon(nlat
, float(points
[nodes
[n
+ 1]][1]))
989 dlen
= math
.hypot(nlat
- lat
, nlon
- lon
)
990 normlat
= (nlat
- lat
) / dlen
* dist
991 normlon
= (nlon
- lon
) / dlen
* dist
999 shortlat
= normlat
* 2
1000 shortlon
= normlon
* 2
1001 elif dlen
> dist
* 3:
1008 if 0: #prev_house == low:
1009 low_node
= prev_node
1011 shortlat
= (nlat
- lat
) / 2
1012 shortlon
= (nlon
- lon
) / 2
1016 low_node
= unproj(lat
+ dlat
+ shortlat
, lon
+ dlon
+ shortlon
)
1017 while low_node
in points
:
1018 low_node
= (low_node
[0] + normlat
/ 10,
1019 low_node
[1] + normlon
/ 10)
1020 attrs
['addr:housenumber'] = low
1021 points_append(low_node
, attrs
.copy())
1024 hi_node
= unproj(nlat
+ dlat
- shortlat
, nlon
+ dlon
- shortlon
)
1025 while hi_node
in points
:
1026 hi_node
= (hi_node
[0] - normlat
/ 10, hi_node
[1] - normlon
/ 10)
1027 attrs
['addr:housenumber'] = hi
1028 points_append(hi_node
, attrs
.copy())
1030 if len(addrs
[n
]) >= 8:
1031 if addrs
[n
][6] != "-1":
1032 pointattrs
[pt0
]['addr:postcode'] = addrs
[n
][6]
1033 if addrs
[n
][7] != "-1":
1034 pointattrs
[pt1
]['addr:postcode'] = addrs
[n
][7]
1035 if len(addrs
[n
]) >= 14:
1036 if addrs
[n
][8] != "-1":
1037 pointattrs
[pt0
]['addr:city'] = addrs
[n
][8]
1038 if addrs
[n
][9] != "-1":
1039 pointattrs
[pt0
]['addr:region'] = addrs
[n
][9]
1040 if addrs
[n
][10] != "-1":
1041 pointattrs
[pt0
]['addr:country'] = addrs
[n
][10]
1042 if addrs
[n
][11] != "-1":
1043 pointattrs
[pt1
]['addr:city'] = addrs
[n
][11]
1044 if addrs
[n
][12] != "-1":
1045 pointattrs
[pt1
]['addr:region'] = addrs
[n
][12]
1046 if addrs
[n
][13] != "-1":
1047 pointattrs
[pt1
]['addr:country'] = addrs
[n
][13]
1050 '_nodes': [pt0
, pt1
],
1051 'addr:interpolation': type,
1064 class NodesToWayNotFound(ValueError):
1066 Raised when way of two nodes can not be found
1068 def __init__(self
,node_a
,node_b
):
1069 self
.node_a
= node_a
1070 self
.node_b
= node_b
1073 return "<NodesToWayNotFound %r,%r>" % (self
.node_a
,self
.node_b
,)
1075 def nodes_to_way(a
, b
):
1077 ## print("DEBUG: way['_nodes']: %r" % (way['_nodes'],)
1078 if a
in way
['_nodes'] and b
in way
['_nodes']:
1079 # Hopefully there's only one
1082 raise NodesToWayNotFound(a
, b
)
1085 way_nodes
= way
['_nodes']
1087 print("DEBUG: node a: %r found in way: %r" % (a
, way
))
1089 print("DEBUG: node b: %r found in way: %r" % (b
, way
))
1091 ## print "DEBUG: no way nodes: a: %r b: %r" % (a, b)
1092 raise NodesToWayNotFound(a
, b
)
1100 def next_node(pivot
, dir):
1101 way
= nodes_to_way(dir, pivot
)['_nodes']
1102 pivotidx
= way
.index(pivot
)
1103 return way
[pivotidx
+ signbit(way
.index(dir) - pivotidx
)]
1105 def split_way(way
, node
):
1106 l
= len(way
['_nodes'])
1107 i
= way
['_nodes'].index(node
)
1108 if i
== 0 or i
== l
- 1:
1112 newway
['_nodes'] = way
['_nodes'][:i
+ 1]
1113 way
['_nodes'] = way
['_nodes'][i
:]
1115 def preprepare_restriction(rel
):
1116 rel
['_nodes'][0] = next_node(rel
['_nodes'][1], rel
['_nodes'][0])
1117 rel
['_nodes'][-1] = next_node(rel
['_nodes'][-2], rel
['_nodes'][-1])
1119 def prepare_restriction(rel
):
1120 fromnode
= rel
['_nodes'][0]
1121 fromvia
= rel
['_nodes'][1]
1122 tonode
= rel
['_nodes'][-1]
1123 tovia
= rel
['_nodes'][-2]
1124 split_way(nodes_to_way(fromnode
, fromvia
), fromvia
)
1125 split_way(nodes_to_way(tonode
, tovia
), tovia
)
1127 def make_restriction_fromviato(rel
):
1128 nodes
= rel
.pop('_nodes')
1130 'from': ('way', [ ways
.index(nodes_to_way(nodes
[0], nodes
[1])) ]),
1131 'via': ('node', nodes
[1:-1]),
1132 'to': ('way', [ ways
.index(nodes_to_way(nodes
[-2], nodes
[-1])) ]),
1135 rel
['_c'] = ways
[rel
['_members']['from'][1][0]]['_c'] + \
1136 ways
[rel
['_members']['to'][1][0]]['_c']
1138 ways
[rel
['_members']['from'][1][0]]['_c'] += 1
1139 ways
[rel
['_members']['to'][1][0]]['_c'] += 1
1143 def name_turn_restriction(rel
, nodes
):
1144 # Try to suss out the type of restriction.. needs to be checked manually
1145 if 'name' in rel
and rel
['name'].lower().find('nakaz') != -1:
1150 if rel
['name'].find('<<') != -1:
1151 rel
['restriction'] = 'no_u_turn'
1152 elif rel
['name'].find('<') != -1:
1153 rel
['restriction'] = beginning
+ 'left_turn'
1154 elif rel
['name'].find('>') != -1:
1155 rel
['restriction'] = beginning
+ 'right_turn'
1157 # Multiple via nodes are not approved by OSM anyway
1158 if 'restriction' not in rel
and len(nodes
) == 3:
1159 # No projection needed
1160 alat
= float(points
[nodes
[0]][0])
1161 alon
= float(points
[nodes
[0]][1])
1162 blat
= float(points
[nodes
[1]][0])
1163 blon
= float(points
[nodes
[1]][1])
1164 clat
= float(points
[nodes
[2]][0])
1165 clon
= float(points
[nodes
[2]][1])
1166 # Vector cross product (?)
1167 angle
= (blat
- alat
) * (clon
- blon
) - (blon
- alon
) * (clat
- blat
)
1170 rel
['restriction'] = beginning
+ 'right_turn'
1172 rel
['restriction'] = beginning
+ 'no_left_turn'
1174 def make_multipolygon(outer
, holes
):
1176 'type': 'multipolygon',
1177 'note': 'FIXME: fix roles manually',
1179 '_src': outer
['_src'],
1181 'outer': ('way', [ ways
.index(outer
) ]),
1182 'inner': ('way', []),
1190 '_src': outer
['_src'],
1193 rel
['_members']['inner'][1].append(ways
.index(way
))
1194 polygon_make_ccw(way
)
1196 # Assume that the polygon with most nodes is the outer shape and
1197 # all other polygons are the holes.
1198 # That's a stupid heuristic but is much simpler than a complete
1199 # check of which polygons lie entirely inside other polygons and
1200 # there might turn up some very complex cases like polygons crossing
1201 # one another and multiple nesting.
1202 if len(inner
) > len(outer
['_nodes']):
1203 tmp
= outer
['_nodes']
1204 outer
['_nodes'] = inner
1206 way
['_nodes'].reverse()
1210 def polygon_make_ccw(shape
):
1211 nodes
= shape
['_nodes']
1212 num
= len(nodes
) - 1
1218 for i
in range(num
):
1223 # No projection needed
1224 alat
= float(points
[nodes
[a
]][0])
1225 alon
= float(points
[nodes
[a
]][1])
1226 blat
= float(points
[nodes
[b
]][0])
1227 blon
= float(points
[nodes
[b
]][1])
1228 clat
= float(points
[nodes
[c
]][0])
1229 clon
= float(points
[nodes
[c
]][1])
1230 ablen
= math
.hypot(blat
- alat
, blon
- alon
)
1231 bclen
= math
.hypot(clat
- blat
, clon
- blon
)
1232 # Vector cross product (?)
1233 cross
= (blat
- alat
) * (clon
- blon
) - (blon
- alon
) * (clat
- blat
)
1234 # Vector dot product (?)
1235 dot
= (blat
- alat
) * (clat
- blat
) + (blon
- alon
) * (clon
- blon
)
1237 sine
= cross
/ (ablen
* bclen
)
1238 cosine
= dot
/ (ablen
* bclen
)
1239 angle
+= signbit(sine
) * math
.acos(cosine
)
1242 angle
= math
.degrees(-angle
)
1244 if angle
> -360.0 - epsilon
and angle
< -360.0 + epsilon
: # CW
1246 elif angle
> 360.0 - epsilon
and angle
< 360.0 + epsilon
: # CCW
1249 # Likely an illegal shape
1250 shape
['fixme'] = "Weird shape"
1254 return unicode(line
, "cp1250").encode("UTF-8")
1256 sys
.stderr
.write("warning: couldn't recode " + line
+ " in UTF-8!\n");
1259 def parse_txt(infile
):
1266 if line
== "[POLYLINE]":
1268 feat
= Features
.polyline
1269 elif line
== "[POLYGON]":
1271 feat
= Features
.polygon
1272 elif line
== "[POI]":
1275 elif line
== "[IMG ID]":
1276 feat
= Features
.ignore
1277 elif line
== '[END]':
1278 way
= { '_src': srcidx
}
1279 for key
in polyline
:
1280 convert_tag(way
, key
, polyline
[key
], feat
)
1281 if comment
is not None:
1282 way
['note'] = comment
1284 if 'Type' in polyline
:
1285 highway
= int(polyline
['Type'], 0)
1286 for i
in way
['_nodes']:
1287 if maxtypes
[i
] > highway
:
1288 maxtypes
[i
] = highway
1292 addrinfo
= way
.pop('_addr')
1294 street
= way
['name']
1297 add_addrinfo(way
['_nodes'], addrinfo
,
1298 street
, miasto
, 0, way
['_c'])
1299 add_addrinfo(way
['_nodes'], addrinfo
,
1300 street
, miasto
, 1, way
['_c'])
1301 if 'ele' in way
and way
['ele'] == '_name':
1302 way
['ele'] = way
.pop('name').replace(',', '.')
1303 if 'depth' in way
and way
['depth'] == '_name':
1304 way
['depth'] = way
.pop('name').replace(',', '.')
1305 if feat
== Features
.polygon
:
1306 polygon_make_ccw(way
)
1308 if feat
== Features
.poi
:
1309 # execution order shouldn't matter here, unlike in C
1310 pointattrs
[way
.pop('_nodes')[0]] = way
1311 if not way
.pop('_c'):
1315 elif feat
== Features
.ignore
:
1316 # Ignore everything within e.g. [IMG ID] until some other
1317 # rule picks up something interesting, e.g. a polyline
1319 elif polyline
is not None and line
!= '':
1321 key
, value
= line
.split('=', 1)
1324 raise ParsingError('Can\'t split the thing')
1327 if key
.startswith('Data'):
1329 while key
in polyline
:
1330 key
= "_Inner" + str(int(key
[6:]) + 1)
1331 elif key
== 'City' and polyline
[key
] == 'Y':
1334 raise ParsingError('Key ' + key
+ ' repeats')
1335 polyline
[key
] = recode(value
).strip()
1336 elif line
.startswith(';'):
1337 strn
= recode(line
[1:].strip(" \t\n"))
1338 if comment
is not None:
1339 comment
= comment
+ " " + strn
1342 elif line
.startswith('Miasto='):
1343 miasto
= recode(line
[7:].strip(" \t\n"))
1345 raise ParsingError('Unhandled line ' + line
)
1347 def parse_pnt(infile
):
1348 # raise ParsingError('No?')
1353 if len(sys
.argv
) < 2 or sys
.argv
[1] == "--help":
1354 print("Usage: " + sys
.argv
[0] + " [files...]")
1356 print("\t ./txt2osm.py UMP-Warszawa/src/WOLOMIN*.txt -- UMP-Warszawa/src/*.txt > wolomin.osm")
1358 for n
, f
in enumerate(sys
.argv
[1:]):
1363 if f
in sys
.argv
[1:srcidx
]:
1366 infile
= open(f
, "r")
1368 sys
.stderr
.write("Can't open file " + f
+ "!\n")
1370 sys
.stderr
.write("Loading " + f
+ "\n")
1372 if f
.endswith("pnt") or f
.endswith("pnt.txt"):
1374 elif f
.endswith("txt") or f
.endswith("mp"):
1379 # Use the road class of the most important (lowest numbered) road
1380 # that meets the roundabout.
1382 if 'junction' in way
and way
['junction'] == 'roundabout':
1383 maxtype
= 0x7 # service
1384 for i
in way
['_nodes']:
1385 if maxtypes
[i
] < maxtype
:
1386 maxtype
= maxtypes
[i
]
1387 tag(way
, pline_types
[maxtype
])
1390 # TODO make sure nodes are ordered counter-clockwise
1393 # find them, remove from /ways/ and move to /relations/
1395 # For restriction relations: locate members and split member ways
1396 # at the "via" node as required by
1397 # http://wiki.openstreetmap.org/wiki/Relation:restriction
1398 relations
= [rel
for rel
in ways
if '_rel' in rel
]
1399 for rel
in relations
:
1400 rel
['type'] = rel
.pop('_rel')
1403 for rel
in relations
:
1404 if rel
['type'] in [ 'restriction', 'lane_restriction' ]:
1406 preprepare_restriction(rel
)
1407 ## print "DEBUG: preprepare_restriction(rel:%r) OK." % (rel,)
1408 except NodesToWayNotFound
:
1409 sys
.stderr
.write("warning: Unable to find nodes to preprepare "
1410 "restriction from rel: %r\n" % (rel
,))
1412 # Way level: split ways on level changes
1413 # TODO: possibly emit a relation to group the ways
1414 levelledways
= [way
for way
in ways
if '_levels' in way
]
1415 for way
in levelledways
:
1417 if '_levels' in way
:
1418 nodes
= way
['_nodes']
1419 levels
= way
.pop('_levels')
1420 for segment
in levels
:
1422 if segment
[1] == -1:
1423 subway
['_nodes'] = nodes
[segment
[0]:]
1425 subway
['_nodes'] = nodes
[segment
[0]:segment
[1] + 1]
1427 subway
['layer'] = str(segment
[2])
1429 subway
['bridge'] = 'yes'
1431 subway
['tunnel'] = 'yes'
1435 if '_innernodes' in way
:
1438 for segment
in way
.pop('_innernodes'):
1440 subway
['_nodes'] = segment
1443 relations
.append(make_multipolygon(way
, way
.pop('_innernodes')))
1445 for rel
in relations
:
1446 if rel
['type'] in [ 'restriction', 'lane_restriction' ]:
1448 prepare_restriction(rel
)
1449 except NodesToWayNotFound
:
1450 sys
.stderr
.write("warning: Unable to find nodes to " +
1451 "preprepare restriction from rel: %r\n" % (rel
,))
1452 for rel
in relations
:
1453 if rel
['type'] in [ 'restriction', 'lane_restriction' ]:
1455 rnodes
= make_restriction_fromviato(rel
)
1457 if rel
['type'] == 'restriction':
1458 name_turn_restriction(rel
, rnodes
)
1459 except NodesToWayNotFound
:
1460 sys
.stderr
.write("warning: Unable to find nodes to " +
1461 "preprepare restriction from rel: %r\n" % (rel
,))
1465 if 'highway' in way
and way
['highway'] == 'unclassified':
1467 way
['highway'] = 'residential'
1468 way
['surface'] = 'unpaved'
1470 way
['highway'] = 'track'
1471 if 'note' not in way
:
1472 way
['note'] = 'FIXME: select one of: residential, unclassified, track'
1474 for index
, point
in enumerate(pointattrs
):
1475 if 'shop' in point
and point
['shop'] == 'fixme':
1477 if index
in way
['_nodes'] and 'highway' in way
:
1479 point
['noexit'] = 'yes'
1484 for node
in way
['_nodes']:
1485 if '_out' in pointattrs
[node
]:
1486 del pointattrs
[node
]['_out']
1488 print("<?xml version='1.0' encoding='UTF-8'?>")
1489 print("<osm version='0.6' generator='txt2osm %s converter for UMP-PL'>" \
1492 for index
, point
in enumerate(points
):
1493 print_point(point
, index
, sys
.argv
)
1495 for index
, way
in enumerate(ways
):
1496 print_way(way
, index
, sys
.argv
)
1498 for index
, rel
in enumerate(relations
):
1499 print_relation(rel
, index
, sys
.argv
)