mirror of
https://github.com/enzet/map-machine.git
synced 2025-07-28 05:48:57 +02:00
Get use of colors from scheme.
This commit is contained in:
parent
5d88d1d85d
commit
c787f48058
4 changed files with 142 additions and 105 deletions
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue