Fix tags processing.

This commit is contained in:
Sergey Vartanov 2021-06-26 23:42:41 +03:00
parent e31719eda7
commit eaa90663e9
6 changed files with 59 additions and 49 deletions

View file

@ -237,16 +237,19 @@ class Constructor:
and line.get_tag("area") != "no"
and self.scheme.is_area(line.tags)
):
processed: Set[str] = set()
priority: int
icon_set: IconSet
icon_set, priority = self.scheme.get_icon(
self.icon_extractor, line.tags, for_="line"
self.icon_extractor, line.tags, processed, for_="line"
)
labels = self.scheme.construct_text(line.tags, "all")
labels = self.scheme.construct_text(line.tags, "all", processed)
point: Point = Point(
icon_set,
labels,
line.tags,
processed,
center_point,
center_coordinates,
is_for_node=False,
@ -266,15 +269,17 @@ class Constructor:
)
self.figures.append(figure)
processed: Set[str] = set()
priority: int
icon_set: IconSet
icon_set, priority = self.scheme.get_icon(
self.icon_extractor, line.tags
self.icon_extractor, line.tags, processed
)
labels = self.scheme.construct_text(line.tags, "all")
labels = self.scheme.construct_text(line.tags, "all", processed)
point: Point = Point(
icon_set, labels, line.tags, center_point, center_coordinates,
is_for_node=False, priority=priority,
icon_set, labels, line.tags, processed, center_point,
center_coordinates, is_for_node=False, priority=priority,
) # fmt: skip
self.points.append(point)
@ -333,6 +338,8 @@ class Constructor:
missing_tags = Counter()
for node_id in sorted_node_ids: # type: int
processed: Set[str] = set()
node_number += 1
ui.progress_bar(
node_number, len(self.map_.nodes), text="Constructing nodes"
@ -365,12 +372,12 @@ class Constructor:
labels = []
else:
icon_set, priority = self.scheme.get_icon(
self.icon_extractor, tags
self.icon_extractor, tags, processed
)
labels = self.scheme.construct_text(tags, "all")
labels = self.scheme.construct_text(tags, "all", processed)
point: Point = Point(
icon_set, labels, tags, flung, node.coordinates,
priority=priority, draw_outline=draw_outline,
icon_set, labels, tags, processed, flung, node.coordinates,
priority=priority, draw_outline=draw_outline
) # fmt: skip
self.points.append(point)

View file

@ -1,7 +1,7 @@
"""
Point: node representation on the map.
"""
from typing import Dict, List, Optional
from typing import Dict, List, Optional, Set
import numpy as np
import svgwrite
@ -54,8 +54,8 @@ class Point(Tagged):
def __init__(
self, icon_set: IconSet, labels: List[Label], tags: Dict[str, str],
point: np.array, coordinates: np.array, priority: float = 0,
is_for_node: bool = True, draw_outline: bool = True
processed: Set[str], point: np.array, coordinates: np.array,
priority: float = 0, is_for_node: bool = True, draw_outline: bool = True
):
super().__init__()
@ -64,6 +64,7 @@ class Point(Tagged):
self.icon_set: IconSet = icon_set
self.labels: List[Label] = labels
self.tags: Dict[str, str] = tags
self.processed: Set[str] = processed
self.point: np.array = point
self.coordinates: np.array = coordinates
self.priority: float = priority
@ -80,9 +81,14 @@ class Point(Tagged):
"""
Draw main shape for one node.
"""
keys_left = [
x for x in self.tags.keys()
if x not in self.processed # and not self.is_no_drawable(x)
]
if (
self.icon_set.main_icon.is_default() and
not self.icon_set.extra_icons
self.icon_set.main_icon.is_default()
and not self.icon_set.extra_icons
and (not keys_left or not self.is_for_node)
):
return
@ -177,7 +183,7 @@ class Point(Tagged):
text = text.replace("&", '&')
text = text[:26] + ("..." if len(text) > 26 else "")
self.draw_text(
svg, text, self.point + np.array((0, self.y)),
svg, text, self.point + np.array((0, self.y + 2)),
occupied, label.fill, size=label.size
)
@ -197,8 +203,6 @@ class Point(Tagged):
#------#
######
"""
self.y += 2
length = len(text) * 6
if occupied:
@ -249,5 +253,5 @@ class Point(Tagged):
)
height: int = icon_size * (1 + int(len(self.icon_set.extra_icons) / 3))
if len(self.labels):
height += 2 + 11 * len(self.labels)
height += 4 + 11 * len(self.labels)
return np.array((width, height))

View file

@ -268,6 +268,7 @@ class Scheme:
self,
icon_extractor: ShapeExtractor,
tags: Dict[str, Any],
processed: Set[str],
for_: str = "node",
) -> Tuple[IconSet, int]:
"""
@ -276,6 +277,7 @@ class Scheme:
:param icon_extractor: extractor with icon specifications
:param tags: OpenStreetMap element tags dictionary
:param for_: target (node, way, area or relation)
:param processed: set of already processed tag keys
:return (icon set, icon priority)
"""
tags_hash: str = (
@ -286,7 +288,6 @@ class Scheme:
main_icon: Optional[Icon] = None
extra_icons: List[Icon] = []
processed: Set[str] = set()
priority: int = 0
index: int = 0
@ -388,7 +389,7 @@ class Scheme:
return None
def construct_text(
self, tags: Dict[str, str], draw_captions: str
self, tags: Dict[str, str], draw_captions: str, processed: Set[str]
) -> List[Label]:
"""
Construct labels for not processed tags.
@ -399,24 +400,19 @@ class Scheme:
alt_name = None
if "name" in tags:
name = tags["name"]
tags.pop("name", None)
if "name:ru" in tags:
if not name:
name = tags["name:ru"]
tags.pop("name:ru", None)
tags.pop("name:ru", None)
if "name:en" in tags:
processed.add("name")
elif "name:en" in tags:
if not name:
name = tags["name:en"]
tags.pop("name:en", None)
tags.pop("name:en", None)
processed.add("name:en")
processed.add("name:en")
if "alt_name" in tags:
if alt_name:
alt_name += ", "
else:
alt_name = ""
alt_name += tags["alt_name"]
tags.pop("alt_name")
processed.add("alt_name")
if "old_name" in tags:
if alt_name:
alt_name += ", "
@ -424,7 +420,7 @@ class Scheme:
alt_name = ""
alt_name += "ex " + tags["old_name"]
address: List[str] = get_address(tags, draw_captions)
address: List[str] = get_address(tags, draw_captions, processed)
if name:
texts.append(Label(name, Color("black")))
@ -436,15 +432,14 @@ class Scheme:
if draw_captions == "main":
return texts
processed: Set[str] = set()
texts += get_text(tags, processed)
if "route_ref" in tags:
texts.append(Label(tags["route_ref"].replace(";", " ")))
tags.pop("route_ref", None)
processed.add("route_ref")
if "cladr:code" in tags:
texts.append(Label(tags["cladr:code"], size=7))
tags.pop("cladr:code", None)
processed.add("cladr:code")
if "website" in tags:
link = tags["website"]
if link[:7] == "http://":
@ -457,16 +452,16 @@ class Scheme:
link = link[:-1]
link = link[:25] + ("..." if len(tags["website"]) > 25 else "")
texts.append(Label(link, Color("#000088")))
tags.pop("website", None)
processed.add("website")
for key in ["phone"]:
if key in tags:
texts.append(Label(tags[key], Color("#444444")))
tags.pop(key)
processed.add(key)
if "height" in tags:
texts.append(Label(f"{tags['height']} m"))
tags.pop("height")
processed.add("height")
for tag in tags:
if self.is_writable(tag):
if self.is_writable(tag) and tag not in processed:
texts.append(Label(tags[tag]))
return texts

View file

@ -22,7 +22,9 @@ class Label:
size: float = 10.0
def get_address(tags: Dict[str, Any], draw_captions_mode: str) -> List[str]:
def get_address(
tags: Dict[str, Any], draw_captions_mode: str, processed: Set[str]
) -> List[str]:
"""
Construct address text list from the tags.
@ -34,23 +36,23 @@ def get_address(tags: Dict[str, Any], draw_captions_mode: str) -> List[str]:
if draw_captions_mode == "address":
if "addr:postcode" in tags:
address.append(tags["addr:postcode"])
tags.pop("addr:postcode", None)
processed.add("addr:postcode")
if "addr:country" in tags:
address.append(tags["addr:country"])
tags.pop("addr:country", None)
processed.add("addr:country")
if "addr:city" in tags:
address.append(tags["addr:city"])
tags.pop("addr:city", None)
processed.add("addr:city")
if "addr:street" in tags:
street = tags["addr:street"]
if street.startswith("улица "):
street = "ул. " + street[len("улица "):]
address.append(street)
tags.pop("addr:street", None)
processed.add("addr:street")
if "addr:housenumber" in tags:
address.append(tags["addr:housenumber"])
tags.pop("addr:housenumber", None)
processed.add("addr:housenumber")
return address

View file

@ -2,7 +2,7 @@
Test icon generation for nodes.
"""
from pathlib import Path
from typing import Dict, Tuple
from typing import Dict, Tuple, Set
import pytest
@ -48,7 +48,8 @@ def get_icon(tags: Dict[str, str]) -> IconSet:
"""
Construct icon from tags.
"""
icon, _ = SCHEME.get_icon(SHAPE_EXTRACTOR, tags)
processed: Set[str] = set()
icon, _ = SCHEME.get_icon(SHAPE_EXTRACTOR, tags, processed)
return icon

View file

@ -1,7 +1,7 @@
"""
Test label generation for nodes.
"""
from typing import List
from typing import List, Set
from roentgen.text import Label
from test import SCHEME
@ -14,7 +14,8 @@ def construct_labels(tags) -> List[Label]:
"""
Construct labels from OSM node tags.
"""
return SCHEME.construct_text(tags, "all")
processed: Set[str] = set()
return SCHEME.construct_text(tags, "all", processed)
def test_1_label() -> None: