Mon, 14 Sep 2020 22:55:45 +0300
restore .hg...
0 | 1 | #!/usr/bin/env python3 |
2 | ||
3 | # Generate highway shields as SVG files in symbols/shields. | |
4 | ||
5 | from __future__ import print_function | |
6 | import copy, lxml.etree, math, os | |
7 | ||
8 | ||
9 | def main(): | |
10 | namespace = 'http://www.w3.org/2000/svg' | |
11 | svgns = '{' + namespace + '}' | |
12 | svgnsmap = {None: namespace} | |
13 | ||
14 | config = {} | |
15 | config['base'] = {} | |
16 | ||
17 | # font_height and font_width are determined by trial and error | |
18 | config['base']['rounded_corners'] = 2 | |
19 | config['base']['font_height'] = 11 | |
20 | config['base']['font_width'] = 0.85 | |
21 | config['base']['padding_x'] = 8 | |
22 | config['base']['padding_y'] = 2 | |
23 | config['base']['stroke_width'] = 1 | |
24 | ||
25 | # Fall back colours used if no colours are defined in road-colours.yaml for a road type. | |
26 | config['base']['fill'] = '#f1f1f1' | |
27 | config['base']['stroke_fill'] = '#c6c6c6' | |
28 | ||
29 | config['global'] = {} | |
30 | ||
31 | config['global']['types'] = ['valtatie', 'kantatie', 'seututie', 'yhdystie', 'eurooppatie'] | |
32 | config['global']['max_width'] = 48 | |
33 | config['global']['output_dir'] = '../symbols/shields/' # specified relative to the script location | |
34 | ||
35 | config['valtatie'] = {'fill': '#ff163c', 'stroke_fill': 'white'} | |
36 | config['kantatie'] = {'fill': '#ffd90f', 'stroke_fill': 'black', 'stroke_width': 0.5} | |
37 | config['seututie'] = {'fill': 'white', 'stroke_fill': 'black', 'stroke_width': 0.5} | |
38 | config['yhdystie'] = {'fill': '#005eb7', 'stroke_fill': 'white'} | |
39 | config['eurooppatie'] = {'fill': '#00997c', 'stroke_fill': 'white'} | |
40 | ||
41 | if not os.path.exists(os.path.dirname(config['global']['output_dir'])): | |
42 | os.makedirs(os.path.dirname(config['global']['output_dir'])) | |
43 | ||
44 | height = 1 | |
45 | shield_size = 'base' | |
46 | ||
47 | dirpath = os.path.join(os.path.dirname(__file__), config['global']['output_dir']) | |
48 | try: | |
49 | os.makedirs(dirpath) | |
50 | except FileExistsError: | |
51 | pass | |
52 | ||
53 | for width in range(1, config['global']['max_width'] + 1): | |
54 | for shield_type in config['global']['types']: | |
55 | ||
56 | # merge base config and specific styles | |
57 | vars = copy.deepcopy(config['base']) | |
58 | if shield_type in config: | |
59 | for option in config[shield_type]: | |
60 | vars[option] = config[shield_type][option] | |
61 | ||
62 | shield_width = 2 * vars['padding_x'] + math.ceil(vars['font_width'] * width) | |
63 | shield_height = 2 * vars['padding_y'] + math.ceil(vars['font_height'] * height) | |
64 | ||
65 | svg = lxml.etree.Element('svg', nsmap=svgnsmap) | |
66 | svg.set('width', '100%') | |
67 | svg.set('height', '100%') | |
68 | svg.set('viewBox', '0 0 ' + str(shield_width + vars['stroke_width']) + ' ' + str(shield_height + vars['stroke_width'])) | |
69 | ||
70 | if vars['stroke_width'] > 0: | |
71 | offset_x = vars['stroke_width'] / 2.0 | |
72 | offset_y = vars['stroke_width'] / 2.0 | |
73 | else: | |
74 | offset_x = 0 | |
75 | offset_y = 0 | |
76 | ||
77 | background = lxml.etree.Element(svgns + 'rect') | |
78 | background.set('x', str(offset_x)) | |
79 | background.set('y', str(offset_y)) | |
80 | background.set('width', str(shield_width)) | |
81 | background.set('height', str(shield_height)) | |
82 | background.set('id', 'shield-background') | |
83 | background.set('style', 'fill:' + vars['fill']) | |
84 | svg.append(background) | |
85 | ||
86 | shield = lxml.etree.Element(svgns + 'rect') | |
87 | shield.set('x', str(offset_x + 0.5)) | |
88 | shield.set('y', str(offset_y + 0.5)) | |
89 | shield.set('width', str(shield_width - 1)) | |
90 | shield.set('height', str(shield_height - 1)) | |
91 | if vars['rounded_corners'] > 0: | |
92 | shield.set('rx', str(vars['rounded_corners'])) | |
93 | shield.set('ry', str(vars['rounded_corners'])) | |
94 | shield.set('id', 'shield') | |
95 | ||
96 | stroke = '' | |
97 | if vars['stroke_width'] > 0: | |
98 | stroke = 'stroke:' + vars['stroke_fill'] + ';stroke-width:' + str(vars['stroke_width']) + ';' | |
99 | ||
100 | shield.set('style', 'fill:' + vars['fill'] + ';' + stroke) | |
101 | ||
102 | svg.append(shield) | |
103 | ||
104 | filename = shield_type + '_' + str(width) + 'x' + str(height) | |
105 | if shield_size != 'base': | |
106 | filename = filename + '_' + shield_size | |
107 | ||
108 | filename = filename + '.svg' | |
109 | ||
110 | # save file | |
111 | try: | |
112 | shieldpath = os.path.join(os.path.dirname(__file__), config['global']['output_dir'] + filename) | |
113 | print('Writing', os.path.realpath(shieldpath)) | |
114 | shieldfile = open(shieldpath, 'wb') | |
115 | shieldfile.write(lxml.etree.tostring(svg, encoding='utf-8', xml_declaration=True, pretty_print=True)) | |
116 | shieldfile.close() | |
117 | except IOError: | |
118 | print('Could not save file ' + filename + '.') | |
119 | continue | |
120 | ||
121 | if __name__ == "__main__": | |
122 | main() |