Support path drawing.

This commit is contained in:
Sergey Vartanov 2021-08-18 23:00:12 +03:00
parent 737e434260
commit ade9d3b034
7 changed files with 55 additions and 13 deletions

View file

@ -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(

View file

@ -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.

View file

@ -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(

View file

@ -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

View file

@ -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.

View file

@ -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)
"""

View file

@ -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] = []