Skip to content

Commit 0f7080c

Browse files
committed
Change priority computing.
Now we check levels first, than layers and only after that figure priority.
1 parent 259707a commit 0f7080c

File tree

8 files changed

+94
-32
lines changed

8 files changed

+94
-32
lines changed

doc/author.svg

Lines changed: 1 addition & 1 deletion
Loading

doc/colors.svg

Lines changed: 1 addition & 1 deletion
Loading

doc/time.svg

Lines changed: 1 addition & 1 deletion
Loading

doc/trees.svg

Lines changed: 1 addition & 1 deletion
Loading

map_machine/doc/preview.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ def main(id_: str | None) -> None:
152152
SCHEME,
153153
label_mode=LabelMode.NO,
154154
zoom_level=15.7,
155-
ignore_level_matching=True,
156155
),
157156
)
158157

@@ -169,9 +168,7 @@ def main(id_: str | None) -> None:
169168
draw_around_point(
170169
np.array((55.751, 37.628)),
171170
"trees",
172-
MapConfiguration(
173-
SCHEME, label_mode=LabelMode(LabelMode.ALL), zoom_level=18.1
174-
),
171+
MapConfiguration(SCHEME, zoom_level=18.1, level="overground"),
175172
get=BoundingBox(37.624, 55.749, 37.633, 55.753),
176173
)
177174

map_machine/feature/road.py

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,16 @@ def __init__(
458458
if "layer" in tags:
459459
self.layer = float(tags["layer"])
460460

461+
self.level: float = 0.0
462+
if "level" in tags:
463+
try:
464+
levels = [
465+
float(x) for x in tags["level"].replace(",", ".").split(";")
466+
]
467+
self.level = min(levels)
468+
except ValueError:
469+
pass
470+
461471
self.placement_offset: float = 0.0
462472
self.is_transition: bool = False
463473

@@ -710,6 +720,12 @@ def __init__(
710720
self.max_layer: float = max(
711721
connection[0].layer for connection in connections
712722
)
723+
self.min_level: float = min(
724+
connection[0].level for connection in connections
725+
)
726+
self.max_level: float = max(
727+
connection[0].level for connection in connections
728+
)
713729
self.scale: float = self.road_1.scale
714730
self.flinger: Flinger = flinger
715731

@@ -888,10 +904,16 @@ def append(self, road: Road) -> None:
888904

889905
def draw_simple(self, svg: Drawing) -> None:
890906
"""Draw roads as styled figures, usually lines with outlines."""
891-
for road in sorted(self.roads, key=lambda x: x.matcher.priority):
907+
for road in sorted(
908+
self.roads,
909+
key=lambda x: (x.level, x.layer, x.matcher.priority),
910+
):
892911
road.draw(svg, is_border=True)
893912

894-
for road in sorted(self.roads, key=lambda x: x.matcher.priority):
913+
for road in sorted(
914+
self.roads,
915+
key=lambda x: (x.level, x.layer, x.matcher.priority),
916+
):
895917
road.draw(svg, is_border=False)
896918

897919
def draw_lanes(
@@ -901,14 +923,17 @@ def draw_lanes(
901923
if not self.roads:
902924
return
903925

904-
layered_roads: dict[float, list[Road]] = {}
905-
layered_connectors: dict[float, list[Connector]] = {}
926+
level_layer = tuple[float, float]
927+
928+
layered_roads: dict[level_layer, list[Road]] = {}
929+
layered_connectors: dict[level_layer, list[Connector]] = {}
906930

907931
for road in self.roads:
932+
key: level_layer = (road.level, road.layer)
908933
if not road.is_transition:
909-
if road.layer not in layered_roads:
910-
layered_roads[road.layer] = []
911-
layered_roads[road.layer].append(road)
934+
if key not in layered_roads:
935+
layered_roads[key] = []
936+
layered_roads[key].append(road)
912937
else:
913938
connections = [
914939
[
@@ -922,9 +947,9 @@ def draw_lanes(
922947
connector: Connector = ComplexConnector(
923948
[connections[0][0], connections[1][0]], flinger
924949
)
925-
if road.layer not in layered_connectors:
926-
layered_connectors[road.layer] = []
927-
layered_connectors[road.layer].append(connector)
950+
if key not in layered_connectors:
951+
layered_connectors[key] = []
952+
layered_connectors[key].append(connector)
928953

929954
for connected in self.nodes.values():
930955
if len(connected) <= 1:
@@ -948,27 +973,41 @@ def draw_lanes(
948973
# `SimpleIntersection(connected, flinger, scale)` here.
949974
continue
950975

951-
if connector.min_layer not in layered_connectors:
952-
layered_connectors[connector.min_layer] = []
953-
layered_connectors[connector.min_layer].append(connector)
976+
min_key: level_layer = (
977+
connector.min_level,
978+
connector.min_layer,
979+
)
980+
if min_key not in layered_connectors:
981+
layered_connectors[min_key] = []
982+
layered_connectors[min_key].append(connector)
954983

955-
if connector.max_layer not in layered_connectors:
956-
layered_connectors[connector.max_layer] = []
957-
layered_connectors[connector.max_layer].append(connector)
984+
max_key: level_layer = (
985+
connector.max_level,
986+
connector.max_layer,
987+
)
988+
if max_key not in layered_connectors:
989+
layered_connectors[max_key] = []
990+
layered_connectors[max_key].append(connector)
958991

959-
for layer in sorted(layered_roads.keys()):
992+
for level_layer_key in sorted(layered_roads.keys()):
960993
roads: list[Road] = sorted(
961-
layered_roads[layer], key=lambda x: x.matcher.priority
994+
layered_roads[level_layer_key],
995+
key=lambda x: x.matcher.priority,
996+
)
997+
connectors: list[Connector] | None = layered_connectors.get(
998+
level_layer_key
962999
)
963-
connectors: list[Connector] | None = layered_connectors.get(layer)
9641000

9651001
# Draw borders.
9661002

9671003
for road in roads:
9681004
road.draw(svg, is_border=True)
9691005
if connectors:
9701006
for connector in connectors:
971-
if connector.min_layer == layer:
1007+
if (
1008+
connector.min_level,
1009+
connector.min_layer,
1010+
) == level_layer_key:
9721011
connector.draw_border(svg)
9731012

9741013
# Draw inner parts.
@@ -977,7 +1016,10 @@ def draw_lanes(
9771016
road.draw(svg, is_border=False)
9781017
if connectors:
9791018
for connector in connectors:
980-
if connector.max_layer == layer:
1019+
if (
1020+
connector.max_level,
1021+
connector.max_layer,
1022+
) == level_layer_key:
9811023
connector.draw(svg)
9821024

9831025
# Draw lane separators.

map_machine/figure.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,26 @@ def get_path(
118118

119119
return path
120120

121+
def get_level(self) -> float:
122+
"""Get figure level value or 0 if it is not specified.
123+
124+
For multi-value levels (e.g. "0;1"), return the minimum value.
125+
"""
126+
if "level" in self.tags:
127+
try:
128+
levels: list[float] = [
129+
float(x)
130+
for x in self.tags["level"].replace(",", ".").split(";")
131+
]
132+
return min(levels)
133+
except ValueError:
134+
return 0.0
135+
return 0.0
136+
121137
def get_layer(self) -> float:
122138
"""Get figure layer value or 0 if it is not specified.
123139
124-
TODO: support values separated by "," or ";".
140+
TODO(enzet): support values separated by "," or ";".
125141
"""
126142
try:
127143
if "layer" in self.tags:
@@ -131,10 +147,17 @@ def get_layer(self) -> float:
131147
return 0.0
132148

133149
def __lt__(self, other: StyledFigure) -> bool:
134-
"""Compare figures based on priority and layer."""
150+
"""Compare figures based on level, layer, and priority."""
151+
152+
# First, check level.
153+
if self.get_level() != other.get_level():
154+
return self.get_level() < other.get_level()
155+
156+
# Then, check layer.
135157
if self.get_layer() != other.get_layer():
136158
return self.get_layer() < other.get_layer()
137159

160+
# Then, check priority.
138161
return self.line_style.priority < other.line_style.priority
139162

140163

map_machine/scheme.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ def from_structure(
302302
else:
303303
way_matcher.style[key] = value
304304

305-
priority = structure.get("priority", 0.0)
305+
priority: float = structure.get("priority", 0.0)
306306
way_matcher.priority = scheme.get_value(priority)
307307
way_matcher.parallel_offset = structure.get("parallel_offset", 0.0)
308308

0 commit comments

Comments
 (0)