Issue #63: support MapCSS 0.2 for icons.

Support MapCSS 0.2 scheme generation with icons for nodes and areas.
This commit is contained in:
Sergey Vartanov 2021-07-10 19:31:47 +03:00
parent 557cc0cc98
commit 2eeccdb877
2 changed files with 37 additions and 6 deletions

View file

@ -23,6 +23,7 @@ class IconCollection:
""" """
icons: List[Icon] icons: List[Icon]
selectors: Dict[str, Icon]
@classmethod @classmethod
def from_scheme( def from_scheme(
@ -40,10 +41,13 @@ class IconCollection:
:param extractor: shape extractor for icon creation :param extractor: shape extractor for icon creation
:param background_color: background color :param background_color: background color
:param color: icon color :param color: icon color
:param add_unused: create icons from shapes that have no corresponding
tags
""" """
icons: List[Icon] = [] icons: List[Icon] = []
selectors: Dict[str, Icon] = {}
def add() -> None: def add() -> Icon:
""" """
Construct icon and add it to the list. Construct icon and add it to the list.
""" """
@ -56,10 +60,15 @@ class IconCollection:
if constructed_icon not in icons: if constructed_icon not in icons:
icons.append(constructed_icon) icons.append(constructed_icon)
return constructed_icon
for matcher in scheme.node_matchers: for matcher in scheme.node_matchers:
matcher: NodeMatcher
if matcher.shapes: if matcher.shapes:
current_set = matcher.shapes current_set = matcher.shapes
add() icon = add()
if not matcher.location_restrictions:
selectors[matcher.get_mapcss_selector()] = icon
if matcher.add_shapes: if matcher.add_shapes:
current_set = matcher.add_shapes current_set = matcher.add_shapes
add() add()
@ -101,7 +110,7 @@ class IconCollection:
icon.recolor(color) icon.recolor(color)
icons.append(icon) icons.append(icon)
return cls(icons) return cls(icons, selectors)
def draw_icons( def draw_icons(
self, self,
@ -172,6 +181,21 @@ class IconCollection:
with file_name.open("w") as output_file: with file_name.open("w") as output_file:
svg.write(output_file) svg.write(output_file)
def get_mapcss_selectors(self) -> str:
"""
Construct MapCSS 0.2 style scheme.
"""
s = ""
for selector in self.selectors:
for target in ["node", "area"]:
s += target + selector + " {\n"
s += ' icon-image: "icon_set/josm/' + "___".join(
self.selectors[selector].get_shape_ids()) + '.svg";\n'
s += " set icon_z17;\n"
s += " icon-width: 16;\n"
s += "}\n"
return s
def __len__(self) -> int: def __len__(self) -> int:
return len(self.icons) return len(self.icons)

View file

@ -72,10 +72,9 @@ class Matcher:
Tag matching. Tag matching.
""" """
def __init__(self, structure: Dict[str, Any]): def __init__(self, structure: Dict[str, Any]):
self.tags = structure["tags"] self.tags: Dict[str, str] = structure["tags"]
self.exception = None
self.exception: Dict[str, str] = {}
if "exception" in structure: if "exception" in structure:
self.exception = structure["exception"] self.exception = structure["exception"]
@ -155,6 +154,14 @@ class NodeMatcher(Matcher):
if "with_icon" in structure: if "with_icon" in structure:
self.with_icon = structure["with_icon"] self.with_icon = structure["with_icon"]
def get_mapcss_selector(self) -> str:
"""
Construct MapCSS 0.2 selector from the node matcher.
See https://wiki.openstreetmap.org/wiki/MapCSS/0.2
"""
return "".join([f"[{x}={y}]" for (x, y) in self.tags.items()])
class WayMatcher(Matcher): class WayMatcher(Matcher):
""" """