Issue #63: support ways, areas, and relations.

This commit is contained in:
Sergey Vartanov 2021-07-29 23:38:11 +03:00
parent 6635a5de4a
commit 0748bab9a5
9 changed files with 73 additions and 37 deletions

View file

@ -107,10 +107,6 @@ def main(options) -> None:
Path(ICONS_FILE_NAME), Path("icons/config.json")
)
def check_level(x) -> bool:
"""Draw objects on all levels."""
return True
if options.level:
if options.level == "overground":
check_level = check_level_overground

View file

@ -1,7 +1,6 @@
"""
Construct Röntgen nodes and ways.
"""
from collections import Counter
from datetime import datetime
from hashlib import sha256
from typing import Any, Dict, Iterator, List, Optional, Set

View file

@ -1,9 +1,9 @@
"""
Icon grid drawing.
"""
from dataclasses import dataclass, field
from dataclasses import dataclass
from pathlib import Path
from typing import Dict, List, Optional, Set
from typing import List, Optional, Set
import logging
import numpy as np

View file

@ -2,7 +2,7 @@
MapCSS scheme creation.
"""
from pathlib import Path
from typing import Dict, List, Optional
from typing import List, Optional, Dict
import logging
from colour import Color
@ -23,13 +23,8 @@ class MapCSSWriter:
self.add_icons_for_lifecycle = add_icons_for_lifecycle
self.icon_directory_name = icon_directory_name
self.matchers: Dict[Matcher, List[str]] = {}
for matcher in scheme.node_matchers:
if matcher.shapes and not matcher.location_restrictions:
self.matchers[matcher] = [
(x if isinstance(x, str) else x["shape"])
for x in matcher.shapes
]
self.point_matchers: List[Matcher] = scheme.node_matchers
self.line_matchers: List[Matcher] = scheme.way_matchers
def add_selector(
self,
@ -38,15 +33,40 @@ class MapCSSWriter:
prefix: str = "",
opacity: Optional[float] = None,
) -> str:
selector = (
target + matcher.get_mapcss_selector(prefix) + " {\n"
f' icon-image: "{self.icon_directory_name}/'
+ "___".join(self.matchers[matcher])
+ '.svg";\n'
elements: Dict[str, str] = {}
clean_shapes = matcher.get_clean_shapes()
if clean_shapes:
elements["icon-image"] = (
f'"{self.icon_directory_name}/'
+ "___".join(clean_shapes) + '.svg"'
)
if opacity is not None:
selector += f" icon-opacity: {opacity:.2f};\n"
elements["icon-opacity"] = f"{opacity:.2f}"
style = matcher.get_style()
if style:
if "fill" in style:
elements["fill-color"] = style["fill"]
if "stroke" in style:
elements["color"] = style["stroke"]
if "stroke-width" in style:
elements["width"] = style["stroke-width"]
if "stroke-dasharray" in style:
elements["dashes"] = style["stroke-dasharray"]
if "opacity" in style:
elements["fill-opacity"] = style["opacity"]
elements["opacity"] = style["opacity"]
if not elements:
return ""
selector: str = target + matcher.get_mapcss_selector(prefix) + " {\n"
for element in elements:
selector += f" {element}: {elements[element]};\n"
selector += "}\n"
return selector
def write(self, output_file) -> None:
@ -58,7 +78,11 @@ class MapCSSWriter:
output_file.write("\n")
for matcher in self.matchers:
for line_matcher in self.line_matchers:
for target in ["way", "relation"]:
output_file.write(self.add_selector(target, line_matcher))
for matcher in self.point_matchers:
for target in ["node", "area"]:
output_file.write(self.add_selector(target, matcher))
@ -67,7 +91,7 @@ class MapCSSWriter:
for index, stage_of_decay in enumerate(STAGES_OF_DECAY):
opacity: float = 0.6 - 0.4 * index / (len(STAGES_OF_DECAY) - 1)
for matcher in self.matchers:
for matcher in self.point_matchers:
if len(matcher.tags) > 1:
continue
for target in ["node", "area"]:

View file

@ -51,9 +51,13 @@ class ArgumentParser(argparse.ArgumentParser):
if "help" in option:
help_value: List = [option["help"]]
if "default" in option and option["default"] and option["default"] != "==SUPPRESS==":
if (
"default" in option
and option["default"]
and option["default"] != "==SUPPRESS=="
):
help_value += [
f", default value: ", Tag("tt", [str(option['default'])])
", default value: ", Tag("tt", [str(option['default'])])
]
row.append(help_value)
else:

View file

@ -137,7 +137,15 @@ class Matcher:
See https://wiki.openstreetmap.org/wiki/MapCSS/0.2
"""
return "".join([get_selector(x, y, prefix) for (x, y) in self.tags.items()])
return "".join(
[get_selector(x, y, prefix) for (x, y) in self.tags.items()]
)
def get_clean_shapes(self):
return None
def get_style(self):
return None
class NodeMatcher(Matcher):
@ -177,6 +185,11 @@ class NodeMatcher(Matcher):
if "with_icon" in structure:
self.with_icon = structure["with_icon"]
def get_clean_shapes(self):
if not self.shapes:
return
return [(x if isinstance(x, str) else x["shape"]) for x in self.shapes]
class WayMatcher(Matcher):
"""
@ -197,6 +210,9 @@ class WayMatcher(Matcher):
if "priority" in structure:
self.priority = structure["priority"]
def get_style(self):
return self.style
class RoadMatcher(Matcher):
"""
@ -391,11 +407,11 @@ class Scheme:
if main_icon and color:
main_icon.recolor(color)
keys_left = [
x
for x in tags.keys()
if x not in processed and not self.is_no_drawable(x)
]
# keys_left = [
# x
# for x in tags.keys()
# if x not in processed and not self.is_no_drawable(x)
# ]
default_shape = icon_extractor.get_shape(DEFAULT_SHAPE_ID)
if not main_icon:

View file

@ -6,7 +6,7 @@ See https://wiki.openstreetmap.org/wiki/Taginfo/Projects
import json
from datetime import datetime
from pathlib import Path
from typing import Dict, List
from typing import List
import logging

View file

@ -3,7 +3,6 @@ Tile generation.
See https://wiki.openstreetmap.org/wiki/Tiles
"""
import argparse
import sys
from dataclasses import dataclass
from pathlib import Path

View file

@ -13,5 +13,3 @@ SCHEME: Scheme = Scheme(Path("scheme/default.yml"))
SHAPE_EXTRACTOR: ShapeExtractor = ShapeExtractor(
Path("icons/icons.svg"), Path("icons/config.json")
)