regions.py

Fri, 05 Feb 2021 12:16:29 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Fri, 05 Feb 2021 12:16:29 +0200
changeset 4
ac067a42b00f
parent 2
7378b802ddf8
permissions
-rw-r--r--

update

1
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
1 #!/usr/bin/env python3
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
2 from xml.etree import ElementTree
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
3 from geometry import *
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
4
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
5 REGION_TYPES = ['major', 'minor']
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
6 REGION_KEY_VALUES = [x + '_region' for x in REGION_TYPES]
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
7 SHAPE_KEYS = [x + '_shapes' for x in REGION_TYPES]
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
8
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
9 def parse_nodes(root):
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
10 nodes = {}
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
11 for child in root:
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
12 if child.tag == 'node':
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
13 lat, lon = float(child.attrib['lat']), float(child.attrib['lon'])
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
14 nodes[child.attrib['id']] = Location(lat, lon)
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
15 return nodes
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
16
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
17 def parse_way(way, nodes):
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
18 def choose_shapes(way, boundary):
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
19 return (way['major_shapes']
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
20 if boundary == 'major_region'
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
21 else way['minor_shapes'])
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
22 result = {'minor_shapes': [], 'major_shapes': []}
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
23 shape = []
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
24 for child in way:
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
25 if child.tag == 'nd':
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
26 shape.append(child.attrib['ref'])
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
27 elif child.tag == 'tag':
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
28 key = child.attrib['k']
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
29 if key in SHAPE_KEYS:
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
30 raise ValueError(str.format('tag "{}" is not allowed', key))
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
31 result[key] = child.attrib['v']
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
32 if key == 'boundary' and result['boundary'] not in REGION_KEY_VALUES:
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
33 return None # we're not interested in it!
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
34 if shape[-1] != shape[0]:
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
35 raise ValueError('polygon is not closed: %r' % result)
2
7378b802ddf8 destination processing
Teemu Piippo <teemu@hecknology.net>
parents: 1
diff changeset
36 if 'boundary' in result:
7378b802ddf8 destination processing
Teemu Piippo <teemu@hecknology.net>
parents: 1
diff changeset
37 shape = [nodes[ref] for ref in shape[:-1]]
7378b802ddf8 destination processing
Teemu Piippo <teemu@hecknology.net>
parents: 1
diff changeset
38 choose_shapes(result, result['boundary']).append(Polygon(*shape))
7378b802ddf8 destination processing
Teemu Piippo <teemu@hecknology.net>
parents: 1
diff changeset
39 return result
1
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
40
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
41 def parse_boundaries(root, *, nodes):
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
42 for child in root:
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
43 if child.tag == 'way':
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
44 way = parse_way(child, nodes = nodes)
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
45 if way:
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
46 yield way
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
47
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
48 def parse_regions(filename):
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
49 from katakana import transliterate as transliterate_katakana
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
50 tree = ElementTree.parse(filename)
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
51 root = tree.getroot()
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
52 nodes = parse_nodes(root)
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
53 regions = dict()
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
54 extra_shapes = list()
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
55 for way in parse_boundaries(root, nodes = nodes):
4
Teemu Piippo <teemu@hecknology.net>
parents: 2
diff changeset
56 if 'boundary' in way and 'municipality' in way and 'name:fi' in way:
Teemu Piippo <teemu@hecknology.net>
parents: 2
diff changeset
57 def clean(x):
Teemu Piippo <teemu@hecknology.net>
parents: 2
diff changeset
58 return x.replace('/', '').replace(';', '')
Teemu Piippo <teemu@hecknology.net>
parents: 2
diff changeset
59 way['ref'] = str.format(
Teemu Piippo <teemu@hecknology.net>
parents: 2
diff changeset
60 '{municipality}/{name}',
Teemu Piippo <teemu@hecknology.net>
parents: 2
diff changeset
61 municipality = str.upper(clean(way['municipality'])),
Teemu Piippo <teemu@hecknology.net>
parents: 2
diff changeset
62 name = clean(way['name:fi']),
Teemu Piippo <teemu@hecknology.net>
parents: 2
diff changeset
63 )
1
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
64 # defines a region
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
65 way['via_factor'] = int(way.get('via_factor', 1))
2
7378b802ddf8 destination processing
Teemu Piippo <teemu@hecknology.net>
parents: 1
diff changeset
66 if way['ref'] in regions:
1
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
67 raise ValueError(str.format(
2
7378b802ddf8 destination processing
Teemu Piippo <teemu@hecknology.net>
parents: 1
diff changeset
68 'Region {ref} defined twice',
7378b802ddf8 destination processing
Teemu Piippo <teemu@hecknology.net>
parents: 1
diff changeset
69 ref = repr(way['ref']),
1
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
70 ))
2
7378b802ddf8 destination processing
Teemu Piippo <teemu@hecknology.net>
parents: 1
diff changeset
71 regions[way['ref']] = way
1
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
72 del way['boundary']
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
73 if 'external' in way:
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
74 way['boundary'] = 'minor_region'
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
75 for prefix in ['', 'short_', 'internal_']:
2
7378b802ddf8 destination processing
Teemu Piippo <teemu@hecknology.net>
parents: 1
diff changeset
76 name_key = prefix + 'name:fi'
7378b802ddf8 destination processing
Teemu Piippo <teemu@hecknology.net>
parents: 1
diff changeset
77 ja_name_key = prefix + 'name:ja'
7378b802ddf8 destination processing
Teemu Piippo <teemu@hecknology.net>
parents: 1
diff changeset
78 if name_key in way and way[name_key] and ja_name_key not in way:
7378b802ddf8 destination processing
Teemu Piippo <teemu@hecknology.net>
parents: 1
diff changeset
79 way[ja_name_key] = transliterate_katakana(way[name_key])
1
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
80 elif 'boundary' in way and 'is_in' in way:
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
81 # adds an extra shape to an existing region
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
82 extra_shapes.append(way)
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
83 for extra_shape in extra_shapes:
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
84 name = extra_shape['is_in']
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
85 try:
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
86 region = regions[name]
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
87 except KeyError:
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
88 raise ValueError(str.format(
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
89 'Extra shape refers to {name} which was not found: {extra_shape}',
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
90 name = repr(name),
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
91 extra_shape = repr(extra_shape),
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
92 ))
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
93 for key in SHAPE_KEYS:
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
94 region[key].extend(extra_shape[key])
f9788970fa46 begin work on bus compiler
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
95 return regions

mercurial