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

View file

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

View file

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

View file

@ -22,7 +22,9 @@ class Label:
size: float = 10.0 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. 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 draw_captions_mode == "address":
if "addr:postcode" in tags: if "addr:postcode" in tags:
address.append(tags["addr:postcode"]) address.append(tags["addr:postcode"])
tags.pop("addr:postcode", None) processed.add("addr:postcode")
if "addr:country" in tags: if "addr:country" in tags:
address.append(tags["addr:country"]) address.append(tags["addr:country"])
tags.pop("addr:country", None) processed.add("addr:country")
if "addr:city" in tags: if "addr:city" in tags:
address.append(tags["addr:city"]) address.append(tags["addr:city"])
tags.pop("addr:city", None) processed.add("addr:city")
if "addr:street" in tags: if "addr:street" in tags:
street = tags["addr:street"] street = tags["addr:street"]
if street.startswith("улица "): if street.startswith("улица "):
street = "ул. " + street[len("улица "):] street = "ул. " + street[len("улица "):]
address.append(street) address.append(street)
tags.pop("addr:street", None) processed.add("addr:street")
if "addr:housenumber" in tags: if "addr:housenumber" in tags:
address.append(tags["addr:housenumber"]) address.append(tags["addr:housenumber"])
tags.pop("addr:housenumber", None) processed.add("addr:housenumber")
return address return address

View file

@ -2,7 +2,7 @@
Test icon generation for nodes. Test icon generation for nodes.
""" """
from pathlib import Path from pathlib import Path
from typing import Dict, Tuple from typing import Dict, Tuple, Set
import pytest import pytest
@ -48,7 +48,8 @@ def get_icon(tags: Dict[str, str]) -> IconSet:
""" """
Construct icon from tags. 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 return icon

View file

@ -1,7 +1,7 @@
""" """
Test label generation for nodes. Test label generation for nodes.
""" """
from typing import List from typing import List, Set
from roentgen.text import Label from roentgen.text import Label
from test import SCHEME from test import SCHEME
@ -14,7 +14,8 @@ def construct_labels(tags) -> List[Label]:
""" """
Construct labels from OSM node tags. 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: def test_1_label() -> None: