mirror of
https://github.com/enzet/map-machine.git
synced 2025-05-22 13:36:26 +02:00
Refactor points and figures.
This commit is contained in:
parent
557e0d1992
commit
51f40b989e
2 changed files with 68 additions and 60 deletions
|
@ -51,14 +51,16 @@ def make_counter_clockwise(polygon: List[OSMNode]) -> List[OSMNode]:
|
||||||
return list(reversed(polygon))
|
return list(reversed(polygon))
|
||||||
|
|
||||||
|
|
||||||
class Node(Tagged):
|
class Point(Tagged):
|
||||||
"""
|
"""
|
||||||
Node in Röntgen terms.
|
Object on the map with no dimensional attributes.
|
||||||
"""
|
"""
|
||||||
def __init__(
|
def __init__(
|
||||||
self, icon_set: IconSet, tags: Dict[str, str],
|
self, icon_set: IconSet, tags: Dict[str, str], point: np.array,
|
||||||
point: np.array, coordinates: np.array,
|
coordinates: np.array, priority: float = 0,
|
||||||
priority: float = 0, is_for_node: bool = True):
|
is_for_node: bool = True):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
assert point is not None
|
assert point is not None
|
||||||
|
|
||||||
self.icon_set: IconSet = icon_set
|
self.icon_set: IconSet = icon_set
|
||||||
|
@ -75,18 +77,21 @@ class Node(Tagged):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class Way:
|
class Figure(Tagged):
|
||||||
"""
|
"""
|
||||||
Way in Röntgen terms.
|
Some figure on the map: way or area.
|
||||||
"""
|
"""
|
||||||
def __init__(
|
def __init__(
|
||||||
self, inners, outers, style: Dict[str, Any],
|
self, tags: Dict[str, str], inners, outers, style: Dict[str, Any],
|
||||||
layer: float = 0.0, levels=None):
|
layer: float = 0.0):
|
||||||
|
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.tags: Dict[str, str] = tags
|
||||||
self.inners = []
|
self.inners = []
|
||||||
self.outers = []
|
self.outers = []
|
||||||
self.style: Dict[str, Any] = style
|
self.style: Dict[str, Any] = style
|
||||||
self.layer = layer
|
self.layer = layer
|
||||||
self.levels = levels
|
|
||||||
|
|
||||||
for inner_nodes in inners:
|
for inner_nodes in inners:
|
||||||
self.inners.append(make_clockwise(inner_nodes))
|
self.inners.append(make_clockwise(inner_nodes))
|
||||||
|
@ -110,6 +115,20 @@ class Way:
|
||||||
|
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
class Building(Figure):
|
||||||
|
def __init__(
|
||||||
|
self, tags: Dict[str, str], inners, outers, style: Dict[str, Any],
|
||||||
|
layer: float):
|
||||||
|
super().__init__(tags, inners, outers, style, layer)
|
||||||
|
|
||||||
|
def get_levels(self):
|
||||||
|
try:
|
||||||
|
return float(self.get_tag("building:levels"))
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
class TextStruct:
|
class TextStruct:
|
||||||
def __init__(
|
def __init__(
|
||||||
self, text: str, fill: Color = Color("#444444"), size: float = 10):
|
self, text: str, fill: Color = Color("#444444"), size: float = 10):
|
||||||
|
@ -219,9 +238,9 @@ class Constructor:
|
||||||
self.flinger: Flinger = flinger
|
self.flinger: Flinger = flinger
|
||||||
self.scheme: Scheme = scheme
|
self.scheme: Scheme = scheme
|
||||||
|
|
||||||
self.nodes: List[Node] = []
|
self.nodes: List[Point] = []
|
||||||
self.ways: List[Way] = []
|
self.figures: List[Figure] = []
|
||||||
self.buildings: List[Way] = []
|
self.buildings: List[Figure] = []
|
||||||
|
|
||||||
def construct_ways(self):
|
def construct_ways(self):
|
||||||
"""
|
"""
|
||||||
|
@ -263,8 +282,6 @@ class Constructor:
|
||||||
|
|
||||||
# layer = 100 * level + 0.01 * layer
|
# layer = 100 * level + 0.01 * layer
|
||||||
|
|
||||||
nodes = None
|
|
||||||
|
|
||||||
center_point, center_coordinates = None, None
|
center_point, center_coordinates = None, None
|
||||||
|
|
||||||
if way:
|
if way:
|
||||||
|
@ -276,8 +293,9 @@ class Constructor:
|
||||||
if not way:
|
if not way:
|
||||||
return
|
return
|
||||||
user_color = get_user_color(way.user, self.seed)
|
user_color = get_user_color(way.user, self.seed)
|
||||||
self.ways.append(
|
self.figures.append(
|
||||||
Way(inners, outers,
|
Figure(
|
||||||
|
way.tags, inners, outers,
|
||||||
{"fill": "none", "stroke": user_color.hex,
|
{"fill": "none", "stroke": user_color.hex,
|
||||||
"stroke-width": 1}))
|
"stroke-width": 1}))
|
||||||
return
|
return
|
||||||
|
@ -286,8 +304,9 @@ class Constructor:
|
||||||
if not way:
|
if not way:
|
||||||
return
|
return
|
||||||
time_color = get_time_color(way.timestamp, self.map_.time)
|
time_color = get_time_color(way.timestamp, self.map_.time)
|
||||||
self.ways.append(
|
self.figures.append(
|
||||||
Way(inners, outers,
|
Figure(
|
||||||
|
way.tags, inners, outers,
|
||||||
{"fill": "none", "stroke": time_color.hex,
|
{"fill": "none", "stroke": time_color.hex,
|
||||||
"stroke-width": 1}))
|
"stroke-width": 1}))
|
||||||
return
|
return
|
||||||
|
@ -296,16 +315,6 @@ class Constructor:
|
||||||
return
|
return
|
||||||
|
|
||||||
appended: bool = False
|
appended: bool = False
|
||||||
kind: str = "way"
|
|
||||||
levels = None
|
|
||||||
|
|
||||||
if "building" in tags: # or "building:part" in tags:
|
|
||||||
kind = "building"
|
|
||||||
if "building:levels" in tags:
|
|
||||||
try:
|
|
||||||
levels = float(tags["building:levels"])
|
|
||||||
except ValueError:
|
|
||||||
levels = None
|
|
||||||
|
|
||||||
for element in self.scheme.ways: # type: Dict[str, Any]
|
for element in self.scheme.ways: # type: Dict[str, Any]
|
||||||
matched: bool = True
|
matched: bool = True
|
||||||
|
@ -329,7 +338,9 @@ class Constructor:
|
||||||
if "priority" in element:
|
if "priority" in element:
|
||||||
layer = element["priority"]
|
layer = element["priority"]
|
||||||
for key in element: # type: str
|
for key in element: # type: str
|
||||||
if key not in ["tags", "no_tags", "priority", "level", "icon", "r", "r2"]:
|
if key not in [
|
||||||
|
"tags", "no_tags", "priority", "level", "icon",
|
||||||
|
"r", "r2"]:
|
||||||
value = element[key]
|
value = element[key]
|
||||||
if isinstance(value, str) and value.endswith("_color"):
|
if isinstance(value, str) and value.endswith("_color"):
|
||||||
value = self.scheme.get_color(value)
|
value = self.scheme.get_color(value)
|
||||||
|
@ -343,15 +354,16 @@ class Constructor:
|
||||||
style["stroke-width"] = \
|
style["stroke-width"] = \
|
||||||
element["r2"] * \
|
element["r2"] * \
|
||||||
self.flinger.get_scale(center_coordinates) + 2
|
self.flinger.get_scale(center_coordinates) + 2
|
||||||
w = Way(inners, outers, style, layer, levels)
|
if "building" in tags:
|
||||||
if kind == "way":
|
self.buildings.append(
|
||||||
self.ways.append(w)
|
Building(tags, inners, outers, style, layer))
|
||||||
elif kind == "building":
|
else:
|
||||||
self.buildings.append(w)
|
self.figures.append(
|
||||||
|
Figure(tags, inners, outers, style, layer))
|
||||||
if center_point is not None and \
|
if center_point is not None and \
|
||||||
(way.is_cycle() and "area" in tags and tags["area"]):
|
(way.is_cycle() and "area" in tags and tags["area"]):
|
||||||
icon_set: IconSet = self.scheme.get_icon(tags)
|
icon_set: IconSet = self.scheme.get_icon(tags)
|
||||||
self.nodes.append(Node(
|
self.nodes.append(Point(
|
||||||
icon_set, tags, center_point, center_coordinates,
|
icon_set, tags, center_point, center_coordinates,
|
||||||
is_for_node=False))
|
is_for_node=False))
|
||||||
appended = True
|
appended = True
|
||||||
|
@ -361,12 +373,12 @@ class Constructor:
|
||||||
style: Dict[str, Any] = {
|
style: Dict[str, Any] = {
|
||||||
"fill": "none", "stroke": Color("red").hex,
|
"fill": "none", "stroke": Color("red").hex,
|
||||||
"stroke-width": 1}
|
"stroke-width": 1}
|
||||||
self.ways.append(Way(
|
self.figures.append(Figure(
|
||||||
kind, inners, outers, style, layer, levels))
|
tags, inners, outers, style, layer))
|
||||||
if center_point is not None and (way.is_cycle() or
|
if center_point is not None and (way.is_cycle() or
|
||||||
"area" in tags and tags["area"]):
|
"area" in tags and tags["area"]):
|
||||||
icon_set: IconSet = self.scheme.get_icon(tags)
|
icon_set: IconSet = self.scheme.get_icon(tags)
|
||||||
self.nodes.append(Node(
|
self.nodes.append(Point(
|
||||||
icon_set, tags, center_point, center_coordinates,
|
icon_set, tags, center_point, center_coordinates,
|
||||||
is_for_node=False))
|
is_for_node=False))
|
||||||
|
|
||||||
|
@ -428,6 +440,6 @@ class Constructor:
|
||||||
if self.mode == "time":
|
if self.mode == "time":
|
||||||
icon_set.color = get_time_color(node.timestamp)
|
icon_set.color = get_time_color(node.timestamp)
|
||||||
|
|
||||||
self.nodes.append(Node(icon_set, tags, flung, node.position))
|
self.nodes.append(Point(icon_set, tags, flung, node.position))
|
||||||
|
|
||||||
ui.progress_bar(-1, len(self.map_.node_map), text="Constructing nodes")
|
ui.progress_bar(-1, len(self.map_.node_map), text="Constructing nodes")
|
||||||
|
|
|
@ -17,7 +17,7 @@ from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
from roentgen import ui
|
from roentgen import ui
|
||||||
from roentgen.address import get_address
|
from roentgen.address import get_address
|
||||||
from roentgen.constructor import Constructor, Node, Way, TextStruct
|
from roentgen.constructor import Constructor, Point, Figure, TextStruct, Building
|
||||||
from roentgen.flinger import Flinger
|
from roentgen.flinger import Flinger
|
||||||
from roentgen.grid import draw_grid
|
from roentgen.grid import draw_grid
|
||||||
from roentgen.extract_icon import Icon, IconExtractor
|
from roentgen.extract_icon import Icon, IconExtractor
|
||||||
|
@ -61,7 +61,7 @@ class Painter:
|
||||||
self.icon_extractor = icon_extractor
|
self.icon_extractor = icon_extractor
|
||||||
self.scheme: Scheme = scheme
|
self.scheme: Scheme = scheme
|
||||||
|
|
||||||
def draw_shapes(self, node: Node, points: List[List[float]]):
|
def draw_shapes(self, node: Point, points: List[List[float]]):
|
||||||
"""
|
"""
|
||||||
Draw shapes for one node.
|
Draw shapes for one node.
|
||||||
"""
|
"""
|
||||||
|
@ -93,7 +93,7 @@ class Painter:
|
||||||
node.icon_set.color, tags=node.tags)
|
node.icon_set.color, tags=node.tags)
|
||||||
left += 16
|
left += 16
|
||||||
|
|
||||||
def draw_texts(self, node: Node):
|
def draw_texts(self, node: Point):
|
||||||
"""
|
"""
|
||||||
Draw all labels.
|
Draw all labels.
|
||||||
"""
|
"""
|
||||||
|
@ -229,7 +229,7 @@ class Painter:
|
||||||
"""
|
"""
|
||||||
Draw area between way and way shifted by the vector.
|
Draw area between way and way shifted by the vector.
|
||||||
"""
|
"""
|
||||||
for way in ways:
|
for way in ways: # type: Building
|
||||||
if stage == 1:
|
if stage == 1:
|
||||||
shift_1 = [0, 0]
|
shift_1 = [0, 0]
|
||||||
shift_2 = [0, -1]
|
shift_2 = [0, -1]
|
||||||
|
@ -238,10 +238,7 @@ class Painter:
|
||||||
shift_2 = [0, -2]
|
shift_2 = [0, -2]
|
||||||
else:
|
else:
|
||||||
shift_1 = [0, -2]
|
shift_1 = [0, -2]
|
||||||
if way.levels:
|
shift_2 = [0, min(-3, -1 * way.get_levels())]
|
||||||
shift_2 = [0, min(-3, -1 * way.levels)]
|
|
||||||
else:
|
|
||||||
shift_2 = [0, -3]
|
|
||||||
|
|
||||||
for nodes in way.inners + way.outers:
|
for nodes in way.inners + way.outers:
|
||||||
for i in range(len(nodes) - 1):
|
for i in range(len(nodes) - 1):
|
||||||
|
@ -252,15 +249,15 @@ class Painter:
|
||||||
d=("M", np.add(flung_1, shift_1), "L",
|
d=("M", np.add(flung_1, shift_1), "L",
|
||||||
np.add(flung_2, shift_1), np.add(flung_2, shift_2),
|
np.add(flung_2, shift_1), np.add(flung_2, shift_2),
|
||||||
np.add(flung_1, shift_2), "Z"),
|
np.add(flung_1, shift_2), "Z"),
|
||||||
fill=color.hex, stroke=color.hex, stroke_width=1))
|
fill=color.hex, stroke="#CCCCCC", stroke_width=1))
|
||||||
|
|
||||||
def draw(self, constructor: Constructor, points):
|
def draw(self, constructor: Constructor, points):
|
||||||
"""
|
"""
|
||||||
Draw map.
|
Draw map.
|
||||||
"""
|
"""
|
||||||
ways = sorted(constructor.ways, key=lambda x: x.layer)
|
ways = sorted(constructor.figures, key=lambda x: x.layer)
|
||||||
ways_length: int = len(ways)
|
ways_length: int = len(ways)
|
||||||
for index, way in enumerate(ways): # type: Way
|
for index, way in enumerate(ways): # type: Figure
|
||||||
ui.progress_bar(index, ways_length, step=10, text="Drawing ways")
|
ui.progress_bar(index, ways_length, step=10, text="Drawing ways")
|
||||||
path: str = way.get_path(self.flinger)
|
path: str = way.get_path(self.flinger)
|
||||||
if path:
|
if path:
|
||||||
|
@ -273,10 +270,9 @@ class Painter:
|
||||||
|
|
||||||
building_shade = Group(opacity=0.1)
|
building_shade = Group(opacity=0.1)
|
||||||
|
|
||||||
for way in constructor.buildings: # type: Way
|
for way in constructor.buildings: # type: Building
|
||||||
shift = [-5, 5]
|
shift = [-5, 5]
|
||||||
if way.levels:
|
shift = [-5 * way.get_levels(), 5 * way.get_levels()]
|
||||||
shift = [-5 * way.levels, 5 * way.levels]
|
|
||||||
for nodes11 in way.inners + way.outers:
|
for nodes11 in way.inners + way.outers:
|
||||||
for i in range(len(nodes11) - 1):
|
for i in range(len(nodes11) - 1):
|
||||||
flung_1 = self.flinger.fling(nodes11[i].position)
|
flung_1 = self.flinger.fling(nodes11[i].position)
|
||||||
|
@ -298,10 +294,10 @@ class Painter:
|
||||||
|
|
||||||
building_paths: List[(str, Dict)] = []
|
building_paths: List[(str, Dict)] = []
|
||||||
|
|
||||||
for way in constructor.buildings: # type: Way
|
for way in constructor.buildings: # type: Building
|
||||||
shift = [0, -3]
|
shift = [0, -3]
|
||||||
if way.levels:
|
shift = np.array([
|
||||||
shift = np.array([0 * way.levels, min(-3, -1 * way.levels)])
|
0 * way.get_levels(), min(-3, -1 * way.get_levels())])
|
||||||
path: str = way.get_path(self.flinger, shift)
|
path: str = way.get_path(self.flinger, shift)
|
||||||
if path:
|
if path:
|
||||||
building_paths.append((path, way.style))
|
building_paths.append((path, way.style))
|
||||||
|
@ -339,7 +335,7 @@ class Painter:
|
||||||
|
|
||||||
# Directions
|
# Directions
|
||||||
|
|
||||||
for node in constructor.nodes: # type: Node
|
for node in constructor.nodes: # type: Point
|
||||||
|
|
||||||
angle = None
|
angle = None
|
||||||
is_revert_gradient: bool = False
|
is_revert_gradient: bool = False
|
||||||
|
@ -396,7 +392,7 @@ class Painter:
|
||||||
# All other nodes
|
# All other nodes
|
||||||
|
|
||||||
nodes = sorted(constructor.nodes, key=lambda x: x.layer)
|
nodes = sorted(constructor.nodes, key=lambda x: x.layer)
|
||||||
for index, node in enumerate(nodes): # type: int, Node
|
for index, node in enumerate(nodes): # type: int, Point
|
||||||
if node.get_tag("natural") == "tree" and \
|
if node.get_tag("natural") == "tree" and \
|
||||||
("diameter_crown" in node.tags or
|
("diameter_crown" in node.tags or
|
||||||
"circumference" in node.tags):
|
"circumference" in node.tags):
|
||||||
|
@ -408,7 +404,7 @@ class Painter:
|
||||||
if self.draw_captions == "no":
|
if self.draw_captions == "no":
|
||||||
return
|
return
|
||||||
|
|
||||||
for node in nodes: # type: Node
|
for node in nodes: # type: Point
|
||||||
if self.mode not in [CREATION_TIME_MODE, AUTHOR_MODE]:
|
if self.mode not in [CREATION_TIME_MODE, AUTHOR_MODE]:
|
||||||
self.draw_texts(node)
|
self.draw_texts(node)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue