diff --git a/src/c3nav/mapdata/render/engines/base.py b/src/c3nav/mapdata/render/engines/base.py index 494fff10..1425a84f 100644 --- a/src/c3nav/mapdata/render/engines/base.py +++ b/src/c3nav/mapdata/render/engines/base.py @@ -1,10 +1,11 @@ import math from abc import ABC, abstractmethod -from functools import lru_cache from typing import Optional from shapely.geometry import JOIN_STYLE, box +from c3nav.mapdata.utils.color import color_to_rgb + class FillAttribs: __slots__ = ('color', 'opacity') @@ -60,14 +61,8 @@ class RenderEngine(ABC): pass @staticmethod - @lru_cache() def color_to_rgb(color, alpha=None): - if color.startswith('#'): - return (*(int(color[i:i + 2], 16) / 255 for i in range(1, 6, 2)), 1 if alpha is None else alpha) - if color.startswith('rgba('): - color = tuple(float(i.strip()) for i in color.strip()[5:-1].split(',')) - return (*(i/255 for i in color[:3]), color[3] if alpha is None else alpha) - raise ValueError('invalid color string!') + return color_to_rgb(color, alpha=None) def add_group(self, group): pass diff --git a/src/c3nav/mapdata/render/renderer.py b/src/c3nav/mapdata/render/renderer.py index a67c7c18..06c6912b 100644 --- a/src/c3nav/mapdata/render/renderer.py +++ b/src/c3nav/mapdata/render/renderer.py @@ -7,6 +7,7 @@ from c3nav.mapdata.render.engines.base import FillAttribs, StrokeAttribs from c3nav.mapdata.render.geometry import hybrid_union from c3nav.mapdata.render.renderdata import LevelRenderData from c3nav.mapdata.render.utils import get_full_levels, get_min_altitude +from c3nav.mapdata.utils.color import color_to_rgb, rgb_to_color class MapRenderer: @@ -109,12 +110,22 @@ class MapRenderer: for color, color_obstacles in height_obstacles.items(): print(height, color) for obstacle in color_obstacles: - engine.add_geometry( - obstacle, - fill=FillAttribs(color or '#B7B7B7'), - stroke=None if color else StrokeAttribs('#888888', 0.05, min_px=0.2), - category='obstacles' - ) + if color: + fill_rgb = color_to_rgb(color) + stroke_color = rgb_to_color((*((0.75*i) for i in fill_rgb[:3]), fill_rgb[3])) + engine.add_geometry( + obstacle, + fill=FillAttribs(color), + stroke=StrokeAttribs(stroke_color, 0.05, min_px=0.2), + category='obstacles' + ) + else: + engine.add_geometry( + obstacle, + fill=FillAttribs('#B7B7B7'), + stroke=StrokeAttribs('#888888', 0.05, min_px=0.2), + category='obstacles' + ) # add walls, stroke_px makes sure that all walls are at least 1px thick on all zoom levels, walls = None diff --git a/src/c3nav/mapdata/utils/color.py b/src/c3nav/mapdata/utils/color.py new file mode 100644 index 00000000..6b7ae5b0 --- /dev/null +++ b/src/c3nav/mapdata/utils/color.py @@ -0,0 +1,17 @@ +from functools import lru_cache + + +@lru_cache() +def color_to_rgb(color, alpha=None): + if color.startswith('#'): + return (*(int(color[i:i + 2], 16) / 255 for i in range(1, 6, 2)), 1 if alpha is None else alpha) + if color.startswith('rgba('): + color = tuple(float(i.strip()) for i in color.strip()[5:-1].split(',')) + return (*(i/255 for i in color[:3]), color[3] if alpha is None else alpha) + raise ValueError('invalid color string!') + + +@lru_cache() +def rgb_to_color(rgb): + # noinspection PyStringFormat + return 'rgba(%d, %d, %d, %.1f)' % (*(i*255 for i in rgb[:3]), rgb[3])