Get use of colors from scheme.

This commit is contained in:
Sergey Vartanov 2022-01-15 12:44:08 +03:00
parent 5d88d1d85d
commit c787f48058
4 changed files with 142 additions and 105 deletions

View file

@ -23,7 +23,6 @@ from map_machine.color import is_bright
__author__ = "Sergey Vartanov" __author__ = "Sergey Vartanov"
__email__ = "me@enzet.ru" __email__ = "me@enzet.ru"
DEFAULT_COLOR: Color = Color("#444444")
DEFAULT_SHAPE_ID: str = "default" DEFAULT_SHAPE_ID: str = "default"
DEFAULT_SMALL_SHAPE_ID: str = "default_small" DEFAULT_SMALL_SHAPE_ID: str = "default_small"
@ -359,7 +358,7 @@ class ShapeSpecification:
"""Specification for shape as a part of an icon.""" """Specification for shape as a part of an icon."""
shape: Shape shape: Shape
color: Color = DEFAULT_COLOR color: Color
offset: np.ndarray = np.array((0.0, 0.0)) offset: np.ndarray = np.array((0.0, 0.0))
flip_horizontally: bool = False flip_horizontally: bool = False
flip_vertically: bool = False flip_vertically: bool = False

View file

@ -182,7 +182,13 @@ class Point(Tagged):
text = text[:26] + ("..." if len(text) > 26 else "") text = text[:26] + ("..." if len(text) > 26 else "")
point = self.point + np.array((0.0, self.y + 2.0)) point = self.point + np.array((0.0, self.y + 2.0))
self.draw_text( self.draw_text(
svg, text, point, occupied, label.fill, size=label.size svg,
text,
point,
occupied,
label.fill,
label.size,
label.out_fill,
) )
def draw_text( def draw_text(
@ -192,8 +198,8 @@ class Point(Tagged):
point: np.ndarray, point: np.ndarray,
occupied: Optional[Occupied], occupied: Optional[Occupied],
fill: Color, fill: Color,
size: float = 10.0, size: float,
out_fill: Color = Color("white"), out_fill: Color,
out_opacity: float = 0.5, out_opacity: float = 0.5,
out_fill_2: Optional[Color] = None, out_fill_2: Optional[Color] = None,
out_opacity_2: float = 1.0, out_opacity_2: float = 1.0,

View file

@ -16,7 +16,6 @@ from map_machine.feature.direction import DirectionSet
from map_machine.map_configuration import MapConfiguration, LabelMode from map_machine.map_configuration import MapConfiguration, LabelMode
from map_machine.osm.osm_reader import Tagged, Tags from map_machine.osm.osm_reader import Tagged, Tags
from map_machine.pictogram.icon import ( from map_machine.pictogram.icon import (
DEFAULT_COLOR,
DEFAULT_SHAPE_ID, DEFAULT_SHAPE_ID,
Icon, Icon,
IconSet, IconSet,
@ -24,7 +23,7 @@ from map_machine.pictogram.icon import (
ShapeExtractor, ShapeExtractor,
ShapeSpecification, ShapeSpecification,
) )
from map_machine.text import Label, construct_text from map_machine.text import Label, TextConstructor
__author__ = "Sergey Vartanov" __author__ = "Sergey Vartanov"
__email__ = "me@enzet.ru" __email__ = "me@enzet.ru"
@ -287,7 +286,7 @@ class RoadMatcher(Matcher):
self.border_color: Color = Color( self.border_color: Color = Color(
scheme.get_color(structure["border_color"]) scheme.get_color(structure["border_color"])
) )
self.color: Color = Color("white") self.color: Color = scheme.get_color("road_color")
if "color" in structure: if "color" in structure:
self.color = Color(scheme.get_color(structure["color"])) self.color = Color(scheme.get_color(structure["color"]))
self.default_width: float = structure["default_width"] self.default_width: float = structure["default_width"]
@ -358,6 +357,12 @@ class Scheme:
# Storage for created icon sets. # Storage for created icon sets.
self.cache: dict[str, tuple[IconSet, int]] = {} self.cache: dict[str, tuple[IconSet, int]] = {}
self.text_constructor: TextConstructor = TextConstructor(
self.get_color("text_color"),
self.get_color("text_main_color"),
self.get_color("text_outline_color"),
)
@classmethod @classmethod
def from_file(cls, file_name: Path) -> "Scheme": def from_file(cls, file_name: Path) -> "Scheme":
""" """
@ -549,7 +554,9 @@ class Scheme:
default_shape = extractor.get_shape(DEFAULT_SHAPE_ID) default_shape = extractor.get_shape(DEFAULT_SHAPE_ID)
if not main_icon: if not main_icon:
main_icon = Icon([ShapeSpecification(default_shape)]) main_icon = Icon(
[ShapeSpecification(default_shape, self.get_color("default"))]
)
returned: IconSet = IconSet(main_icon, extra_icons, processed) returned: IconSet = IconSet(main_icon, extra_icons, processed)
self.cache[tags_hash] = returned, priority self.cache[tags_hash] = returned, priority
@ -593,11 +600,19 @@ class Scheme:
self, tags: Tags, processed: set[str], label_mode: LabelMode self, tags: Tags, processed: set[str], label_mode: LabelMode
) -> list[Label]: ) -> list[Label]:
"""Construct labels for not processed tags.""" """Construct labels for not processed tags."""
texts: list[Label] = construct_text(tags, processed, label_mode) texts: list[Label] = self.text_constructor.construct_text(
tags, processed, label_mode
)
for tag in tags: for tag in tags:
if self.is_writable(tag, tags[tag]) and tag not in processed: if self.is_writable(tag, tags[tag]) and tag not in processed:
texts.append(Label(tags[tag])) texts.append(
Label(
tags[tag],
self.get_color("text_color"),
self.get_color("text_outline_color"),
)
)
return texts return texts
def is_area(self, tags: Tags) -> bool: def is_area(self, tags: Tags) -> bool:
@ -624,7 +639,7 @@ class Scheme:
structure: Union[str, dict[str, Any]], structure: Union[str, dict[str, Any]],
extractor: ShapeExtractor, extractor: ShapeExtractor,
groups: dict[str, str] = None, groups: dict[str, str] = None,
color: Color = DEFAULT_COLOR, color: Optional[Color] = None,
) -> ShapeSpecification: ) -> ShapeSpecification:
""" """
Parse shape specification from structure, that is just shape string Parse shape specification from structure, that is just shape string
@ -632,7 +647,9 @@ class Scheme:
and offset (optional). and offset (optional).
""" """
shape: Shape = extractor.get_shape(DEFAULT_SHAPE_ID) shape: Shape = extractor.get_shape(DEFAULT_SHAPE_ID)
color: Color = color color: Color = (
color if color is not None else Color(self.colors["default"])
)
offset: np.ndarray = np.array((0.0, 0.0)) offset: np.ndarray = np.array((0.0, 0.0))
flip_horizontally: bool = False flip_horizontally: bool = False
flip_vertically: bool = False flip_vertically: bool = False

View file

@ -13,7 +13,6 @@ __author__ = "Sergey Vartanov"
__email__ = "me@enzet.ru" __email__ = "me@enzet.ru"
DEFAULT_FONT_SIZE: float = 10.0 DEFAULT_FONT_SIZE: float = 10.0
DEFAULT_COLOR: Color = Color("#444444")
@dataclass @dataclass
@ -21,7 +20,8 @@ class Label:
"""Text label.""" """Text label."""
text: str text: str
fill: Color = DEFAULT_COLOR fill: Color
out_fill: Color
size: float = DEFAULT_FONT_SIZE size: float = DEFAULT_FONT_SIZE
@ -70,111 +70,126 @@ def format_frequency(value: str) -> str:
return f"{value} " return f"{value} "
def get_text(tags: dict[str, Any], processed: set[str]) -> list[Label]: @dataclass
"""Get text representation of writable tags.""" class TextConstructor:
texts: list[Label] = []
values: list[str] = []
if "voltage:primary" in tags: default_color: Color
values.append(tags["voltage:primary"]) main_color: Color
processed.add("voltage:primary") default_out_color: Color
if "voltage:secondary" in tags: def label(self, text: str, size: float = DEFAULT_FONT_SIZE):
values.append(tags["voltage:secondary"]) return Label(
processed.add("voltage:secondary") text, self.default_color, self.default_out_color, size=size
if "voltage" in tags:
values = tags["voltage"].split(";")
processed.add("voltage")
if values:
texts.append(Label(", ".join(map(format_voltage, values))))
if "frequency" in tags:
text: str = ", ".join(
map(format_frequency, tags["frequency"].split(";"))
) )
texts.append(Label(text))
processed.add("frequency")
return texts def get_text(
self, tags: dict[str, Any], processed: set[str]
) -> list[Label]:
"""Get text representation of writable tags."""
texts: list[Label] = []
values: list[str] = []
if "voltage:primary" in tags:
values.append(tags["voltage:primary"])
processed.add("voltage:primary")
def construct_text( if "voltage:secondary" in tags:
tags: Tags, processed: set[str], label_mode: LabelMode values.append(tags["voltage:secondary"])
) -> list[Label]: processed.add("voltage:secondary")
"""Construct list of labels from OSM tags."""
texts: list[Label] = [] if "voltage" in tags:
values = tags["voltage"].split(";")
processed.add("voltage")
name: Optional[str] = None if values:
alternative_name: Optional[str] = None texts.append(self.label(", ".join(map(format_voltage, values))))
if "name" in tags: if "frequency" in tags:
name = tags["name"] text: str = ", ".join(
processed.add("name") map(format_frequency, tags["frequency"].split(";"))
elif "name:en" in tags: )
if not name: texts.append(self.label(text))
name = tags["name:en"] processed.add("frequency")
processed.add("name:en")
processed.add("name:en")
if "alt_name" in tags:
if alternative_name:
alternative_name += ", "
else:
alternative_name = ""
alternative_name += tags["alt_name"]
processed.add("alt_name")
if "old_name" in tags:
if alternative_name:
alternative_name += ", "
else:
alternative_name = ""
alternative_name += "ex " + tags["old_name"]
address: list[str] = get_address(tags, processed, label_mode)
if name:
texts.append(Label(name, Color("black")))
if alternative_name:
texts.append(Label(f"({alternative_name})"))
if address:
texts.append(Label(", ".join(address)))
if label_mode == LabelMode.MAIN:
return texts return texts
texts += get_text(tags, processed) def construct_text(
self, tags: Tags, processed: set[str], label_mode: LabelMode
) -> list[Label]:
"""Construct list of labels from OSM tags."""
if "route_ref" in tags: texts: list[Label] = []
texts.append(Label(tags["route_ref"].replace(";", " ")))
processed.add("route_ref")
if "cladr:code" in tags: name: Optional[str] = None
texts.append(Label(tags["cladr:code"], size=7.0)) alternative_name: Optional[str] = None
processed.add("cladr:code")
if "website" in tags: if "name" in tags:
link = tags["website"] name = tags["name"]
if link[:7] == "http://": processed.add("name")
link = link[7:] elif "name:en" in tags:
if link[:8] == "https://": if not name:
link = link[8:] name = tags["name:en"]
if link[:4] == "www.": processed.add("name:en")
link = link[4:] processed.add("name:en")
if link[-1] == "/": if "alt_name" in tags:
link = link[:-1] if alternative_name:
link = link[:25] + ("..." if len(tags["website"]) > 25 else "") alternative_name += ", "
texts.append(Label(link, Color("#000088"))) else:
processed.add("website") alternative_name = ""
alternative_name += tags["alt_name"]
processed.add("alt_name")
if "old_name" in tags:
if alternative_name:
alternative_name += ", "
else:
alternative_name = ""
alternative_name += "ex " + tags["old_name"]
for key in ["phone"]: address: list[str] = get_address(tags, processed, label_mode)
if key in tags:
texts.append(Label(tags[key], Color("#444444")))
processed.add(key)
if "height" in tags: if name:
texts.append(Label(f"{tags['height']} m")) texts.append(Label(name, self.main_color, self.default_out_color))
processed.add("height") if alternative_name:
texts.append(self.label(f"({alternative_name})"))
if address:
texts.append(self.label(", ".join(address)))
return texts if label_mode == LabelMode.MAIN:
return texts
texts += self.get_text(tags, processed)
if "route_ref" in tags:
texts.append(self.label(tags["route_ref"].replace(";", " ")))
processed.add("route_ref")
if "cladr:code" in tags:
texts.append(self.label(tags["cladr:code"], size=7.0))
processed.add("cladr:code")
if "website" in tags:
link = tags["website"]
if link[:7] == "http://":
link = link[7:]
if link[:8] == "https://":
link = link[8:]
if link[:4] == "www.":
link = link[4:]
if link[-1] == "/":
link = link[:-1]
link = link[:25] + ("..." if len(tags["website"]) > 25 else "")
texts.append(Label(link, Color("#000088"), self.default_out_color))
processed.add("website")
for key in ["phone"]:
if key in tags:
texts.append(
Label(tags[key], Color("#444444"), self.default_out_color)
)
processed.add(key)
if "height" in tags:
texts.append(self.label(f"{tags['height']} m"))
processed.add("height")
return texts