Issue #45: refactor road specification in scheme.

Add special "road" part and move road specifications from the "ways".
Add road matcher.  We should remove "priority" key and use
specifications order instead in the future.
This commit is contained in:
Sergey Vartanov 2021-05-28 04:05:15 +03:00
parent 38925e3a71
commit 9d41b34214
4 changed files with 171 additions and 266 deletions

View file

@ -19,7 +19,7 @@ from roentgen.osm_reader import (
Map, OSMMember, OSMNode, OSMRelation, OSMWay, Tagged
)
from roentgen.point import Point
from roentgen.scheme import DEFAULT_COLOR, LineStyle, Scheme
from roentgen.scheme import DEFAULT_COLOR, LineStyle, Scheme, RoadMatcher
from roentgen.util import MinMax
__author__ = "Sergey Vartanov"
@ -30,12 +30,6 @@ TIME_COLOR_SCALE: List[Color] = [
Color("#581845"), Color("#900C3F"), Color("#C70039"), Color("#FF5733"),
Color("#FFC300"), Color("#DAF7A6")
]
ROAD_HIGHWAY_VALUES: List[str] = [
"motorway", "trunk", "primary", "secondary", "tertiary", "unclassified",
"residential", "motorway_link", "trunk_link", "primary_link",
"secondary_link", "tertiary_link", "living_street", "service",
"pedestrian", "track", "bus_guideway", "escape", "raceway", "road", "busway"
]
def is_clockwise(polygon: List[OSMNode]) -> bool:
@ -175,11 +169,10 @@ class Road(Figure):
"""
def __init__(
self, tags: Dict[str, str], inners, outers, flinger: Flinger,
line_styles: List[LineStyle]
self, tags: Dict[str, str], inners, outers, matcher
):
super().__init__(tags, inners, outers, None)
self.line_styles = line_styles
self.matcher: RoadMatcher = matcher
def line_center(nodes: List[OSMNode], flinger: Flinger) -> np.array:
@ -387,12 +380,10 @@ class Constructor:
Building(line.tags, inners, outers, self.flinger, self.scheme)
)
if (
"highway" in line.tags
and line.tags["highway"] in ROAD_HIGHWAY_VALUES
):
road_matcher = self.scheme.get_road(line.tags)
if road_matcher:
self.roads.append(
Road(line.tags, inners, outers, self.flinger, line_styles)
Road(line.tags, inners, outers, road_matcher)
)
return

View file

@ -75,17 +75,33 @@ class Painter:
ui.progress_bar(-1, 0, text="Drawing ways")
roads = sorted(
constructor.roads, key=lambda x: x.line_styles[0].priority
constructor.roads, key=lambda x: x.matcher.priority
)
for road in roads:
path_commands: str = road.get_path(self.flinger)
path = Path(d=path_commands)
path.update(road.line_styles[0].style)
path.update({
"fill": "none",
"stroke": road.matcher.border_color.hex,
"stroke-linecap": "round",
"stroke-linejoin": "round",
"stroke-width":
road.matcher.default_width
* self.flinger.get_scale(road.outers[0][0].coordinates) + 2
})
self.svg.add(path)
for road in roads:
path_commands: str = road.get_path(self.flinger)
path = Path(d=path_commands)
path.update(road.line_styles[1].style)
path.update({
"fill": "none",
"stroke": road.matcher.color.hex,
"stroke-linecap": "round",
"stroke-linejoin": "round",
"stroke-width":
road.matcher.default_width
* self.flinger.get_scale(road.outers[0][0].coordinates)
})
self.svg.add(path)
# Trees

View file

@ -163,22 +163,18 @@ class WayMatcher(Matcher):
if "priority" in structure:
self.priority = structure["priority"]
self.r = None
if "r" in structure:
self.r = structure["r"]
self.l = 0
if "r1" in structure:
self.r = structure["r1"]
self.l = 1
if "r2" in structure:
self.r = structure["r2"]
self.l = 2
def get_style(self, scale):
if self.r:
return {**self.style, **{"stroke-width": self.r * scale + self.l}}
else:
return self.style
class RoadMatcher(Matcher):
def __init__(self, structure: Dict[str, Any], scheme):
super().__init__(structure)
self.border_color: Color = Color(scheme.get_color(structure["border_color"]))
self.color: Color = Color("white")
if "color" in structure:
self.color = Color(scheme.get_color(structure["color"]))
self.default_width: float = structure["default_width"]
self.priority: float = 0
if "priority" in structure:
self.priority = structure["priority"]
class Scheme:
@ -206,6 +202,9 @@ class Scheme:
self.way_matchers: List[WayMatcher] = [
WayMatcher(x, self.colors) for x in content["ways"]
]
self.road_matchers: List[RoadMatcher] = [
RoadMatcher(x, self) for x in content["roads"]
]
self.area_matchers: List[Matcher] = [
Matcher(x) for x in content["area_tags"]
]
@ -374,12 +373,17 @@ class Scheme:
if not matcher.is_matched(tags):
continue
line_styles.append(
LineStyle(matcher.get_style(scale), matcher.priority)
)
line_styles.append(LineStyle(matcher.style, matcher.priority))
return line_styles
def get_road(self, tags: Dict[str, Any]) -> Optional[RoadMatcher]:
for matcher in self.road_matchers:
if not matcher.is_matched(tags):
continue
return matcher
return None
def construct_text(
self, tags: Dict[str, str], draw_captions: str
) -> List[Label]:

View file

@ -822,6 +822,56 @@ node_icons:
- tags: {crossing:island: "no"}
add_shapes: [rectangle_vertical_rounded_crossed]
roads:
- tags: {highway: motorway}
default_width: 15
border_color: road_border_color
color: "#FFFFFF"
- tags: {highway: trunk}
default_width: 13
border_color: road_border_color
priority: 41
- tags: {highway: primary}
default_width: 11
border_color: primary_border_color
color: primary_color
priority: 41.9
- tags: {highway: motorway_link}
default_width: 9
border_color: road_border_color
priority: 41
- tags: {highway: secondary}
default_width: 9
border_color: secondary_border_color
priority: 41.8
color: secondary_color
- tags: {highway: tertiary}
default_width: 7
border_color: tertiary_border_color
priority: 41.7
color: tertiary_color
- tags: {highway: unclassified}
default_width: 5
border_color: road_border_color
priority: 41
- tags: {highway: residential}
default_width: 5
border_color: road_border_color
priority: 41
- tags: {highway: living_street}
default_width: 4
border_color: road_border_color
priority: 41
- tags: {highway: service}
exception: {service: parking_aisle}
default_width: 3
border_color: road_border_color
priority: 41
- tags: {highway: service, service: parking_aisle}
default_width: 2
border_color: road_border_color
priority: 41
ways:
- tags: {indoor: area}
style:
@ -866,6 +916,79 @@ ways:
opacity: 0.1
priority: 80
- tags: {highway: track}
style:
stroke-width: 1.5
stroke: track_color
stroke-linecap: round
stroke-linejoin: round
priority: 41
- tags: {highway: [footway, pedestrian, cycleway]}
exception: {area: "yes"}
style:
stroke-width: 3
stroke: foot_border_color
stroke-linecap: round
stroke-linejoin: round
priority: 41
- tags: {highway: steps}
style:
stroke-width: 6
stroke: foot_border_color
stroke-linecap: butt
- tags: {highway: path}
style:
stroke-width: 3
stroke: foot_border_color
priority: 41
- tags: {highway: [footway, pedestrian]}
exception: {area: "yes"}
style:
stroke-width: 1.5
stroke-dasharray: 7,3
stroke-linecap: round
stroke-linejoin: round
stroke: foot_color
priority: 42
- tags: {highway: [footway, pedestrian], area: "yes"}
style:
stroke: none
fill: "#DDDDDD"
stroke-linecap: round
stroke-linejoin: round
priority: -55 # FIXME
- tags: {highway: cycleway}
exception: {area: "yes"}
style:
stroke-width: 1
stroke: cycle_color
stroke-dasharray: 8,2
stroke-linecap: butt
priority: 42
- tags: {highway: steps, conveying: "*"}
style:
stroke-width: 5
stroke-dasharray: 1.5,2
stroke-linecap: butt
stroke: "#888888"
priority: 42
- tags: {highway: steps}
exception: {conveying: "*"}
style:
stroke-width: 5
stroke-dasharray: 1.5,2
stroke-linecap: butt
stroke: foot_color
priority: 42
- tags: {highway: path}
style:
stroke-width: 1.5
stroke-dasharray: 5,3
stroke-linecap: butt
stroke: foot_color
priority: 42
- tags: {natural: wood}
style:
fill: wood_color
@ -1047,235 +1170,6 @@ ways:
stroke: platform_border_color
priority: 41
- tags: {highway: motorway}
r2: 15
style:
stroke: road_border_color
stroke-linecap: round
stroke-linejoin: round
priority: 41
- tags: {highway: trunk}
r2: 13
style:
stroke: road_border_color
stroke-linecap: round
stroke-linejoin: round
priority: 41
- tags: {highway: primary}
r2: 11
style:
stroke: primary_border_color
stroke-linecap: round
stroke-linejoin: round
priority: 41.9
- tags: {highway: motorway_link}
r2: 9
style:
stroke: road_border_color
stroke-linecap: round
stroke-linejoin: round
priority: 41
- tags: {highway: secondary}
r2: 9
style:
stroke: secondary_border_color
stroke-linecap: round
stroke-linejoin: round
priority: 41.8
- tags: {highway: tertiary}
r2: 7
style:
stroke: tertiary_border_color
stroke-linecap: round
stroke-linejoin: round
priority: 41.7
- tags: {highway: unclassified}
r2: 5
style:
stroke: road_border_color
stroke-linecap: round
stroke-linejoin: round
priority: 41
- tags: {highway: residential}
r2: 5
style:
stroke: road_border_color
stroke-linecap: round
stroke-linejoin: round
priority: 41
- tags: {highway: living_street}
r2: 4
style:
stroke: road_border_color
stroke-linecap: round
stroke-linejoin: round
priority: 41
- tags: {highway: service}
exception: {service: parking_aisle}
r2: 3
style:
stroke: road_border_color
stroke-linecap: round
stroke-linejoin: round
priority: 41
- tags: {highway: service, service: parking_aisle}
r2: 2
style:
stroke: road_border_color
stroke-linecap: round
stroke-linejoin: round
priority: 41
- tags: {highway: track}
style:
stroke-width: 1.5
stroke: track_color
stroke-linecap: round
stroke-linejoin: round
priority: 41
- tags: {highway: [footway, pedestrian, cycleway]}
exception: {area: "yes"}
style:
stroke-width: 3
stroke: foot_border_color
stroke-linecap: round
stroke-linejoin: round
priority: 41
- tags: {highway: steps}
style:
stroke-width: 6
stroke: foot_border_color
stroke-linecap: butt
- tags: {highway: path}
style:
stroke-width: 3
stroke: foot_border_color
priority: 41
- tags: {highway: motorway}
r: 15
style:
stroke: "#FFFFFF"
stroke-linecap: round
stroke-linejoin: round
priority: 42
- tags: {highway: trunk}
r: 13
style:
stroke: "#FFFFFF"
stroke-linecap: round
stroke-linejoin: round
priority: 42
- tags: {highway: primary}
r: 11
style:
stroke: primary_color
stroke-linecap: round
stroke-linejoin: round
priority: 42.9
- tags: {highway: secondary}
r: 9
style:
stroke: secondary_color
stroke-linecap: round
stroke-linejoin: round
priority: 42.8
- tags: {highway: motorway_link}
r: 9
style:
stroke: "#FFFFFF"
stroke-linecap: round
stroke-linejoin: round
priority: 42
- tags: {highway: tertiary}
r: 7
style:
stroke: tertiary_color
stroke-linecap: round
stroke-linejoin: round
priority: 42.7
- tags: {highway: unclassified}
r: 5
style:
stroke: "#FFFFFF"
stroke-linecap: round
stroke-linejoin: round
priority: 42
- tags: {highway: residential}
r: 5
style:
stroke: "#FFFFFF"
stroke-linecap: round
stroke-linejoin: round
priority: 42
- tags: {highway: living_street}
r: 4
style:
stroke: "#FFFFFF"
stroke-linecap: round
stroke-linejoin: round
priority: 42
- tags: {highway: service}
exception: {service: parking_aisle}
r: 3
style:
stroke: "#FFFFFF"
stroke-linecap: round
stroke-linejoin: round
priority: 42
- tags: {highway: service, service: parking_aisle}
r: 2
style:
stroke: "#FFFFFF"
stroke-linecap: round
stroke-linejoin: round
priority: 42
- tags: {highway: [footway, pedestrian]}
exception: {area: "yes"}
style:
stroke-width: 1.5
stroke-dasharray: 7,3
stroke-linecap: round
stroke-linejoin: round
stroke: foot_color
priority: 42
- tags: {highway: [footway, pedestrian], area: "yes"}
style:
stroke: none
fill: "#DDDDDD"
stroke-linecap: round
stroke-linejoin: round
priority: -55 # FIXME
- tags: {highway: cycleway}
exception: {area: "yes"}
style:
stroke-width: 1
stroke: cycle_color
stroke-dasharray: 8,2
stroke-linecap: butt
priority: 42
- tags: {highway: steps, conveying: "*"}
style:
stroke-width: 5
stroke-dasharray: 1.5,2
stroke-linecap: butt
stroke: "#888888"
priority: 42
- tags: {highway: steps}
exception: {conveying: "*"}
style:
stroke-width: 5
stroke-dasharray: 1.5,2
stroke-linecap: butt
stroke: foot_color
priority: 42
- tags: {highway: path}
style:
stroke-width: 1.5
stroke-dasharray: 5,3
stroke-linecap: butt
stroke: foot_color
priority: 42
- tags: {route: ferry}
style:
stroke-width: 1