mirror of
https://github.com/enzet/map-machine.git
synced 2025-05-31 18:06:23 +02:00
Refactor way and relation processing.
This commit is contained in:
parent
bbc28b4c61
commit
5506eb3082
7 changed files with 256 additions and 310 deletions
|
@ -8,9 +8,9 @@ import yaml
|
|||
|
||||
from colour import Color
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Dict, List, Optional, Set
|
||||
from typing import Any, Dict, List, Optional, Set, Union
|
||||
|
||||
from roentgen.extract_icon import DEFAULT_SHAPE_ID
|
||||
from roentgen.icon import DEFAULT_SHAPE_ID
|
||||
|
||||
DEFAULT_COLOR: Color = Color("#444444")
|
||||
|
||||
|
@ -28,6 +28,12 @@ class IconSet:
|
|||
is_default: bool
|
||||
|
||||
|
||||
@dataclass
|
||||
class LineStyle:
|
||||
style: Dict[str, Union[int, float, str]]
|
||||
priority: float = 0.0
|
||||
|
||||
|
||||
class Scheme:
|
||||
"""
|
||||
Map style.
|
||||
|
@ -43,7 +49,9 @@ class Scheme:
|
|||
content: Dict[str, Any] = yaml.load(
|
||||
input_file.read(), Loader=yaml.FullLoader)
|
||||
|
||||
self.nodes: List[Dict[str, Any]] = content["nodes"]
|
||||
self.node_icons: List[Dict[str, Any]] = content["node_icons"]
|
||||
self.line_icons: List[Dict[str, Any]] = content["line_icons"]
|
||||
|
||||
self.ways: List[Dict[str, Any]] = content["ways"]
|
||||
|
||||
self.colors: Dict[str, str] = content["colors"]
|
||||
|
@ -83,7 +91,7 @@ class Scheme:
|
|||
if key in self.tags_to_write or key in self.tags_to_skip:
|
||||
return True
|
||||
for prefix in self.prefix_to_write + self.prefix_to_skip: # type: str
|
||||
if key[:len(prefix) + 1] == prefix + ":":
|
||||
if key[:len(prefix) + 1] == f"{prefix}:":
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -94,24 +102,23 @@ class Scheme:
|
|||
|
||||
:param key: OpenStreetMap tag key
|
||||
"""
|
||||
if key in self.tags_to_skip:
|
||||
if key in self.tags_to_skip: # type: str
|
||||
return False
|
||||
if key in self.tags_to_write:
|
||||
if key in self.tags_to_write: # type: str
|
||||
return True
|
||||
for prefix in self.prefix_to_write:
|
||||
if key[:len(prefix) + 1] == prefix + ":":
|
||||
for prefix in self.prefix_to_write: # type: str
|
||||
if key[:len(prefix) + 1] == f"{prefix}:":
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_icon(self, tags: Dict[str, Any]) -> IconSet:
|
||||
def get_icon(self, tags: Dict[str, Any], for_: str = "node") -> IconSet:
|
||||
"""
|
||||
Construct icon set.
|
||||
|
||||
:param tags: OpenStreetMap element tags dictionary
|
||||
"""
|
||||
tags_hash: str = \
|
||||
",".join(tags.keys()) + ":" + \
|
||||
",".join(map(lambda x: str(x), tags.values()))
|
||||
tags_hash: str = (
|
||||
",".join(tags.keys()) + ":" + ",".join(map(str, tags.values())))
|
||||
|
||||
if tags_hash in self.cache:
|
||||
return self.cache[tags_hash]
|
||||
|
@ -121,14 +128,16 @@ class Scheme:
|
|||
processed: Set[str] = set()
|
||||
fill: Color = DEFAULT_COLOR
|
||||
|
||||
for matcher in self.nodes: # type: Dict[str, Any]
|
||||
rules = self.node_icons if for_ == "node" else self.line_icons
|
||||
|
||||
for matcher in rules: # type: Dict[str, Any]
|
||||
matched: bool = True
|
||||
for key in matcher["tags"]: # type: str
|
||||
if key not in tags:
|
||||
matched = False
|
||||
break
|
||||
if matcher["tags"][key] != "*" and \
|
||||
matcher["tags"][key] != tags[key]:
|
||||
if (matcher["tags"][key] != "*" and
|
||||
matcher["tags"][key] != tags[key]):
|
||||
matched = False
|
||||
break
|
||||
if "no_tags" in matcher:
|
||||
|
@ -136,29 +145,30 @@ class Scheme:
|
|||
if no_tag in tags.keys():
|
||||
matched = False
|
||||
break
|
||||
if matched:
|
||||
if "draw" in matcher and not matcher["draw"]:
|
||||
processed |= set(matcher["tags"].keys())
|
||||
if "icon" in matcher:
|
||||
main_icon = copy.deepcopy(matcher["icon"])
|
||||
processed |= set(matcher["tags"].keys())
|
||||
if "over_icon" in matcher:
|
||||
if main_icon: # TODO: check main icon in under icons
|
||||
main_icon += matcher["over_icon"]
|
||||
for key in matcher["tags"].keys():
|
||||
processed.add(key)
|
||||
if "add_icon" in matcher:
|
||||
extra_icons += [matcher["add_icon"]]
|
||||
for key in matcher["tags"].keys():
|
||||
processed.add(key)
|
||||
if "color" in matcher:
|
||||
fill = self.get_color(matcher["color"])
|
||||
if not matched:
|
||||
continue
|
||||
if "draw" in matcher and not matcher["draw"]:
|
||||
processed |= set(matcher["tags"].keys())
|
||||
if "icon" in matcher:
|
||||
main_icon = copy.deepcopy(matcher["icon"])
|
||||
processed |= set(matcher["tags"].keys())
|
||||
if "over_icon" in matcher:
|
||||
if main_icon: # TODO: check main icon in under icons
|
||||
main_icon += matcher["over_icon"]
|
||||
for key in matcher["tags"].keys():
|
||||
processed.add(key)
|
||||
if "add_icon" in matcher:
|
||||
extra_icons += [matcher["add_icon"]]
|
||||
for key in matcher["tags"].keys():
|
||||
processed.add(key)
|
||||
if "color" in matcher:
|
||||
fill = self.get_color(matcher["color"])
|
||||
for key in matcher["tags"].keys():
|
||||
processed.add(key)
|
||||
|
||||
for tag_key in tags: # type: str
|
||||
if tag_key in ["color", "colour"] or tag_key.endswith(":color") or \
|
||||
tag_key.endswith(":colour"):
|
||||
if (tag_key in ["color", "colour"] or tag_key.endswith(":color") or
|
||||
tag_key.endswith(":colour")):
|
||||
fill = self.get_color(tags[tag_key])
|
||||
processed.add(tag_key)
|
||||
|
||||
|
@ -181,3 +191,48 @@ class Scheme:
|
|||
self.cache[tags_hash] = returned
|
||||
|
||||
return returned
|
||||
|
||||
def get_style(self, tags: Dict[str, Any], scale):
|
||||
|
||||
line_styles = []
|
||||
|
||||
for element in self.ways: # type: Dict[str, Any]
|
||||
priority = 0
|
||||
matched: bool = True
|
||||
for config_tag_key in element["tags"]: # type: str
|
||||
matcher = element["tags"][config_tag_key]
|
||||
if (config_tag_key not in tags or
|
||||
(matcher != "*" and
|
||||
tags[config_tag_key] != matcher and
|
||||
tags[config_tag_key] not in matcher)):
|
||||
matched = False
|
||||
break
|
||||
if "no_tags" in element:
|
||||
for config_tag_key in element["no_tags"]: # type: str
|
||||
if (config_tag_key in tags and
|
||||
tags[config_tag_key] ==
|
||||
element["no_tags"][config_tag_key]):
|
||||
matched = False
|
||||
break
|
||||
if not matched:
|
||||
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", "no_tags", "priority", "level", "icon",
|
||||
"r", "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 "r2" in element:
|
||||
style["stroke-width"] = (element["r2"] * scale + 2)
|
||||
|
||||
line_styles.append(LineStyle(style, priority))
|
||||
|
||||
return line_styles
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue