From 01a1700ba221fe429e759ea89a2d02c7d3c0f0b9 Mon Sep 17 00:00:00 2001 From: Sergey Vartanov Date: Sun, 10 Oct 2021 17:32:04 +0300 Subject: [PATCH] Fix road connection colors. --- map_machine/icons/icons.svg | 542 +++++++++++++++++++++++++++--------- map_machine/road.py | 56 ++-- tests/test_elements.py | 3 + 3 files changed, 452 insertions(+), 149 deletions(-) diff --git a/map_machine/icons/icons.svg b/map_machine/icons/icons.svg index a0337d3..1c10bea 100644 --- a/map_machine/icons/icons.svg +++ b/map_machine/icons/icons.svg @@ -1,19 +1,18 @@ + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + sodipodi:docname="icons.svg" + inkscape:version="0.91 r13725" + version="1.1" + id="svg2987" + height="600px" + width="800px"> + inkscape:label="#rect9680" + inkscape:connector-curvature="0" /> + y="391" /> + style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;enable-background:accumulate;opacity:0.94" /> @@ -4133,7 +4133,7 @@ rx="0.5" ry="0.5" y="-184.5" - x="394.5" + x="393.5" height="1" width="2.5" id="rect4601" @@ -5278,21 +5278,21 @@ ry="0" rx="0" y="455" - x="371" + x="19" height="3" width="10" id="rect9339" style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> @@ -10143,26 +10143,26 @@ id="path6085" sodipodi:type="arc" sodipodi:cx="184" - sodipodi:cy="390" + sodipodi:cy="389" sodipodi:rx="3" sodipodi:ry="3" sodipodi:start="3.1415927" sodipodi:end="0" sodipodi:open="true" - d="m 181,390 a 3,3 0 0 1 3,-3 3,3 0 0 1 3,3" + d="m 181,389 a 3,3 0 0 1 3,-3 3,3 0 0 1 3,3" sodipodi:arc-type="arc" /> + inkscape:label="#rect22867" + inkscape:connector-curvature="0" /> + y="391" /> - + d="m 55.49023,466 a 0.50005,0.50005 0 0 0 -0.17578,0.0352 l -5,2 a 0.50050477,0.50050477 0 1 0 0.3711,0.92968 L 51,468.83984 51,474 l -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 l 0,4 c 0,0.277 0.223,0.5 0.5,0.5 l 10,0 c 0.277,0 0.5,-0.223 0.5,-0.5 l 0,-4 c 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 0,-3 1,0 0,1.5 a 0.50005,0.50005 0 0 0 0.5,0.5 l 1,0 a 0.50005,0.50005 0 1 0 0,-1 l -0.5,0 0,-1.5 A 0.50005,0.50005 0 0 0 61.5,470 l -1.5,0 0,-1.16016 0.31445,0.125 a 0.50050477,0.50050477 0 1 0 0.3711,-0.92968 l -5,-2 A 0.50005,0.50005 0 0 0 55.49023,466 Z m 0.01,1.03906 3.5,1.40039 0,1.56055 -2,0 0,-0.5 -3,0 0,0.5 -2,0 0,-1.56055 3.5,-1.40039 z M 52,471 l 2,0 0,0.5 0,2.5 -2,0 0,-3 z m 5,0 2,0 0,3 -4,0 0,-2.5 2,0 0,-0.5 z" + id="rect7630" + inkscape:connector-curvature="0" /> @@ -23015,16 +23007,16 @@ sodipodi:nodetypes="cssc" inkscape:connector-curvature="0" id="path7678" - d="m 455.5,454.5 3,0 c 0.5,0 1,0.5 1,1 l 0,1.5" + d="m 103.5,454.5 3,0 c 0.5,0 1,0.5 1,1 l 0,1.5" style="opacity:0.2;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + d="m 87.5,466 c -1.08333,0 -1.98566,0.27863 -2.60352,0.89648 C 84.27863,467.51434 84,468.41667 84,469.5 l 0,3 c 0,0.52778 -0.39063,1.0625 -0.89062,1.6875 C 82.60938,474.8125 82,475.52778 82,476.5 a 0.50005,0.50005 0 1 0 1,0 c 0,-0.52778 0.39063,-1.0625 0.89062,-1.6875 C 84.39062,474.1875 85,473.47222 85,472.5 l 0,-3 c 0,-0.91667 0.22137,-1.51434 0.60352,-1.89648 C 85.98566,467.22137 86.58333,467 87.5,467 a 0.50005,0.50005 0 1 0 0,-1 z m -1.5,3 0,1 0.5,0 0,2.5 0.5,0.5 0,5 -1,0 0,1 4,0 0,-1 -1,0 0,-5 0.5,-0.5 0,-0.5 2,0 c 0.0833,0 0.22505,0.0571 0.33398,0.16602 C 91.94292,472.27495 92,472.41667 92,472.5 l 0,0.5 -0.5,0 0,1 0.91992,0 a 0.50005,0.50005 0 0 0 0.16211,0 l 0.91797,0 0,-1 -0.5,0 0,-0.5 c 0,-0.41667 -0.19292,-0.77495 -0.45898,-1.04102 C 92.27495,471.19292 91.91667,471 91.5,471 l -2,0 0,-1 0.5,0 0,-1 -4,0 z" + id="path7745" + inkscape:connector-curvature="0" /> + d="m 102.5,466 c -0.86111,0 -1.53681,0.31215 -1.94727,0.80469 C 100.14228,467.29723 100,467.91667 100,468.5 l 0,2 c 0,0.83333 -0.35352,1.14648 -0.85352,1.64648 -0.5,0.5 -1.14648,1.18685 -1.14648,2.35352 a 0.50005,0.50005 0 1 0 1,0 c 0,-0.83333 0.35352,-1.14648 0.85352,-1.64648 0.5,-0.5 1.14648,-1.18685 1.14648,-2.35352 l 0,-2 c 0,-0.41667 0.10772,-0.79723 0.32227,-1.05469 C 101.53681,467.18785 101.86111,467 102.5,467 a 0.50005,0.50005 0 1 0 0,-1 z m 0.5,2 c -0.554,0 -1,0.446 -1,1 l 0,9 -1,0 0,1 4,0 0,-1 -1,0 0,-7 2.5,0 c 0.0833,0 0.22505,0.0571 0.33398,0.16602 C 106.94292,471.27495 107,471.41667 107,471.5 l 0,1.5 -1,0 0,1 3,0 0,-1 -1,0 0,-1.5 c 0,-0.41667 -0.19292,-0.77495 -0.45898,-1.04102 C 107.27495,470.19292 106.91667,470 106.5,470 l -2.5,0 0,-1 c 0,-0.554 -0.446,-1 -1,-1 z" + id="path7759" + inkscape:connector-curvature="0" /> + d="m 132.5,465 c -0.86111,0 -1.53681,0.31215 -1.94727,0.80469 C 130.14228,466.29723 130,466.91667 130,467.5 l 0,3 c 0,0.91667 -0.19727,1.27734 -0.44727,1.77734 -0.25,0.5 -0.55273,1.13933 -0.55273,2.22266 a 0.50005,0.50005 0 1 0 1,0 c 0,-0.91667 0.19727,-1.27734 0.44727,-1.77734 0.25,-0.5 0.55273,-1.13933 0.55273,-2.22266 l 0,-3 c 0,-0.41667 0.10772,-0.79723 0.32227,-1.05469 C 131.53681,466.18785 131.86111,466 132.5,466 a 0.50005,0.50005 0 1 0 0,-1 z m 0.4375,2 C 132.41812,467 132,467.446 132,468 l 0,10 -1,0 0,1 4,0 0,-1 -1,0 0,-9 1.5,0 c 0.0833,0 0.22505,0.0571 0.33398,0.16602 C 135.94292,469.27495 136,469.41667 136,469.5 l 0,0.5 1,0 0,-0.5 c 0,-0.41667 -0.19292,-0.77495 -0.45898,-1.04102 C 136.27495,468.19292 135.91667,468 135.5,468 l -1.5,0 c 0,-0.554 -0.41812,-1 -0.9375,-1 l -0.125,0 z m 6.5625,3 c -1.37479,0 -2.5,1.12521 -2.5,2.5 l 0,0.5 -0.5,0 a 0.50005,0.50005 0 1 0 0,1 l 0.0898,0 0.91993,4.59766 A 0.50005,0.50005 0 0 0 138,479 l 3,0 a 0.50005,0.50005 0 0 0 0.49023,-0.40234 L 142.41016,474 142.5,474 a 0.50005,0.50005 0 1 0 0,-1 l -0.5,0 0,-0.5 c 0,-1.37479 -1.12521,-2.5 -2.5,-2.5 z m 0,1 c 0.83435,0 1.5,0.66565 1.5,1.5 l 0,0.5 -3,0 0,-0.5 c 0,-0.83435 0.66565,-1.5 1.5,-1.5 z m -1.89062,3 3.78124,0 -0.80078,4 -2.17968,0 -0.80078,-4 z" + id="path7769" + inkscape:connector-curvature="0" /> + d="m 117.5,465 c -0.86111,0 -1.53681,0.31215 -1.94727,0.80469 C 115.14228,466.29723 115,466.91667 115,467.5 l 0,3 c 0,0.83333 -0.35352,1.14648 -0.85352,1.64648 -0.5,0.5 -1.14648,1.18685 -1.14648,2.35352 a 0.50005,0.50005 0 1 0 1,0 c 0,-0.83333 0.35352,-1.14648 0.85352,-1.64648 0.5,-0.5 1.14648,-1.18685 1.14648,-2.35352 l 0,-3 c 0,-0.41667 0.10772,-0.79723 0.32227,-1.05469 C 116.53681,466.18785 116.86111,466 117.5,466 a 0.50005,0.50005 0 1 0 0,-1 z m 0.4375,2 C 117.41812,467 117,467.446 117,468 l 0,10 -1,0 0,1 4,0 0,-1 -1,0 0,-9 3.5,0 c 0.0833,0 0.22505,0.0571 0.33398,0.16602 C 122.94292,469.27495 123,469.41667 123,469.5 l 0,0.5 -1,0 0,1 3,0 0,-1 -1,0 0,-0.5 c 0,-0.41667 -0.19292,-0.77495 -0.45898,-1.04102 C 123.27495,468.19292 122.91667,468 122.5,468 l -3.5,0 c 0,-0.554 -0.41812,-1 -0.9375,-1 l -0.125,0 z m 3.5625,5 a 0.50005,0.50005 0 0 0 -0.49414,0.58203 l 1,6 A 0.50005,0.50005 0 0 0 122.5,479 l 3,0 a 0.50005,0.50005 0 0 0 0.49414,-0.41797 l 1,-6 A 0.50005,0.50005 0 0 0 126.5,472 l -5,0 z m 0.5918,1 3.8164,0 -0.33203,2 -3.15234,0 -0.33203,-2 z" + id="path7771" + inkscape:connector-curvature="0" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/map_machine/road.py b/map_machine/road.py index f734a46..65c7873 100644 --- a/map_machine/road.py +++ b/map_machine/road.py @@ -415,42 +415,56 @@ class Road(Tagged): if "layer" in tags: self.layer = float(tags["layer"]) - def draw(self, svg: Drawing, flinger: Flinger, is_border: bool) -> None: - """Draw road as simple SVG path.""" + def get_style( + self, flinger: Flinger, is_border: bool, is_for_stroke: bool = False + ) -> dict: + """Get road SVG style.""" width: float if self.width is not None: width = self.width else: width = self.matcher.default_width + border_width: float if is_border: color = self.get_border_color() - extra_width = 2 + border_width = 2.0 else: color = self.get_color() - extra_width = 0 + border_width = 0.0 + extra_width: float = 0.0 if is_border: + if self.tags.get("bridge") == "yes": + extra_width = 0.5 if self.tags.get("ford") == "yes": - width += 2 + extra_width = 2.0 if self.tags.get("embankment") == "yes": - width += 4 + extra_width = 4.0 scale: float = flinger.get_scale(self.nodes[0].coordinates) - path_commands: str = self.line.get_path() - path: Path = Path(d=path_commands) style: dict[str, Any] = { "fill": "none", "stroke": color.hex, "stroke-linecap": "butt", "stroke-linejoin": "round", - "stroke-width": scale * width + extra_width, + "stroke-width": scale * width + extra_width + border_width, } + if is_for_stroke: + style["stroke-width"] = 2 + extra_width if is_border and self.tags.get("embankment") == "yes": style["stroke-dasharray"] = "1,3" if self.tags.get("tunnel") == "yes": if is_border: style["stroke-dasharray"] = "3,3" + + return style + + def draw(self, svg: Drawing, flinger: Flinger, is_border: bool) -> None: + """Draw road as simple SVG path.""" + style = self.get_style(flinger, is_border) + path_commands: str = self.line.get_path() + path: Path = Path(d=path_commands) path.update(style) svg.add(path) @@ -549,6 +563,7 @@ class Connector: self.road_1: Road self.index_1: int self.road_1, self.index_1 = connections[0] + self.priority = self.road_1.matcher.priority self.min_layer: float = min(x[0].layer for x in connections) self.max_layer: float = max(x[0].layer for x in connections) @@ -604,7 +619,7 @@ class SimpleConnector(Connector): class ComplexConnector(Connector): """ - Connection between roads that change width. + Connection between two roads that change width. """ def __init__( @@ -649,24 +664,22 @@ class ComplexConnector(Connector): circle: Circle = svg.circle( road.line.points[index], road.width * self.scale / 2, - fill=road.matcher.color.hex, + fill=road.get_color(), ) svg.add(circle) path: Path = svg.path( d=["M"] + self.curve_1 + ["L"] + self.curve_2 + ["Z"], - fill=self.road_1.matcher.color.hex, + fill=self.road_1.get_color(), ) svg.add(path) def draw_border(self, svg: Drawing) -> None: """Draw connection outline.""" path: Path = svg.path( - d=["M"] + self.curve_1 + ["L"] + self.curve_2 + ["Z"], - fill="none", - stroke=self.road_1.matcher.border_color.hex, - stroke_width=2, + d=["M"] + self.curve_1 + ["L"] + self.curve_2 + ["Z"] ) + path.update(self.road_1.get_style(self.flinger, True, True)) svg.add(path) @@ -685,7 +698,9 @@ class SimpleIntersection(Connector): def draw(self, svg: Drawing) -> None: """Draw connection fill.""" - for road, index in self.connections: + for road, index in sorted( + self.connections, key=lambda x: x[0].matcher.priority + ): node: OSMNode = self.road_1.nodes[self.index_1] point: np.ndarray = self.flinger.fling(node.coordinates) circle: Circle = svg.circle( @@ -757,7 +772,8 @@ class Roads: else: connector = ComplexConnector(connected, flinger, scale) else: - connector = SimpleIntersection(connected, flinger, scale) + continue + # connector = SimpleIntersection(connected, flinger, scale) if connector.min_layer not in layered_connectors: layered_connectors[connector.min_layer] = [] @@ -783,11 +799,11 @@ class Roads: if connector.min_layer == layer: connector.draw_border(svg) + for road in roads: + road.draw(svg, flinger, False) for connector in connectors: if connector.max_layer == layer: connector.draw(svg) - for road in roads: - road.draw(svg, flinger, False) for road in roads: road.draw_lanes(svg, flinger, road.matcher.border_color) diff --git a/tests/test_elements.py b/tests/test_elements.py index 043200e..870d5ae 100644 --- a/tests/test_elements.py +++ b/tests/test_elements.py @@ -1,3 +1,6 @@ +""" +Draw test nodes, ways, and relations. +""" from pathlib import Path from typing import Optional