diff --git a/roentgen/constructor.py b/roentgen/constructor.py index 7700d84..5980b21 100644 --- a/roentgen/constructor.py +++ b/roentgen/constructor.py @@ -234,7 +234,7 @@ class Constructor: priority: int icon_set: IconSet icon_set, priority = self.scheme.get_icon( - self.icon_extractor, line.tags, processed, for_="line" + self.icon_extractor, line.tags, processed ) labels = self.scheme.construct_text(line.tags, "all", processed) point: Point = Point( diff --git a/roentgen/direction.py b/roentgen/direction.py index 3bec4ce..411a126 100644 --- a/roentgen/direction.py +++ b/roentgen/direction.py @@ -1,16 +1,16 @@ """ Direction tag support. """ -from typing import Iterator, Optional, Union +from typing import Iterator, Optional import numpy as np from portolan import middle +from roentgen.drawing import PathCommand + __author__ = "Sergey Vartanov" __email__ = "me@enzet.ru" -SVGPath = Union[float, str, np.array] - SHIFT: float = -np.pi / 2 SMALLEST_ANGLE: float = np.pi / 15 DEFAULT_ANGLE: float = np.pi / 30 @@ -90,7 +90,7 @@ class Sector: self.start = np.dot(rotation_matrix(result_angle), vector) self.end = np.dot(rotation_matrix(-result_angle), vector) - def draw(self, center: np.array, radius: float) -> Optional[list[SVGPath]]: + def draw(self, center: np.array, radius: float) -> Optional[PathCommand]: """ Construct SVG path commands for arc element. @@ -139,7 +139,7 @@ class DirectionSet: def __str__(self) -> str: return ", ".join(map(str, self.sectors)) - def draw(self, center: np.array, radius: float) -> Iterator[list[SVGPath]]: + def draw(self, center: np.array, radius: float) -> Iterator[PathCommand]: """ Construct SVG "d" for arc elements. diff --git a/roentgen/drawing.py b/roentgen/drawing.py index 623f8fb..29d6e9c 100644 --- a/roentgen/drawing.py +++ b/roentgen/drawing.py @@ -3,7 +3,7 @@ Drawing utility. """ from dataclasses import dataclass from pathlib import Path -from typing import Optional, List +from typing import Optional, List, Union import cairo import numpy as np @@ -16,6 +16,8 @@ from svgwrite.text import Text __author__ = "Sergey Vartanov" __email__ = "me@enzet.ru" +PathCommand = list[Union[float, str, np.array]] + @dataclass class Style: @@ -75,6 +77,10 @@ class Drawing: """Draw line.""" raise NotImplementedError + def path(self, command: PathCommand, style: Style) -> None: + """Draw path.""" + raise NotImplementedError + def text(self, text: str, point: np.array, color: Color = Color("black")): """Draw text.""" raise NotImplementedError @@ -107,10 +113,14 @@ class SVGDrawing(Drawing): def line(self, points: List[np.array], style: Style) -> None: """Draw line.""" - commands: str = "M " + command: PathCommand = ["M"] for point in points: - commands += f"{point[0]},{point[1]} L " - path = SVGPath(d=commands[:-3]) + command += [point, "L"] + self.path(command[:-1], style) + + def path(self, command: PathCommand, style: Style) -> None: + """Draw path.""" + path = SVGPath(d=command) style.update_svg_element(path) self.image.add(path) @@ -162,6 +172,36 @@ class PNGDrawing(Drawing): self.context.line_to(float(point[0]), float(point[1])) style.draw_png_stroke(self.context) + def _do_path(self, command) -> None: + """Draw path.""" + for index in range(len(command)): + element = command[index] + if isinstance(element, str): + next_element: np.array = command[index + 1] + if element == 5: + self.context.move_to(next_element[0], next_element[1]) + if element == 5: + self.context.line_to(next_element[0], next_element[1]) + if element == 5: + self.context.curve_to( + next_element[0], + next_element[1], + command[index + 2][0], + command[index + 2][1], + command[index + 3][0], + command[index + 3][1], + ) + index += 1 + + def path(self, command: PathCommand, style: Style) -> None: + """Draw path.""" + if style.fill is not None: + self._do_path(command) + style.draw_png_fill(self.context) + if style.stroke is not None: + self._do_path(command) + style.draw_png_stroke(self.context) + def text(self, text: str, point: np.array, color: Color = Color("black")): """Draw text.""" self.context.set_source_rgb( diff --git a/roentgen/moire_manager.py b/roentgen/moire_manager.py index 9cbd0b4..10b8221 100644 --- a/roentgen/moire_manager.py +++ b/roentgen/moire_manager.py @@ -178,6 +178,7 @@ class RoentgenHTML(RoentgenMoire, DefaultHTML): """ def __init__(self) -> None: + super().__init__() self.images: dict = {} def color(self, args: Arguments) -> str: @@ -204,6 +205,7 @@ class RoentgenOSMWiki(RoentgenMoire, DefaultWiki): """ def __init__(self) -> None: + super().__init__() self.images: dict = {} self.extractor: ShapeExtractor = ShapeExtractor( workspace.ICONS_PATH, workspace.ICONS_CONFIG_PATH diff --git a/roentgen/road.py b/roentgen/road.py index 973c39d..b02f021 100644 --- a/roentgen/road.py +++ b/roentgen/road.py @@ -30,6 +30,7 @@ class Lane: destination: Optional[str] = None # Lane destination def set_forward(self, is_forward: bool) -> None: + """If true, lane is forward, otherwise it's backward.""" self.is_forward = is_forward def get_width(self, scale: float): @@ -339,7 +340,7 @@ class Intersection: part_2.update() def draw( - self, drawing: svgwrite.Drawing, scale: float, is_debug: bool = False + self, drawing: svgwrite.Drawing, is_debug: bool = False ) -> None: """ Draw all road parts and intersection. diff --git a/roentgen/scheme.py b/roentgen/scheme.py index 73c060b..b803cef 100644 --- a/roentgen/scheme.py +++ b/roentgen/scheme.py @@ -333,14 +333,12 @@ class Scheme: extractor: ShapeExtractor, tags: dict[str, Any], processed: set[str], - for_: str = "node", ) -> tuple[IconSet, int]: """ Construct icon set. :param extractor: extractor with icon specifications :param tags: OpenStreetMap element tags dictionary - :param for_: target (node, way, area or relation) :param processed: set of already processed tag keys :return (icon set, icon priority) """ diff --git a/roentgen/text.py b/roentgen/text.py index 0d78fc2..d62ac7e 100644 --- a/roentgen/text.py +++ b/roentgen/text.py @@ -31,6 +31,7 @@ def get_address( :param tags: OSM node, way or relation tags :param draw_captions_mode: captions mode ("all", "main", or "no") + :param processed: set of processed tag keys """ address: list[str] = []