Skip to content

Commit

Permalink
Let generate_shields use road-colors.yaml
Browse files Browse the repository at this point in the history
Refactor generate_shields.py to use road-colors.yaml as well. It now
uses methods from generate_road_colours.py to do this.
  • Loading branch information
jdhoek committed Jul 11, 2016
1 parent 5290f17 commit d13cb88
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 148 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ data/
*.xml
node_modules/
localconfig.json

# Generated at runtime by Python.
*.pyc
**/*.pyc
38 changes: 24 additions & 14 deletions road-colors.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,28 @@ hue: [10, 106]
# Lightness ranges from 0 to 100; dark to bright.
# Chroma ranges from 0 to 100 too; unsaturated to fully saturated.
classes:
fill:
lightness: [70, 97]
chroma: [35, 29]
casing:
lightness: [50, 50]
chroma: [70, 55]
low-zoom:
lightness: [62, 92]
chroma: [50, 40]
low-zoom-casing:
lightness: [50, 70]
chroma: [50, 65]
# Colours for output into the MSS file
mss:
fill:
lightness: [70, 97]
chroma: [35, 29]
casing:
lightness: [50, 50]
chroma: [70, 55]
low-zoom:
lightness: [62, 92]
chroma: [50, 40]
low-zoom-casing:
lightness: [50, 70]
chroma: [50, 65]
shield:
lightness: [20, 25]
chroma: [40, 42]
# Colours used by the road shields script
shield:
lightness: [20, 25]
chroma: [40, 42]
fill:
lightness: [85, 95]
chroma: [12, 14]
stroke_fill:
lightness: [70, 80]
chroma: [22, 24]
35 changes: 25 additions & 10 deletions scripts/generate_road_colours.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,18 @@ def rgb_error(self):
return delta_e_cie2000(convert_color(self.m_lch, LabColor),
convert_color(sRGBColor.new_from_rgb_hex(self.rgb()), LabColor))


def main():
parser = argparse.ArgumentParser(description='Generates road colours')
parser.add_argument('-v', '--verbose', dest='verbose', help='Generates information about colour differences', action='store_true', default=False)
args = parser.parse_args()

settings = yaml.load(open('road-colors.yaml', 'r'))

def load_settings():
"""Read the settings from YAML."""
return yaml.load(open('road-colors.yaml', 'r'))

def generate_colours(settings, section):
"""Generate colour ranges.
Arguments:
settings -- The settings loaded by load_settings.
section -- Which section of the settings under 'classes' to use. Typically
'mss' or 'shields'.
"""
road_classes = settings['roads']
colour_divisions = len(road_classes) - 1
hues = OrderedDict()
Expand All @@ -62,7 +66,7 @@ def main():
# The higher the road classification, the higher its saturation. Conversely,
# the roads get brighter towards the lower end of the classification.

classes = settings['classes']
classes = settings['classes'][section]
for cls, params in classes.iteritems():
l = params['lightness']
c = params['chroma']
Expand All @@ -83,6 +87,18 @@ def main():
c += delta_c
l += delta_l

return colours

def main():
parser = argparse.ArgumentParser(description='Generates road colours')
parser.add_argument('-v', '--verbose', dest='verbose', help='Generates information about colour differences', action='store_true', default=False)
args = parser.parse_args()

settings = load_settings()
road_classes = settings['roads']
colour_divisions = len(road_classes) - 1
colours = generate_colours(settings, 'mss')

# Print a warning about the nature of these definitions.
print "/* This is generated code, do not change this file manually. */"
print "/* */"
Expand All @@ -91,7 +107,6 @@ def main():
print "/* ./scripts/generate_road_colours.py > road-colors-generated.mss */"
print "/* */"


for line_name, line_colours in colours.iteritems():
for name, colour in line_colours.iteritems():
if args.verbose:
Expand Down
247 changes: 123 additions & 124 deletions scripts/generate_shields.py
Original file line number Diff line number Diff line change
@@ -1,132 +1,131 @@
#!/usr/bin/env python

# generate highway shields
# Generate highway shields as SVG files in symbols/shields.

from __future__ import print_function
import copy, lxml.etree, math, os
from generate_road_colours import load_settings, generate_colours

def main():

namespace = 'http://www.w3.org/2000/svg'
svgns = '{' + namespace + '}'
svgnsmap = {None: namespace}

config = {}
config['base'] = {}

config['base']['rounded_corners'] = 2
config['base']['font_height'] = 9.1
config['base']['font_width'] = 5.9
config['base']['padding_x'] = 4
config['base']['padding_y'] = 2
config['base']['fill'] = '#ddd'
config['base']['stroke_width'] = 1
config['base']['stroke_fill'] = '#000'

config['global'] = {}

config['global']['types'] = ['motorway', 'trunk', 'primary', 'secondary', 'tertiary']
config['global']['max_width'] = 11
config['global']['max_height'] = 4
config['global']['output_dir'] = '../symbols/shields/' # specified relative to the script location

config['global']['additional_sizes'] = ['base', 'z16', 'z18']

# specific values overwrite config['base'] ones
config['motorway'] = {}
config['trunk'] = {}
config['primary'] = {}
config['secondary'] = {}
config['tertiary'] = {}

# colour values are generated by generate_road_colours.py

config['motorway']['fill'] = '#eccdd1' # Lch(85,12,10), error 0.3
config['motorway']['stroke_fill'] = '#d39da5' # Lch(70,22,10), error 0.2
config['trunk']['fill'] = '#f2d7ce' # Lch(88,12,42), error 1.0
config['trunk']['stroke_fill'] = '#d7a899' # Lch(73,22,42), error 0.9
config['primary']['fill'] = '#f3e3cf' # Lch(91,12,74), error 1.4
config['primary']['stroke_fill'] = '#d1b795' # Lch(76,22,74), error 1.8
config['secondary']['fill'] = '#eeefd7' # Lch(94,12,106), error 1.3
config['secondary']['stroke_fill'] = '#c4c69c' # Lch(79,22,106), error 1.5
config['tertiary']['fill'] = '#f1f1f1' # Lch(95,0,0), error 0.1
config['tertiary']['stroke_fill'] = '#c6c6c6' # Lch(80,0,0), error 0.1

# changes for different size versions
config['z16'] = {}
config['z18'] = {}

config['z16']['font_width'] = 6.5
config['z16']['font_height'] = 10.1
config['z18']['font_width'] = 7.2
config['z18']['font_height'] = 11.1

if not os.path.exists(os.path.dirname(config['global']['output_dir'])):
os.makedirs(os.path.dirname(config['global']['output_dir']))

for height in range(1, config['global']['max_height'] + 1):
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]

for shield_size in config['global']['additional_sizes']:

if shield_size != 'base':
if shield_size in config:
for option in config[shield_size]:
vars[option] = config[shield_size][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

shield = lxml.etree.Element(svgns + 'rect')
shield.set('x', str(offset_x))
shield.set('y', str(offset_y))
shield.set('width', str(shield_width))
shield.set('height', str(shield_height))
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:
shieldfile = open(os.path.join(os.path.dirname(__file__), config['global']['output_dir'] + filename), 'w')
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()
settings = load_settings()
colours = generate_colours(settings, 'shield')

namespace = 'http://www.w3.org/2000/svg'
svgns = '{' + namespace + '}'
svgnsmap = {None: namespace}

config = {}
config['base'] = {}

config['base']['rounded_corners'] = 2
config['base']['font_height'] = 9.1
config['base']['font_width'] = 5.9
config['base']['padding_x'] = 4
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'] = ['motorway', 'trunk', 'primary', 'secondary', 'tertiary']
config['global']['max_width'] = 11
config['global']['max_height'] = 4
config['global']['output_dir'] = '../symbols/shields/' # specified relative to the script location

config['global']['additional_sizes'] = ['base', 'z16', 'z18']

# specific values overwrite config['base'] ones
config['motorway'] = {}
config['trunk'] = {}
config['primary'] = {}
config['secondary'] = {}
config['tertiary'] = {}

# Colour values generated by generate_road_colours.py.
for line_name, line_colours in colours.iteritems():
for name, colour in line_colours.iteritems():
config[name][line_name] = colour.rgb()

# changes for different size versions
config['z16'] = {}
config['z18'] = {}

config['z16']['font_width'] = 6.5
config['z16']['font_height'] = 10.1
config['z18']['font_width'] = 7.2
config['z18']['font_height'] = 11.1

if not os.path.exists(os.path.dirname(config['global']['output_dir'])):
os.makedirs(os.path.dirname(config['global']['output_dir']))

for height in range(1, config['global']['max_height'] + 1):
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]

for shield_size in config['global']['additional_sizes']:

if shield_size != 'base':
if shield_size in config:
for option in config[shield_size]:
vars[option] = config[shield_size][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

shield = lxml.etree.Element(svgns + 'rect')
shield.set('x', str(offset_x))
shield.set('y', str(offset_y))
shield.set('width', str(shield_width))
shield.set('height', str(shield_height))
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:
shieldfile = open(os.path.join(os.path.dirname(__file__), config['global']['output_dir'] + filename), 'w')
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()

0 comments on commit d13cb88

Please sign in to comment.