mirror of
https://github.com/enzet/map-machine.git
synced 2025-05-21 13:06:25 +02:00
Support path drawing.
This commit is contained in:
parent
737e434260
commit
ade9d3b034
7 changed files with 55 additions and 13 deletions
|
@ -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(
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
"""
|
||||
|
|
|
@ -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] = []
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue