Issue #84: fix layers one more time.

This commit is contained in:
Sergey Vartanov 2021-09-18 22:52:56 +03:00
parent 895790dd0e
commit a0d25b87d4

View file

@ -476,6 +476,59 @@ def get_curve_points(
return [road_end + left, center + left, center + right, road_end + right] return [road_end + left, center + left, center + right, road_end + right]
class Connector:
"""
Two roads connection.
"""
def __init__(
self,
road_1: Road,
index_1: int,
road_2: Road,
index_2: int,
flinger: Flinger,
scale: float,
) -> None:
self.road_1: Road = road_1
self.road_2: Road = road_2
self.index_1: int = index_1
self.index_2: int = index_2
node: OSMNode = road_1.nodes[index_1]
point: np.ndarray = flinger.fling(node.coordinates)
c1: list[np.ndarray] = get_curve_points(
road_1, scale, point, road_1.line.points[index_1]
)
c2: list[np.ndarray] = get_curve_points(
road_2, scale, point, road_2.line.points[index_2]
)
self.curve_1: PathCommands = [c1[0], "C", c1[1], c2[2], c2[3]]
self.curve_2: PathCommands = [c2[0], "C", c2[1], c1[2], c1[3]]
self.layer: float = min(road_1.layer, road_2.layer)
def draw(self, svg: Drawing) -> None:
"""Draw connection fill."""
path = svg.path(
d=["M"] + self.curve_1 + ["L"] + self.curve_2 + ["Z"],
fill=self.road_1.matcher.color.hex,
)
svg.add(path)
def draw_border(self, svg: Drawing) -> None:
"""Draw connection outline."""
for curve in self.curve_1, self.curve_2:
path = svg.path(
d=["M"] + curve,
fill="none",
stroke=self.road_1.matcher.border_color.hex,
)
svg.add(path)
class Roads: class Roads:
""" """
Whole road structure. Whole road structure.
@ -501,6 +554,8 @@ class Roads:
scale: float = flinger.get_scale(self.roads[0].nodes[0].coordinates) scale: float = flinger.get_scale(self.roads[0].nodes[0].coordinates)
layered_roads: dict[float, list[Road]] = {} layered_roads: dict[float, list[Road]] = {}
layered_connectors: dict[float, list[Connector]] = {}
for road in self.roads: for road in self.roads:
if road.layer not in layered_roads: if road.layer not in layered_roads:
layered_roads[road.layer] = [] layered_roads[road.layer] = []
@ -511,49 +566,39 @@ class Roads:
continue continue
road.line.shorten(index) road.line.shorten(index)
for id_ in self.connections:
if len(self.connections[id_]) != 2:
continue
connected: list[tuple[Road, int]] = self.connections[id_]
road_1, index_1 = connected[0]
road_2, index_2 = connected[1]
connector: Connector = Connector(
road_1, index_1, road_2, index_2, flinger, scale
)
if connector.layer not in layered_connectors:
layered_connectors[connector.layer] = []
layered_connectors[connector.layer].append(connector)
for layer in sorted(layered_roads.keys()): for layer in sorted(layered_roads.keys()):
roads = sorted( roads: list[Road] = sorted(
layered_roads[layer], key=lambda x: x.matcher.priority layered_roads[layer], key=lambda x: x.matcher.priority
) )
connectors: list[Connector]
if layer in layered_connectors:
connectors = layered_connectors[layer]
else:
connectors = []
for road in roads: for road in roads:
road.draw(svg, flinger, road.matcher.border_color, 2) road.draw(svg, flinger, road.matcher.border_color, 2)
for connector in connectors:
connector.draw_border(svg)
for road in roads: for road in roads:
road.draw(svg, flinger, road.matcher.color) road.draw(svg, flinger, road.matcher.color)
for id_ in self.connections: for connector in connectors:
if len(self.connections[id_]) != 2: connector.draw(svg)
continue
connected: list[tuple[Road, int]] = self.connections[id_]
road_1, index_1 = connected[0]
if road_1.layer != layer:
continue
road_2, index_2 = connected[1]
node: OSMNode = road_1.nodes[index_1]
point = flinger.fling(node.coordinates)
c1: PathCommands = get_curve_points(
road_1, scale, point, road_1.line.points[index_1]
)
c2: PathCommands = get_curve_points(
road_2, scale, point, road_2.line.points[index_2]
)
curve_1 = [c1[0], "C", c1[1], c2[2], c2[3]]
curve_2 = [c2[0], "C", c2[1], c1[2], c1[3]]
path = svg.path(
d=["M"] + curve_1 + ["L"] + curve_2 + ["Z"],
fill=road_1.matcher.color.hex,
)
svg.add(path)
for curve in curve_1, curve_2:
path = svg.path(
d=["M"] + curve,
fill="none",
stroke=road_1.matcher.border_color.hex,
)
svg.add(path)
for road in roads: for road in roads:
road.draw_lanes(svg, flinger, road.matcher.border_color) road.draw_lanes(svg, flinger, road.matcher.border_color)