--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/generate_shields.py Mon Sep 14 22:55:45 2020 +0300 @@ -0,0 +1,122 @@ +#!/usr/bin/env python3 + +# Generate highway shields as SVG files in symbols/shields. + +from __future__ import print_function +import copy, lxml.etree, math, os + + +def main(): + namespace = 'http://www.w3.org/2000/svg' + svgns = '{' + namespace + '}' + svgnsmap = {None: namespace} + + config = {} + config['base'] = {} + + # font_height and font_width are determined by trial and error + config['base']['rounded_corners'] = 2 + config['base']['font_height'] = 11 + config['base']['font_width'] = 0.85 + config['base']['padding_x'] = 8 + config['base']['padding_y'] = 2 + config['base']['stroke_width'] = 1 + + # Fall back colours used if no colours are defined in road-colours.yaml for a road type. + config['base']['fill'] = '#f1f1f1' + config['base']['stroke_fill'] = '#c6c6c6' + + config['global'] = {} + + config['global']['types'] = ['valtatie', 'kantatie', 'seututie', 'yhdystie', 'eurooppatie'] + config['global']['max_width'] = 48 + config['global']['output_dir'] = '../symbols/shields/' # specified relative to the script location + + config['valtatie'] = {'fill': '#ff163c', 'stroke_fill': 'white'} + config['kantatie'] = {'fill': '#ffd90f', 'stroke_fill': 'black', 'stroke_width': 0.5} + config['seututie'] = {'fill': 'white', 'stroke_fill': 'black', 'stroke_width': 0.5} + config['yhdystie'] = {'fill': '#005eb7', 'stroke_fill': 'white'} + config['eurooppatie'] = {'fill': '#00997c', 'stroke_fill': 'white'} + + if not os.path.exists(os.path.dirname(config['global']['output_dir'])): + os.makedirs(os.path.dirname(config['global']['output_dir'])) + + height = 1 + shield_size = 'base' + + dirpath = os.path.join(os.path.dirname(__file__), config['global']['output_dir']) + try: + os.makedirs(dirpath) + except FileExistsError: + pass + + for width in range(1, config['global']['max_width'] + 1): + for shield_type in config['global']['types']: + + # merge base config and specific styles + vars = copy.deepcopy(config['base']) + if shield_type in config: + for option in config[shield_type]: + vars[option] = config[shield_type][option] + + shield_width = 2 * vars['padding_x'] + math.ceil(vars['font_width'] * width) + shield_height = 2 * vars['padding_y'] + math.ceil(vars['font_height'] * height) + + svg = lxml.etree.Element('svg', nsmap=svgnsmap) + svg.set('width', '100%') + svg.set('height', '100%') + svg.set('viewBox', '0 0 ' + str(shield_width + vars['stroke_width']) + ' ' + str(shield_height + vars['stroke_width'])) + + if vars['stroke_width'] > 0: + offset_x = vars['stroke_width'] / 2.0 + offset_y = vars['stroke_width'] / 2.0 + else: + offset_x = 0 + offset_y = 0 + + background = lxml.etree.Element(svgns + 'rect') + background.set('x', str(offset_x)) + background.set('y', str(offset_y)) + background.set('width', str(shield_width)) + background.set('height', str(shield_height)) + background.set('id', 'shield-background') + background.set('style', 'fill:' + vars['fill']) + svg.append(background) + + shield = lxml.etree.Element(svgns + 'rect') + shield.set('x', str(offset_x + 0.5)) + shield.set('y', str(offset_y + 0.5)) + shield.set('width', str(shield_width - 1)) + shield.set('height', str(shield_height - 1)) + if vars['rounded_corners'] > 0: + shield.set('rx', str(vars['rounded_corners'])) + shield.set('ry', str(vars['rounded_corners'])) + shield.set('id', 'shield') + + stroke = '' + if vars['stroke_width'] > 0: + stroke = 'stroke:' + vars['stroke_fill'] + ';stroke-width:' + str(vars['stroke_width']) + ';' + + shield.set('style', 'fill:' + vars['fill'] + ';' + stroke) + + svg.append(shield) + + filename = shield_type + '_' + str(width) + 'x' + str(height) + if shield_size != 'base': + filename = filename + '_' + shield_size + + filename = filename + '.svg' + + # save file + try: + shieldpath = os.path.join(os.path.dirname(__file__), config['global']['output_dir'] + filename) + print('Writing', os.path.realpath(shieldpath)) + shieldfile = open(shieldpath, 'wb') + shieldfile.write(lxml.etree.tostring(svg, encoding='utf-8', xml_declaration=True, pretty_print=True)) + shieldfile.close() + except IOError: + print('Could not save file ' + filename + '.') + continue + +if __name__ == "__main__": + main()