diff --git a/roentgen/grid.py b/roentgen/grid.py index a353479..192f85e 100644 --- a/roentgen/grid.py +++ b/roentgen/grid.py @@ -54,33 +54,34 @@ def draw_all_icons( if constructed_icon not in icons: icons.append(constructed_icon) - for group in scheme.icons: - for element in group["tags"]: # type: Dict[str, Any] - for key in ["shapes", "add_shapes"]: - if key in element: - current_set = element[key] - add() - if "over_icon" not in element: - continue - if "under_icon" in element: - for icon_id in element["under_icon"]: # type: str - current_set = set([icon_id] + element["over_icon"]) - add() - if not ("under_icon" in element and "with_icon" in element): - continue - for icon_id in element["under_icon"]: # type: str - for icon_2_id in element["with_icon"]: # type: str - current_set: Set[str] = set( - [icon_id] + [icon_2_id] + element["over_icon"]) - add() - for icon_2_id in element["with_icon"]: # type: str - for icon_3_id in element["with_icon"]: # type: str - current_set = set( - [icon_id] + [icon_2_id] + [icon_3_id] + - element["over_icon"]) - if (icon_2_id != icon_3_id and icon_2_id != icon_id and - icon_3_id != icon_id): - add() + for matcher in scheme.node_matchers: + if matcher.shapes: + current_set = matcher.shapes + add() + if matcher.add_shapes: + current_set = matcher.add_shapes + add() + if not matcher.over_icon: + continue + if matcher.under_icon: + for icon_id in matcher.under_icon: + current_set = set([icon_id] + matcher.over_icon) + add() + if not (matcher.under_icon and matcher.with_icon): + continue + for icon_id in matcher.under_icon: + for icon_2_id in matcher.with_icon: + current_set: Set[str] = set( + [icon_id] + [icon_2_id] + matcher.over_icon) + add() + for icon_2_id in matcher.with_icon: + for icon_3_id in matcher.with_icon: + current_set = set( + [icon_id] + [icon_2_id] + [icon_3_id] + + matcher.over_icon) + if (icon_2_id != icon_3_id and icon_2_id != icon_id and + icon_3_id != icon_id): + add() specified_ids: Set[str] = set() diff --git a/roentgen/scheme.py b/roentgen/scheme.py index 6ddafed..fe84e53 100644 --- a/roentgen/scheme.py +++ b/roentgen/scheme.py @@ -66,37 +66,119 @@ def is_matched_tag( return MatchingType.NOT_MATCHED -def is_matched(matcher: Dict[str, Any], tags: Dict[str, str]) -> bool: - """ - Check whether element tags matches tag matcher. +class Matcher: + def __init__(self, structure: Dict[str, Any]): + self.tags = structure["tags"] - :param matcher: dictionary with tag keys and values, value lists, or "*" - :param tags: element tags to match - """ - matched: bool = True + self.exception = None - for config_tag_key in matcher["tags"]: - config_tag_key: str - tag_matcher = matcher["tags"][config_tag_key] - if ( - is_matched_tag(config_tag_key, tag_matcher, tags) == - MatchingType.NOT_MATCHED - ): - matched = False - break + if "exception" in structure: + self.exception = structure["exception"] - if "exception" in matcher: - for config_tag_key in matcher["exception"]: + self.replace_shapes: bool = True + if "replace_shapes" in structure: + self.replace_shapes = structure["replace_shapes"] + + def is_matched(self, tags: Dict[str, str]) -> bool: + """ + Check whether element tags matches tag matcher. + + :param tags: element tags to match + """ + matched: bool = True + + for config_tag_key in self.tags: config_tag_key: str - tag_matcher = matcher["exception"][config_tag_key] + tag_matcher = self.tags[config_tag_key] if ( - is_matched_tag(config_tag_key, tag_matcher, tags) != - MatchingType.NOT_MATCHED + is_matched_tag(config_tag_key, tag_matcher, tags) == + MatchingType.NOT_MATCHED ): matched = False break - return matched + if self.exception: + for config_tag_key in self.exception: + config_tag_key: str + tag_matcher = self.exception[config_tag_key] + if ( + is_matched_tag(config_tag_key, tag_matcher, tags) != + MatchingType.NOT_MATCHED + ): + matched = False + break + + return matched + + +class NodeMatcher(Matcher): + """ + Tag specification matcher. + """ + def __init__(self, structure: Dict[str, Any]): + # Dictionary with tag keys and values, value lists, or "*" + super().__init__(structure) + + self.draw: bool = True + if "draw" in structure: + self.draw = structure["draw"] + + self.shapes = None + if "shapes" in structure: + self.shapes = structure["shapes"] + + self.over_icon = None + if "over_icon" in structure: + self.over_icon = structure["over_icon"] + + self.add_shapes = None + if "add_shapes" in structure: + self.add_shapes = structure["add_shapes"] + + self.set_main_color = None + if "set_main_color" in structure: + self.set_main_color = structure["set_main_color"] + + self.under_icon = None + if "under_icon" in structure: + self.under_icon = structure["under_icon"] + + self.with_icon = None + if "with_icon" in structure: + self.with_icon = structure["with_icon"] + + +class WayMatcher(Matcher): + def __init__(self, structure: Dict[str, Any], colors): + super().__init__(structure) + self.style: Dict[str, Any] = {"fill": "none"} + if "style" in structure: + style: Dict[str, Any] = structure["style"] + for key in style: + if str(style[key]).endswith("_color"): + self.style[key] = colors[style[key]] + else: + self.style[key] = style[key] + self.priority = 0 + 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 Scheme: @@ -112,15 +194,21 @@ class Scheme: """ with file_name.open() as input_file: content: Dict[str, Any] = yaml.load( - input_file.read(), Loader=yaml.FullLoader) - - self.icons: List[Dict[str, Any]] = content["node_icons"] - self.ways: List[Dict[str, Any]] = content["ways"] + input_file.read(), Loader=yaml.FullLoader + ) + self.node_matchers: List[NodeMatcher] = [] + for group in content["node_icons"]: + for element in group["tags"]: + self.node_matchers.append(NodeMatcher(element)) self.colors: Dict[str, str] = content["colors"] - self.area_tags: List[Dict[str, str]] = content["area_tags"] - + self.way_matchers: List[WayMatcher] = [ + WayMatcher(x, self.colors) for x in content["ways"] + ] + self.area_matchers: List[Matcher] = [ + Matcher(x) for x in content["area_tags"] + ] self.tags_to_write: List[str] = content["tags_to_write"] self.prefix_to_write: List[str] = content["prefix_to_write"] self.tags_to_skip: List[str] = content["tags_to_skip"] @@ -202,49 +290,43 @@ class Scheme: index: int = 0 - for group in self.icons: - for matcher in group["tags"]: - matcher: Dict[str, Any] - if "replace_shapes" in matcher and main_icon: - continue - matched: bool = is_matched(matcher, tags) - matcher_tags: Set[str] = matcher["tags"].keys() - if not matched: - continue - priority = len(self.icons) - index - if "draw" in matcher and not matcher["draw"]: - processed |= set(matcher_tags) - if "shapes" in matcher: - main_icon = Icon([ - ShapeSpecification.from_structure(x, icon_extractor, self) - for x in matcher["shapes"] - ]) - processed |= set(matcher_tags) - if "over_icon" in matcher: - if main_icon: - main_icon.add_specifications([ - ShapeSpecification.from_structure( - x, icon_extractor, self - ) - for x in matcher["over_icon"] - ]) - for key in matcher_tags: - processed.add(key) - if "add_shapes" in matcher: - extra_icons += [Icon([ + for matcher in self.node_matchers: + if not matcher.replace_shapes and main_icon: + continue + matched: bool = matcher.is_matched(tags) + if not matched: + continue + matcher_tags: Set[str] = set(matcher.tags.keys()) + priority = len(self.node_matchers) - index + if not matcher.draw: + processed |= matcher_tags + if matcher.shapes: + main_icon = Icon([ + ShapeSpecification.from_structure(x, icon_extractor, self) + for x in matcher.shapes + ]) + processed |= matcher_tags + if matcher.over_icon: + if main_icon: + main_icon.add_specifications([ ShapeSpecification.from_structure( - x, icon_extractor, self, Color("#888888") + x, icon_extractor, self ) - for x in matcher["add_shapes"] - ])] - for key in matcher_tags: - processed.add(key) - if "color" in matcher: - assert False - if "set_main_color" in matcher: - main_icon.recolor(self.get_color(matcher["set_main_color"])) + for x in matcher.over_icon + ]) + processed |= matcher_tags + if matcher.add_shapes: + extra_icons += [Icon([ + ShapeSpecification.from_structure( + x, icon_extractor, self, Color("#888888") + ) + for x in matcher.add_shapes + ])] + processed |= matcher_tags + if matcher.set_main_color: + main_icon.recolor(self.get_color(matcher.set_main_color)) - index += 1 + index += 1 color: Optional[Color] = None @@ -288,31 +370,13 @@ class Scheme: """ line_styles = [] - for element in self.ways: # type: Dict[str, Any] - priority = 0 - matched: bool = is_matched(element, tags) - if not matched: + for matcher in self.way_matchers: + if not matcher.is_matched(tags): continue - style: Dict[str, Any] = {"fill": "none"} - if "priority" in element: - priority = element["priority"] - for key in element: # type: str - if key not in [ - "tags", "exception", "priority", "level", "shapes", "r", - "r1", "r2" - ]: - value = element[key] - if isinstance(value, str) and value.endswith("_color"): - value = self.get_color(value) - style[key] = value - if "r" in element: - style["stroke-width"] = (element["r"] * scale) - if "r1" in element: - style["stroke-width"] = (element["r1"] * scale + 1) - if "r2" in element: - style["stroke-width"] = (element["r2"] * scale + 2) - line_styles.append(LineStyle(style, priority)) + line_styles.append( + LineStyle(matcher.get_style(scale), matcher.priority) + ) return line_styles @@ -403,7 +467,7 @@ class Scheme: """ Check whether way described by tags is area. """ - for matcher in self.area_tags: - if is_matched(matcher, tags): + for matcher in self.area_matchers: + if matcher.is_matched(tags): return True return False diff --git a/scheme/default.yml b/scheme/default.yml index 330ebaf..d3e0c91 100644 --- a/scheme/default.yml +++ b/scheme/default.yml @@ -729,6 +729,12 @@ node_icons: {shape: digit_4, offset: [-2, 2]}, {shape: digit_0, offset: [2, 2]}, ] + - tags: {traffic_sign: maxspeed, maxspeed: ".."} + shapes: [ + circle_11, + {shape: digit_3, offset: [-2, 0], color: "#FFFFFF"}, + {shape: digit_0, offset: [2, 0], color: "#FFFFFF"}, + ] - tags: {traffic_sign: stop} shapes: [stop] - tags: {highway: give_way} @@ -818,470 +824,565 @@ node_icons: ways: - tags: {indoor: area} - stroke: indoor_border_color - stroke-width: 1 - fill: indoor_color + style: + stroke: indoor_border_color + stroke-width: 1 + fill: indoor_color priority: 10 - tags: {indoor: corridor} - stroke: indoor_color - stroke-width: 1 - fill: indoor_color + style: + stroke: indoor_color + stroke-width: 1 + fill: indoor_color priority: 11 - tags: {highway: corridor} - stroke: "#00FF00" - stroke-width: 5 + style: + stroke: "#00FF00" + stroke-width: 5 priority: 11 - tags: {indoor: ["yes", room, elevator], area: "yes"} - stroke: indoor_color - stroke-width: 1 - fill: indoor_color + style: + stroke: indoor_color + stroke-width: 1 + fill: indoor_color priority: 12 - tags: {indoor: column} - stroke: indoor_color - stroke-width: 1 - fill: indoor_color + style: + stroke: indoor_color + stroke-width: 1 + fill: indoor_color priority: 13 - tags: {power: line} - stroke: "#000000" - stroke-width: 1 - opacity: 0.2 + style: + stroke: "#000000" + stroke-width: 1 + opacity: 0.2 priority: 80 - tags: {power: cable} - stroke: "#000000" - stroke-width: 1 - opacity: 0.1 + style: + stroke: "#000000" + stroke-width: 1 + opacity: 0.1 priority: 80 - tags: {natural: wood} - fill: wood_color + style: + fill: wood_color priority: 21 - tags: {natural: wetland} - fill: wetland_color + style: + fill: wetland_color priority: 21 - tags: {natural: grassland} - fill: grass_color - stroke: grass_border_color + style: + fill: grass_color + stroke: grass_border_color priority: 20 - tags: {natural: scrub} - fill: wood_color + style: + fill: wood_color priority: 21 - tags: {natural: sand} - fill: sand_color + style: + fill: sand_color priority: 20 - tags: {natural: beach} - fill: beach_color + style: + fill: beach_color priority: 20 - tags: {natural: desert} - fill: desert_color + style: + fill: desert_color priority: 20 - tags: {natural: forest} - fill: wood_color + style: + fill: wood_color priority: 21 - tags: {natural: tree_row} priority: 21 - stroke: wood_color - stroke-width: 5 - stroke-linecap: round - stroke-linejoin: round + style: + stroke: wood_color + stroke-width: 5 + stroke-linecap: round + stroke-linejoin: round - tags: {natural: water} - fill: water_color - # stroke: water_border_color - # stroke-width: 1 + style: + fill: water_color + # stroke: water_border_color + # stroke-width: 1 priority: 21 - tags: {natural: coastline} - # fill: water_color - stroke: water_border_color - stroke-width: 1 + style: + # fill: water_color + stroke: water_border_color + stroke-width: 1 priority: 21 - tags: {natural: ridge} - stroke-width: 2 - opacity: 0.3 - stroke: ridge_color + style: + stroke-width: 2 + opacity: 0.3 + stroke: ridge_color priority: 21 - tags: {natural: bare_rock} - fill: rock_color + style: + fill: rock_color - tags: {natural: scree} - fill: scree_color + style: + fill: scree_color - tags: {landuse: allotments} - fill: allotments_color + style: + fill: allotments_color priority: 20 - tags: {landuse: conservation} - fill: grass_color + style: + fill: grass_color priority: 20 - tags: {landuse: construction} - fill: construction_color + style: + fill: construction_color - tags: {landuse: farmland} - fill: farmland_color + style: + fill: farmland_color + stroke: farmland_border_color priority: 20 - stroke: farmland_border_color - tags: {landuse: forest} - fill: wood_color + style: + fill: wood_color priority: 20 - tags: {landuse: garages} - fill: parking_color + style: + fill: parking_color priority: 21 - tags: {landuse: grass} - fill: grass_color + style: + fill: grass_color + stroke: grass_border_color priority: 20 - stroke: grass_border_color - tags: {landuse: orchard} - fill: orchard_color + style: + fill: orchard_color priority: 21 - tags: {landuse: meadow} - fill: meadow_color + style: + fill: meadow_color + stroke: meadow_border_color priority: 20 - stroke: meadow_border_color # Hidden land use - tags: {landuse: cemetery} - fill: hidden_color - opacity: 0.05 + style: + fill: hidden_color + opacity: 0.05 - tags: {landuse: commercial} - fill: hidden_color - opacity: 0.05 + style: + fill: hidden_color + opacity: 0.05 - tags: {landuse: industrial} - fill: hidden_color - opacity: 0.05 + style: + fill: hidden_color + opacity: 0.05 - tags: {landuse: military} - fill: hidden_color - opacity: 0.05 + style: + fill: hidden_color + opacity: 0.05 - tags: {landuse: railway} - fill: hidden_color - opacity: 0.05 + style: + fill: hidden_color + opacity: 0.05 - tags: {landuse: residential} - fill: hidden_color - opacity: 0.05 + style: + fill: hidden_color + opacity: 0.05 - tags: {power: substation} - fill: hidden_color - opacity: 0.05 + style: + fill: hidden_color + opacity: 0.05 - tags: {building: "*"} - fill: building_color - stroke: building_border_color + style: + fill: building_color + stroke: building_border_color #- tags: {building:part: "*"} # fill: building_color # stroke: building_border_color - tags: {amenity: ferry_terminal} - fill: ferry_terminal_color - priority: 50 + style: + fill: ferry_terminal_color + priority: 50 - tags: {amenity: parking} - fill: parking_color - opacity: 0.5 + style: + fill: parking_color + opacity: 0.5 - tags: {aeroway: landingpad} - fill: "#000000" - opacity: 0.1 + style: + fill: "#000000" + opacity: 0.1 - tags: {aeroway: helipad} - fill: "#440044" - opacity: 0.1 + style: + fill: "#440044" + opacity: 0.1 - tags: {waterway: riverbank} - fill: none # water_color - stroke: water_border_color - stroke-width: 1 + style: + fill: none # water_color + stroke: water_border_color + stroke-width: 1 - tags: {waterway: ditch} - fill: none # water_color - stroke: water_color - stroke-width: 2 + style: + fill: none # water_color + stroke: water_color + stroke-width: 2 - tags: {railway: subway} - stroke-width: 10 - stroke: "#DDDDDD" + style: + stroke-width: 10 + stroke: "#DDDDDD" priority: 41 - tags: {railway: [rail, narrow_gauge, tram]} - stroke-width: 2 - stroke: "#000000" + style: + stroke-width: 2 + stroke: "#000000" priority: 43 - tags: {railway: platform} - fill: platform_color - stroke-width: 1 - stroke: platform_border_color + style: + fill: platform_color + stroke-width: 1 + stroke: platform_border_color priority: 41 - tags: {highway: motorway} r2: 15 - stroke: road_border_color - stroke-linecap: round - stroke-linejoin: round + style: + stroke: road_border_color + stroke-linecap: round + stroke-linejoin: round priority: 41 - tags: {highway: trunk} r2: 13 - stroke: road_border_color - stroke-linecap: round - stroke-linejoin: round + style: + stroke: road_border_color + stroke-linecap: round + stroke-linejoin: round priority: 41 - tags: {highway: primary} r2: 11 - stroke: primary_border_color - stroke-linecap: round - stroke-linejoin: round + style: + stroke: primary_border_color + stroke-linecap: round + stroke-linejoin: round priority: 41.9 - tags: {highway: motorway_link} r2: 9 - stroke: road_border_color - stroke-linecap: round - stroke-linejoin: round + style: + stroke: road_border_color + stroke-linecap: round + stroke-linejoin: round priority: 41 - tags: {highway: secondary} r2: 9 - stroke: secondary_border_color - stroke-linecap: round - stroke-linejoin: round + style: + stroke: secondary_border_color + stroke-linecap: round + stroke-linejoin: round priority: 41.8 - tags: {highway: tertiary} r2: 7 - stroke: tertiary_border_color - stroke-linecap: round - stroke-linejoin: round + style: + stroke: tertiary_border_color + stroke-linecap: round + stroke-linejoin: round priority: 41.7 - tags: {highway: unclassified} r2: 5 - stroke: road_border_color - stroke-linecap: round - stroke-linejoin: round + style: + stroke: road_border_color + stroke-linecap: round + stroke-linejoin: round priority: 41 - tags: {highway: residential} r2: 5 - stroke: road_border_color - stroke-linecap: round - stroke-linejoin: round + style: + stroke: road_border_color + stroke-linecap: round + stroke-linejoin: round priority: 41 - tags: {highway: living_street} r2: 4 - stroke: road_border_color - stroke-linecap: round - stroke-linejoin: round + style: + stroke: road_border_color + stroke-linecap: round + stroke-linejoin: round priority: 41 - tags: {highway: service} exception: {service: parking_aisle} r2: 3 - stroke: road_border_color - stroke-linecap: round - stroke-linejoin: round + style: + stroke: road_border_color + stroke-linecap: round + stroke-linejoin: round priority: 41 - tags: {highway: service, service: parking_aisle} r2: 2 - stroke: road_border_color - stroke-linecap: round - stroke-linejoin: round + style: + stroke: road_border_color + stroke-linecap: round + stroke-linejoin: round priority: 41 - tags: {highway: track} - stroke-width: 1.5 - stroke: track_color - stroke-linecap: round - stroke-linejoin: round + style: + stroke-width: 1.5 + stroke: track_color + stroke-linecap: round + stroke-linejoin: round priority: 41 - tags: {highway: [footway, pedestrian, cycleway]} exception: {area: "yes"} - stroke-width: 3 - stroke: foot_border_color - stroke-linecap: round - stroke-linejoin: round + style: + stroke-width: 3 + stroke: foot_border_color + stroke-linecap: round + stroke-linejoin: round priority: 41 - tags: {highway: steps} - stroke-width: 6 - stroke: foot_border_color - stroke-linecap: butt + style: + stroke-width: 6 + stroke: foot_border_color + stroke-linecap: butt - tags: {highway: path} - stroke-width: 3 - stroke: foot_border_color + style: + stroke-width: 3 + stroke: foot_border_color priority: 41 - tags: {highway: motorway} r: 15 - stroke: "#FFFFFF" - stroke-linecap: round - stroke-linejoin: round + style: + stroke: "#FFFFFF" + stroke-linecap: round + stroke-linejoin: round priority: 42 - tags: {highway: trunk} r: 13 - stroke: "#FFFFFF" - stroke-linecap: round - stroke-linejoin: round + style: + stroke: "#FFFFFF" + stroke-linecap: round + stroke-linejoin: round priority: 42 - tags: {highway: primary} r: 11 - stroke: primary_color - stroke-linecap: round - stroke-linejoin: round + style: + stroke: primary_color + stroke-linecap: round + stroke-linejoin: round priority: 42.9 - tags: {highway: secondary} r: 9 - stroke: secondary_color - stroke-linecap: round - stroke-linejoin: round + style: + stroke: secondary_color + stroke-linecap: round + stroke-linejoin: round priority: 42.8 - tags: {highway: motorway_link} r: 9 - stroke: "#FFFFFF" - stroke-linecap: round - stroke-linejoin: round + style: + stroke: "#FFFFFF" + stroke-linecap: round + stroke-linejoin: round priority: 42 - tags: {highway: tertiary} r: 7 - stroke: tertiary_color - stroke-linecap: round - stroke-linejoin: round + style: + stroke: tertiary_color + stroke-linecap: round + stroke-linejoin: round priority: 42.7 - tags: {highway: unclassified} r: 5 - stroke: "#FFFFFF" - stroke-linecap: round - stroke-linejoin: round + style: + stroke: "#FFFFFF" + stroke-linecap: round + stroke-linejoin: round priority: 42 - tags: {highway: residential} r: 5 - stroke: "#FFFFFF" - stroke-linecap: round - stroke-linejoin: round + style: + stroke: "#FFFFFF" + stroke-linecap: round + stroke-linejoin: round priority: 42 - tags: {highway: living_street} r: 4 - stroke: "#FFFFFF" - stroke-linecap: round - stroke-linejoin: round + style: + stroke: "#FFFFFF" + stroke-linecap: round + stroke-linejoin: round priority: 42 - tags: {highway: service} exception: {service: parking_aisle} r: 3 - stroke: "#FFFFFF" - stroke-linecap: round - stroke-linejoin: round + style: + stroke: "#FFFFFF" + stroke-linecap: round + stroke-linejoin: round priority: 42 - tags: {highway: service, service: parking_aisle} r: 2 - stroke: "#FFFFFF" - stroke-linecap: round - stroke-linejoin: round + style: + stroke: "#FFFFFF" + stroke-linecap: round + stroke-linejoin: round priority: 42 - tags: {highway: [footway, pedestrian]} exception: {area: "yes"} - stroke-width: 1.5 - stroke-dasharray: 7,3 - stroke-linecap: round - stroke-linejoin: round - stroke: foot_color + 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"} - stroke: none - fill: "#DDDDDD" - stroke-linecap: round - stroke-linejoin: round + style: + stroke: none + fill: "#DDDDDD" + stroke-linecap: round + stroke-linejoin: round priority: -55 # FIXME - tags: {highway: cycleway} exception: {area: "yes"} - stroke-width: 1 - stroke: cycle_color - stroke-dasharray: 8,2 - stroke-linecap: butt + style: + stroke-width: 1 + stroke: cycle_color + stroke-dasharray: 8,2 + stroke-linecap: butt priority: 42 - tags: {highway: steps, conveying: "*"} - stroke-width: 5 - stroke-dasharray: 1.5,2 - stroke-linecap: butt - stroke: "#888888" + style: + stroke-width: 5 + stroke-dasharray: 1.5,2 + stroke-linecap: butt + stroke: "#888888" priority: 42 - tags: {highway: steps} exception: {conveying: "*"} - stroke-width: 5 - stroke-dasharray: 1.5,2 - stroke-linecap: butt - stroke: foot_color + style: + stroke-width: 5 + stroke-dasharray: 1.5,2 + stroke-linecap: butt + stroke: foot_color priority: 42 - tags: {highway: path} - stroke-width: 1.5 - stroke-dasharray: 5,3 - stroke-linecap: butt - stroke: foot_color + style: + stroke-width: 1.5 + stroke-dasharray: 5,3 + stroke-linecap: butt + stroke: foot_color priority: 42 - tags: {route: ferry} - stroke-width: 1 - stroke-dasharray: 3,3 - stroke-linecap: butt - stroke: route_color + style: + stroke-width: 1 + stroke-dasharray: 3,3 + stroke-linecap: butt + stroke: route_color priority: 42 - tags: {leisure: garden} - fill: grass_color + style: + fill: grass_color priority: 21 - tags: {leisure: park} - fill: grass_color - opacity: 0.5 + style: + fill: grass_color + opacity: 0.5 - tags: {leisure: pitch} - fill: pitch_color - stroke: pitch_border_color - stroke-width: 1 + style: + fill: pitch_color + stroke: pitch_border_color + stroke-width: 1 priority: 21 - tags: {leisure: track} - fill: pitch_color - stroke: pitch_border_color - stroke-width: 1 + style: + fill: pitch_color + stroke: pitch_border_color + stroke-width: 1 priority: 21 - tags: {leisure: fitness_station} - fill: pitch_color - stroke: pitch_border_color - stroke-width: 1 + style: + fill: pitch_color + stroke: pitch_border_color + stroke-width: 1 priority: 21 - tags: {leisure: playground} - fill: playground_color - opacity: 0.2 + style: + fill: playground_color + opacity: 0.2 priority: 21 - tags: {leisure: swimming_pool} - fill: water_color - stroke: water_border_color - stroke-width: 1 + style: + fill: water_color + stroke: water_border_color + stroke-width: 1 - tags: {barrier: hedge} - fill: none - stroke: wood_color - stroke-width: 4 + style: + fill: none + stroke: wood_color + stroke-width: 4 priority: 40 - tags: {barrier: city_wall} - fill: none - stroke: "#000000" - stroke-width: 1 - opacity: 0.35 + style: + fill: none + stroke: "#000000" + stroke-width: 1 + opacity: 0.35 priority: 40 - tags: {barrier: wall} - fill: none - stroke: "#000000" - stroke-width: 1 - opacity: 0.3 + style: + fill: none + stroke: "#000000" + stroke-width: 1 + opacity: 0.3 priority: 40 - tags: {barrier: [fence, retaining_wall]} - fill: none - stroke: "#000000" - stroke-width: 1 - opacity: 0.25 + style: + fill: none + stroke: "#000000" + stroke-width: 1 + opacity: 0.25 priority: 40 - tags: {barrier: handrail} - fill: none - stroke: "#000000" - stroke-width: 1 - opacity: 0.2 + style: + fill: none + stroke: "#000000" + stroke-width: 1 + opacity: 0.2 priority: 40 - tags: {barrier: kerb} - fill: none - stroke: "#000000" - stroke-width: 1 - opacity: 0.15 + style: + fill: none + stroke: "#000000" + stroke-width: 1 + opacity: 0.15 priority: 40 - tags: {border: "*"} - stroke: "#FF0000" - stroke-width: 0.5 - stroke-dasharray: 10,20 + style: + stroke: "#FF0000" + stroke-width: 0.5 + stroke-dasharray: 10,20 - tags: {"area:highway": "*"} - tags: {boundary: "*"} - # stroke: boundary_color - # stroke-width: 0.3 - # stroke-dasharray: 10,5 + # style: + # stroke: boundary_color + # stroke-width: 0.3 + # stroke-dasharray: 10,5 priority: 60 area_tags: