mirror of
https://github.com/enzet/map-machine.git
synced 2025-06-05 04:12:08 +02:00
Fix some Pylint warnings.
This commit is contained in:
parent
1cadabd173
commit
310a631217
9 changed files with 84 additions and 67 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
"""
|
||||||
|
Röntgen project: simple Python map renderer for OpenStreetMap and icon set.
|
||||||
|
"""
|
||||||
|
|
||||||
__url__ = "https://github.com/enzet/Roentgen"
|
__url__ = "https://github.com/enzet/Roentgen"
|
||||||
__maintainer__ = "Sergey Vartanov"
|
__maintainer__ = "Sergey Vartanov"
|
||||||
__maintainer_email__ = "me@enzet.ru"
|
__maintainer_email__ = "me@enzet.ru"
|
||||||
|
|
|
@ -14,14 +14,13 @@ from colour import Color
|
||||||
from roentgen import ui
|
from roentgen import ui
|
||||||
from roentgen.color import get_gradient_color
|
from roentgen.color import get_gradient_color
|
||||||
from roentgen.flinger import Flinger
|
from roentgen.flinger import Flinger
|
||||||
from roentgen.icon import (
|
from roentgen.icon import (DEFAULT_SMALL_SHAPE_ID, Icon, IconSet,
|
||||||
DEFAULT_SMALL_SHAPE_ID, ShapeExtractor, Icon, IconSet, ShapeSpecification
|
ShapeExtractor, ShapeSpecification)
|
||||||
)
|
|
||||||
from roentgen.osm_reader import (
|
from roentgen.osm_reader import (
|
||||||
Map, OSMMember, OSMNode, OSMRelation, OSMWay, Tagged
|
Map, OSMMember, OSMNode, OSMRelation, OSMWay, Tagged
|
||||||
)
|
)
|
||||||
from roentgen.point import Point
|
from roentgen.point import Point
|
||||||
from roentgen.scheme import LineStyle, Scheme, DEFAULT_COLOR
|
from roentgen.scheme import DEFAULT_COLOR, LineStyle, Scheme
|
||||||
from roentgen.util import MinMax
|
from roentgen.util import MinMax
|
||||||
|
|
||||||
DEBUG: bool = False
|
DEBUG: bool = False
|
||||||
|
@ -372,8 +371,8 @@ class Constructor:
|
||||||
labels = self.scheme.construct_text(line.tags, True)
|
labels = self.scheme.construct_text(line.tags, True)
|
||||||
|
|
||||||
self.nodes.append(Point(
|
self.nodes.append(Point(
|
||||||
icon_set, labels, line.tags, center_point, center_coordinates,
|
icon_set, labels, line.tags, center_point,
|
||||||
is_for_node=False, priority=priority
|
center_coordinates, is_for_node=False, priority=priority
|
||||||
))
|
))
|
||||||
|
|
||||||
if not line_styles:
|
if not line_styles:
|
||||||
|
|
|
@ -10,7 +10,7 @@ import numpy as np
|
||||||
from colour import Color
|
from colour import Color
|
||||||
from svgwrite import Drawing
|
from svgwrite import Drawing
|
||||||
|
|
||||||
from roentgen.icon import ShapeExtractor, Shape, Icon, ShapeSpecification
|
from roentgen.icon import Icon, ShapeExtractor, ShapeSpecification
|
||||||
from roentgen.scheme import Scheme
|
from roentgen.scheme import Scheme
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,15 +38,18 @@ def draw_all_icons(
|
||||||
icons_file_name: str = "icons/icons.svg"
|
icons_file_name: str = "icons/icons.svg"
|
||||||
extractor: ShapeExtractor = ShapeExtractor(icons_file_name)
|
extractor: ShapeExtractor = ShapeExtractor(icons_file_name)
|
||||||
|
|
||||||
def add():
|
def add() -> None:
|
||||||
|
"""
|
||||||
|
Construct icon and add it to the list.
|
||||||
|
"""
|
||||||
specifications = [
|
specifications = [
|
||||||
ShapeSpecification.from_structure(x, extractor, scheme)
|
ShapeSpecification.from_structure(x, extractor, scheme)
|
||||||
for x in current_set
|
for x in current_set
|
||||||
]
|
]
|
||||||
icon: Icon = Icon(specifications)
|
constructed_icon: Icon = Icon(specifications)
|
||||||
icon.recolor(color, white=background_color)
|
constructed_icon.recolor(color, white=background_color)
|
||||||
if icon not in icons:
|
if constructed_icon not in icons:
|
||||||
icons.append(icon)
|
icons.append(constructed_icon)
|
||||||
|
|
||||||
for element in scheme.icons: # type: Dict[str, Any]
|
for element in scheme.icons: # type: Dict[str, Any]
|
||||||
for key in ["icon", "add_icon"]:
|
for key in ["icon", "add_icon"]:
|
||||||
|
@ -91,13 +94,13 @@ def draw_all_icons(
|
||||||
|
|
||||||
draw_grid(
|
draw_grid(
|
||||||
output_file_name, icons, columns, step,
|
output_file_name, icons, columns, step,
|
||||||
background_color=background_color, color=color
|
background_color=background_color
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def draw_grid(
|
def draw_grid(
|
||||||
file_name: str, icons: List[Icon], columns: int = 16, step: float = 24,
|
file_name: str, icons: List[Icon], columns: int = 16, step: float = 24,
|
||||||
background_color: Color = Color("white"), color: Color = Color("black")
|
background_color: Color = Color("white")
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Draw icons in the form of table
|
Draw icons in the form of table
|
||||||
|
@ -107,7 +110,6 @@ def draw_grid(
|
||||||
:param columns: number of columns in grid
|
:param columns: number of columns in grid
|
||||||
:param step: horizontal and vertical distance between icons in grid
|
:param step: horizontal and vertical distance between icons in grid
|
||||||
:param background_color: background color
|
:param background_color: background color
|
||||||
:param color: foreground color
|
|
||||||
"""
|
"""
|
||||||
point: np.array = np.array((step / 2, step / 2))
|
point: np.array = np.array((step / 2, step / 2))
|
||||||
width: float = step * columns
|
width: float = step * columns
|
||||||
|
@ -133,4 +135,3 @@ def draw_grid(
|
||||||
|
|
||||||
with open(file_name, "w") as output_file:
|
with open(file_name, "w") as output_file:
|
||||||
svg.write(output_file)
|
svg.write(output_file)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ Author: Sergey Vartanov (me@enzet.ru).
|
||||||
"""
|
"""
|
||||||
import re
|
import re
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Dict, Optional, List, Set, Any
|
from typing import Any, Dict, List, Optional, Set
|
||||||
from xml.dom.minidom import Document, Element, Node, parse
|
from xml.dom.minidom import Document, Element, Node, parse
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
@ -140,6 +140,8 @@ class ShapeExtractor:
|
||||||
if id_ in self.shapes:
|
if id_ in self.shapes:
|
||||||
return self.shapes[id_]
|
return self.shapes[id_]
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ShapeSpecification:
|
class ShapeSpecification:
|
||||||
|
@ -153,7 +155,7 @@ class ShapeSpecification:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_structure(
|
def from_structure(
|
||||||
cls, structure: Any, extractor: ShapeExtractor, scheme: "Scheme",
|
cls, structure: Any, extractor: ShapeExtractor, scheme,
|
||||||
color: Color = DEFAULT_COLOR
|
color: Color = DEFAULT_COLOR
|
||||||
) -> "ShapeSpecification":
|
) -> "ShapeSpecification":
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -13,7 +13,7 @@ from svgwrite.path import Path
|
||||||
from svgwrite.shapes import Rect
|
from svgwrite.shapes import Rect
|
||||||
|
|
||||||
from roentgen import ui
|
from roentgen import ui
|
||||||
from roentgen.constructor import Building, Constructor, Figure, Segment
|
from roentgen.constructor import Building, Constructor, Segment
|
||||||
from roentgen.direction import DirectionSet, Sector
|
from roentgen.direction import DirectionSet, Sector
|
||||||
from roentgen.flinger import Flinger
|
from roentgen.flinger import Flinger
|
||||||
from roentgen.icon import ShapeExtractor
|
from roentgen.icon import ShapeExtractor
|
||||||
|
@ -35,11 +35,11 @@ class Painter:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, map_: Map, flinger: Flinger,
|
self, map_: Map, flinger: Flinger,
|
||||||
svg: svgwrite.Drawing, icon_extractor: ShapeExtractor,
|
svg: svgwrite.Drawing, icon_extractor: ShapeExtractor,
|
||||||
scheme: Scheme, show_missing_tags: bool = False, overlap: int = 12,
|
scheme: Scheme, show_missing_tags: bool = False, overlap: int = 12,
|
||||||
mode: str = "normal", draw_captions: str = "main"):
|
mode: str = "normal", draw_captions: str = "main"
|
||||||
|
):
|
||||||
self.show_missing_tags: bool = show_missing_tags
|
self.show_missing_tags: bool = show_missing_tags
|
||||||
self.overlap: int = overlap
|
self.overlap: int = overlap
|
||||||
self.mode: str = mode
|
self.mode: str = mode
|
||||||
|
@ -55,7 +55,7 @@ class Painter:
|
||||||
if self.mode in [AUTHOR_MODE, CREATION_TIME_MODE]:
|
if self.mode in [AUTHOR_MODE, CREATION_TIME_MODE]:
|
||||||
self.background_color: Color = Color("#111111")
|
self.background_color: Color = Color("#111111")
|
||||||
|
|
||||||
def draw(self, constructor: Constructor):
|
def draw(self, constructor: Constructor) -> None:
|
||||||
"""
|
"""
|
||||||
Draw map.
|
Draw map.
|
||||||
"""
|
"""
|
||||||
|
@ -64,7 +64,7 @@ class Painter:
|
||||||
|
|
||||||
ways = sorted(constructor.figures, key=lambda x: x.line_style.priority)
|
ways = sorted(constructor.figures, key=lambda x: x.line_style.priority)
|
||||||
ways_length: int = len(ways)
|
ways_length: int = len(ways)
|
||||||
for index, way in enumerate(ways): # type: Figure
|
for index, way in enumerate(ways):
|
||||||
ui.progress_bar(index, ways_length, step=10, text="Drawing ways")
|
ui.progress_bar(index, ways_length, step=10, text="Drawing ways")
|
||||||
path_commands: str = way.get_path(self.flinger)
|
path_commands: str = way.get_path(self.flinger)
|
||||||
if path_commands:
|
if path_commands:
|
||||||
|
|
|
@ -74,7 +74,11 @@ class OSMNode(Tagged):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def parse_from_structure(self, structure: Dict[str, Any]) -> "OSMNode":
|
def parse_from_structure(self, structure: Dict[str, Any]) -> "OSMNode":
|
||||||
|
"""
|
||||||
|
Parse node from Overpass-like structure.
|
||||||
|
|
||||||
|
:param structure: input structure
|
||||||
|
"""
|
||||||
self.id_ = structure["id"]
|
self.id_ = structure["id"]
|
||||||
self.coordinates = np.array((structure["lat"], structure["lon"]))
|
self.coordinates = np.array((structure["lat"], structure["lon"]))
|
||||||
if "tags" in structure:
|
if "tags" in structure:
|
||||||
|
@ -190,7 +194,11 @@ class OSMRelation(Tagged):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def parse_from_structure(self, structure: Dict[str, Any]) -> "OSMRelation":
|
def parse_from_structure(self, structure: Dict[str, Any]) -> "OSMRelation":
|
||||||
|
"""
|
||||||
|
Parse relation from Overpass-like structure.
|
||||||
|
|
||||||
|
:param structure: input structure
|
||||||
|
"""
|
||||||
self.id_ = structure["id"]
|
self.id_ = structure["id"]
|
||||||
for member in structure["members"]:
|
for member in structure["members"]:
|
||||||
mem = OSMMember()
|
mem = OSMMember()
|
||||||
|
@ -214,6 +222,11 @@ class OSMMember:
|
||||||
self.role = ""
|
self.role = ""
|
||||||
|
|
||||||
def parse_from_xml(self, text: str) -> "OSMMember":
|
def parse_from_xml(self, text: str) -> "OSMMember":
|
||||||
|
"""
|
||||||
|
Parse relation member from XML way representation.
|
||||||
|
|
||||||
|
:param text: XML relation member representation
|
||||||
|
"""
|
||||||
self.type_: str = get_value("type", text)
|
self.type_: str = get_value("type", text)
|
||||||
self.ref: int = int(get_value("ref", text))
|
self.ref: int = int(get_value("ref", text))
|
||||||
self.role: str = get_value("role", text)
|
self.role: str = get_value("role", text)
|
||||||
|
@ -275,10 +288,18 @@ class Map:
|
||||||
|
|
||||||
|
|
||||||
class OverpassReader:
|
class OverpassReader:
|
||||||
|
"""
|
||||||
|
Reader for JSON structure extracted from Overpass API.
|
||||||
|
|
||||||
|
See https://wiki.openstreetmap.org/wiki/Overpass_API
|
||||||
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.map_ = Map()
|
self.map_ = Map()
|
||||||
|
|
||||||
def parse_json_file(self, file_name: str) -> Map:
|
def parse_json_file(self, file_name: str) -> Map:
|
||||||
|
"""
|
||||||
|
Parse JSON structure from the file and construct map.
|
||||||
|
"""
|
||||||
with open(file_name) as input_file:
|
with open(file_name) as input_file:
|
||||||
structure = json.load(input_file)
|
structure = json.load(input_file)
|
||||||
|
|
||||||
|
@ -311,13 +332,14 @@ class OSMReader:
|
||||||
self.map_ = Map()
|
self.map_ = Map()
|
||||||
|
|
||||||
def parse_osm_file(
|
def parse_osm_file(
|
||||||
self, file_name: str, parse_nodes: bool = True,
|
self, file_name: str, parse_nodes: bool = True,
|
||||||
parse_ways: bool = True, parse_relations: bool = True,
|
parse_ways: bool = True, parse_relations: bool = True,
|
||||||
full: bool = False) -> Map:
|
full: bool = False
|
||||||
|
) -> Map:
|
||||||
"""
|
"""
|
||||||
Parse OSM XML representation.
|
Parse OSM XML representation.
|
||||||
|
|
||||||
:param file_name input OSM XML file name
|
:param file_name: input OSM XML file name
|
||||||
"""
|
"""
|
||||||
with open(file_name) as input_file:
|
with open(file_name) as input_file:
|
||||||
lines_number: int = sum(1 for _ in input_file)
|
lines_number: int = sum(1 for _ in input_file)
|
||||||
|
|
|
@ -10,10 +10,8 @@ from typing import Any, Dict, List, Optional, Set, Tuple, Union
|
||||||
import yaml
|
import yaml
|
||||||
from colour import Color
|
from colour import Color
|
||||||
|
|
||||||
from roentgen.icon import (
|
from roentgen.icon import (DEFAULT_COLOR, DEFAULT_SHAPE_ID, Icon, IconSet,
|
||||||
IconSet, ShapeSpecification, DEFAULT_SHAPE_ID, ShapeExtractor,
|
ShapeExtractor, ShapeSpecification)
|
||||||
DEFAULT_COLOR,
|
|
||||||
Icon)
|
|
||||||
from roentgen.text import Label, get_address, get_text
|
from roentgen.text import Label, get_address, get_text
|
||||||
|
|
||||||
|
|
||||||
|
@ -163,9 +161,9 @@ class Scheme:
|
||||||
|
|
||||||
:param key: OpenStreetMap tag key
|
:param key: OpenStreetMap tag key
|
||||||
"""
|
"""
|
||||||
if key in self.tags_to_skip: # type: str
|
if key in self.tags_to_skip:
|
||||||
return False
|
return False
|
||||||
if key in self.tags_to_write: # type: str
|
if key in self.tags_to_write:
|
||||||
return True
|
return True
|
||||||
for prefix in self.prefix_to_write: # type: str
|
for prefix in self.prefix_to_write: # type: str
|
||||||
if key[:len(prefix) + 1] == f"{prefix}:":
|
if key[:len(prefix) + 1] == f"{prefix}:":
|
||||||
|
@ -265,7 +263,9 @@ class Scheme:
|
||||||
return returned, priority
|
return returned, priority
|
||||||
|
|
||||||
def get_style(self, tags: Dict[str, Any], scale):
|
def get_style(self, tags: Dict[str, Any], scale):
|
||||||
|
"""
|
||||||
|
Get line style based on tags and scale.
|
||||||
|
"""
|
||||||
line_styles = []
|
line_styles = []
|
||||||
|
|
||||||
for element in self.ways: # type: Dict[str, Any]
|
for element in self.ways: # type: Dict[str, Any]
|
||||||
|
@ -366,10 +366,10 @@ class Scheme:
|
||||||
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)
|
tags.pop("website", None)
|
||||||
for k in ["phone"]:
|
for key in ["phone"]:
|
||||||
if k in tags:
|
if key in tags:
|
||||||
texts.append(Label(tags[k], Color("#444444")))
|
texts.append(Label(tags[key], Color("#444444")))
|
||||||
tags.pop(k)
|
tags.pop(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")
|
tags.pop("height")
|
||||||
|
@ -379,6 +379,9 @@ class Scheme:
|
||||||
return texts
|
return texts
|
||||||
|
|
||||||
def is_area(self, tags: Dict[str, str]) -> bool:
|
def is_area(self, tags: Dict[str, str]) -> bool:
|
||||||
|
"""
|
||||||
|
Check whether way described by tags is area.
|
||||||
|
"""
|
||||||
for matcher in self.area_tags:
|
for matcher in self.area_tags:
|
||||||
if is_matched(matcher, tags):
|
if is_matched(matcher, tags):
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -70,15 +70,19 @@ def format_voltage(value: str) -> str:
|
||||||
|
|
||||||
|
|
||||||
def format_frequency(value: str) -> str:
|
def format_frequency(value: str) -> str:
|
||||||
|
"""
|
||||||
|
Format frequency value to more human-readable form.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
int_value: int = int(value)
|
|
||||||
return f"{value} Hz"
|
return f"{value} Hz"
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def get_text(tags: Dict[str, Any]) -> List[str]:
|
def get_text(tags: Dict[str, Any]) -> List[str]:
|
||||||
|
"""
|
||||||
|
Get text representation of writable tags.
|
||||||
|
"""
|
||||||
texts: List[str] = []
|
texts: List[str] = []
|
||||||
|
|
||||||
values: List[str] = []
|
values: List[str] = []
|
||||||
|
@ -92,6 +96,7 @@ def get_text(tags: Dict[str, Any]) -> List[str]:
|
||||||
|
|
||||||
if "frequency" in tags:
|
if "frequency" in tags:
|
||||||
texts.append(", ".join(map(
|
texts.append(", ".join(map(
|
||||||
format_frequency, tags["frequency"].split(";"))))
|
format_frequency, tags["frequency"].split(";")
|
||||||
|
)))
|
||||||
|
|
||||||
return texts
|
return texts
|
||||||
|
|
|
@ -76,29 +76,9 @@ def parse_options(args) -> argparse.Namespace:
|
||||||
return arguments
|
return arguments
|
||||||
|
|
||||||
|
|
||||||
def progress_bar1(
|
|
||||||
number: int, total: int, length: int = 20, step: int = 1000) -> None:
|
|
||||||
"""
|
|
||||||
Draw progress bar using Unicode symbols.
|
|
||||||
|
|
||||||
:param number: current value
|
|
||||||
:param total: maximum value
|
|
||||||
:param length: progress bar length.
|
|
||||||
:param step: frequency of progress bar updating (assuming that numbers go
|
|
||||||
subsequently)
|
|
||||||
:param text: short description
|
|
||||||
"""
|
|
||||||
ratio: float = number / total
|
|
||||||
parts: int = int(ratio * length * BOXES_LENGTH)
|
|
||||||
fill_length: int = int(parts / BOXES_LENGTH)
|
|
||||||
box: str = BOXES[int(parts - fill_length * BOXES_LENGTH)]
|
|
||||||
return (
|
|
||||||
f"{fill_length * '█'}{box}{int(length - fill_length - 1) * ' '}")
|
|
||||||
|
|
||||||
|
|
||||||
def progress_bar(
|
def progress_bar(
|
||||||
number: int, total: int, length: int = 20, step: int = 1000,
|
number: int, total: int, length: int = 20, step: int = 1000, text: str = ""
|
||||||
text: str = "") -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Draw progress bar using Unicode symbols.
|
Draw progress bar using Unicode symbols.
|
||||||
|
|
||||||
|
@ -118,7 +98,8 @@ def progress_bar(
|
||||||
box: str = BOXES[int(parts - fill_length * BOXES_LENGTH)]
|
box: str = BOXES[int(parts - fill_length * BOXES_LENGTH)]
|
||||||
print(
|
print(
|
||||||
f"{str(int(int(ratio * 1000) / 10)):>3} % {fill_length * '█'}{box}"
|
f"{str(int(int(ratio * 1000) / 10)):>3} % {fill_length * '█'}{box}"
|
||||||
f"{int(length - fill_length - 1) * ' '}▏{text}")
|
f"{int(length - fill_length - 1) * ' '}▏{text}"
|
||||||
|
)
|
||||||
sys.stdout.write("\033[F")
|
sys.stdout.write("\033[F")
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue