Change scheme format; support pathlib.
Change name documentation as well.
6
.gitignore
vendored
|
@ -22,8 +22,10 @@ missed_tags.yml
|
|||
|
||||
# Cache
|
||||
|
||||
map/ # OSM XML files
|
||||
cache/
|
||||
map/
|
||||
|
||||
# Generated files
|
||||
|
||||
icon_set/ # Generated SVG icon files
|
||||
icon_set/
|
||||
out/
|
||||
|
|
BIN
doc/grid.png
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
BIN
doc/power.png
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 652 B |
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 144 KiB |
BIN
doc/trees.png
Before Width: | Height: | Size: 167 KiB After Width: | Height: | Size: 169 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
43
roentgen.py
|
@ -7,6 +7,7 @@ import argparse
|
|||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
import numpy as np
|
||||
import svgwrite
|
||||
|
@ -15,7 +16,7 @@ from roentgen import ui
|
|||
from roentgen.constructor import Constructor
|
||||
from roentgen.flinger import Flinger
|
||||
from roentgen.grid import draw_all_icons
|
||||
from roentgen.icon import ShapeExtractor, ShapeConfiguration
|
||||
from roentgen.icon import ShapeExtractor
|
||||
from roentgen.mapper import (
|
||||
AUTHOR_MODE, CREATION_TIME_MODE, ICONS_FILE_NAME, Painter, TAGS_FILE_NAME,
|
||||
check_level_number, check_level_overground
|
||||
|
@ -38,22 +39,26 @@ def main(argv) -> None:
|
|||
if not options:
|
||||
sys.exit(1)
|
||||
|
||||
input_file_names: List[Path]
|
||||
|
||||
if options.input_file_name:
|
||||
input_file_name = options.input_file_name
|
||||
input_file_names = list(map(Path, options.input_file_name))
|
||||
else:
|
||||
content = get_osm(options.boundary_box)
|
||||
if not content:
|
||||
ui.error("cannot download OSM data")
|
||||
input_file_name = [os.path.join("map", options.boundary_box + ".osm")]
|
||||
input_file_names = ["map" / Path(options.boundary_box + ".osm")]
|
||||
|
||||
scheme: Scheme = Scheme(TAGS_FILE_NAME)
|
||||
scheme: Scheme = Scheme(Path(TAGS_FILE_NAME))
|
||||
min_: np.array
|
||||
max_: np.array
|
||||
|
||||
if input_file_name[0].endswith(".json"):
|
||||
if input_file_names[0].name.endswith(".json"):
|
||||
reader: OverpassReader = OverpassReader()
|
||||
reader.parse_json_file(input_file_name[0])
|
||||
reader.parse_json_file(input_file_names[0])
|
||||
map_ = reader.map_
|
||||
min1 = np.array((map_.boundary_box[0].min_, map_.boundary_box[1].min_))
|
||||
max1 = np.array((map_.boundary_box[0].max_, map_.boundary_box[1].max_))
|
||||
min_ = np.array((map_.boundary_box[0].min_, map_.boundary_box[1].min_))
|
||||
max_ = np.array((map_.boundary_box[0].max_, map_.boundary_box[1].max_))
|
||||
else:
|
||||
|
||||
boundary_box = list(map(float, options.boundary_box.split(',')))
|
||||
|
@ -65,19 +70,19 @@ def main(argv) -> None:
|
|||
|
||||
osm_reader = OSMReader()
|
||||
|
||||
for file_name in input_file_name:
|
||||
if not os.path.isfile(file_name):
|
||||
print("Fatal: no such file: " + file_name + ".")
|
||||
for file_name in input_file_names:
|
||||
if not file_name.is_file():
|
||||
print(f"Fatal: no such file: {file_name}.")
|
||||
sys.exit(1)
|
||||
|
||||
osm_reader.parse_osm_file(file_name, full=full)
|
||||
|
||||
map_: Map = osm_reader.map_
|
||||
|
||||
min1: np.array = np.array((boundary_box[1], boundary_box[0]))
|
||||
max1: np.array = np.array((boundary_box[3], boundary_box[2]))
|
||||
min_ = np.array((boundary_box[1], boundary_box[0]))
|
||||
max_ = np.array((boundary_box[3], boundary_box[2]))
|
||||
|
||||
flinger: Flinger = Flinger(MinMax(min1, max1), options.scale)
|
||||
flinger: Flinger = Flinger(MinMax(min_, max_), options.scale)
|
||||
size: np.array = flinger.size
|
||||
|
||||
svg: svgwrite.Drawing = (
|
||||
|
@ -130,11 +135,13 @@ def draw_element(target: str, tags_description: str):
|
|||
comma, key from value is separated by equals sign.
|
||||
"""
|
||||
tags = dict([x.split("=") for x in tags_description.split(",")])
|
||||
scheme = Scheme("scheme/default.yml")
|
||||
extractor = ShapeExtractor("icons/icons.svg", Path("icons/config.json"))
|
||||
scheme = Scheme(Path("scheme/default.yml"))
|
||||
extractor = ShapeExtractor(
|
||||
Path("icons/icons.svg"), Path("icons/config.json")
|
||||
)
|
||||
icon, priority = scheme.get_icon(extractor, tags)
|
||||
is_for_node: bool = target == "node"
|
||||
labels = scheme.construct_text(tags, True)
|
||||
labels = scheme.construct_text(tags, "all")
|
||||
point = Point(
|
||||
icon, labels, tags, np.array((32, 32)), None, is_for_node=is_for_node,
|
||||
draw_outline=is_for_node
|
||||
|
@ -154,7 +161,7 @@ def draw_element(target: str, tags_description: str):
|
|||
svg.write(open("test_icon.svg", "w+"))
|
||||
|
||||
|
||||
def draw_grid():
|
||||
def draw_grid() -> None:
|
||||
"""
|
||||
Draw all possible icon shapes combinations as grid.
|
||||
"""
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
Color utility.
|
||||
|
||||
Author: Sergey Vartanov (me@enzet.ru)
|
||||
"""
|
||||
from typing import Any, List
|
||||
|
||||
|
@ -9,6 +7,9 @@ from colour import Color
|
|||
|
||||
from roentgen.util import MinMax
|
||||
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
|
||||
def is_bright(color: Color) -> bool:
|
||||
"""
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
Construct Röntgen nodes and ways.
|
||||
|
||||
Author: Sergey Vartanov (me@enzet.ru).
|
||||
"""
|
||||
from collections import Counter
|
||||
from datetime import datetime
|
||||
|
@ -23,6 +21,9 @@ from roentgen.point import Point
|
|||
from roentgen.scheme import DEFAULT_COLOR, LineStyle, Scheme
|
||||
from roentgen.util import MinMax
|
||||
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
DEBUG: bool = False
|
||||
TIME_COLOR_SCALE: List[Color] = [
|
||||
Color("#581845"), Color("#900C3F"), Color("#C70039"), Color("#FF5733"),
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
"""
|
||||
Direction tag support.
|
||||
|
||||
Author: Sergey Vartanov (me@enzet.ru).
|
||||
"""
|
||||
from typing import Iterator, List, Optional, Union
|
||||
|
||||
import numpy as np
|
||||
from portolan import middle
|
||||
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
SVGPath = Union[float, str, np.array]
|
||||
|
||||
SHIFT: float = -np.pi / 2
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""
|
||||
Author: Sergey Vartanov (me@enzet.ru)
|
||||
|
||||
Geo projection.
|
||||
"""
|
||||
from typing import Optional
|
||||
|
@ -9,6 +7,9 @@ import numpy as np
|
|||
|
||||
from roentgen.util import MinMax
|
||||
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
EQUATOR_LENGTH: float = 40_075_017 # (in meters)
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
Icon grid drawing.
|
||||
|
||||
Author: Sergey Vartanov (me@enzet.ru).
|
||||
"""
|
||||
from os.path import join
|
||||
from pathlib import Path
|
||||
|
@ -14,6 +12,9 @@ from svgwrite import Drawing
|
|||
from roentgen.icon import Icon, ShapeExtractor, ShapeSpecification
|
||||
from roentgen.scheme import Scheme
|
||||
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
|
||||
def draw_all_icons(
|
||||
output_file_name: str, output_directory: str, columns: int = 16,
|
||||
|
@ -31,14 +32,13 @@ def draw_all_icons(
|
|||
:param background_color: background color
|
||||
:param color: icon color
|
||||
"""
|
||||
tags_file_name: str = "scheme/default.yml"
|
||||
scheme: Scheme = Scheme(tags_file_name)
|
||||
scheme: Scheme = Scheme(Path("scheme/default.yml"))
|
||||
|
||||
icons: List[Icon] = []
|
||||
|
||||
icons_file_name: str = "icons/icons.svg"
|
||||
extractor: ShapeExtractor = ShapeExtractor(
|
||||
icons_file_name, Path("icons/config.json")
|
||||
Path(icons_file_name), Path("icons/config.json")
|
||||
)
|
||||
|
||||
def add() -> None:
|
||||
|
@ -54,7 +54,8 @@ def draw_all_icons(
|
|||
if constructed_icon not in icons:
|
||||
icons.append(constructed_icon)
|
||||
|
||||
for element in scheme.icons: # type: Dict[str, Any]
|
||||
for group in scheme.icons:
|
||||
for element in group["tags"]: # type: Dict[str, Any]
|
||||
for key in ["icon", "add_icon"]:
|
||||
if key in element:
|
||||
current_set = element[key]
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
Extract icons from SVG file.
|
||||
|
||||
Author: Sergey Vartanov (me@enzet.ru).
|
||||
"""
|
||||
import json
|
||||
import re
|
||||
|
@ -19,6 +17,9 @@ from svgwrite.path import Path as SvgPath
|
|||
from roentgen.color import is_bright
|
||||
from roentgen.ui import error
|
||||
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
DEFAULT_COLOR: Color = Color("#444444")
|
||||
DEFAULT_SHAPE_ID: str = "default"
|
||||
DEFAULT_SMALL_SHAPE_ID: str = "default_small"
|
||||
|
@ -94,7 +95,7 @@ class ShapeExtractor:
|
|||
Shape is a single path with "id" attribute that aligned to 16×16 grid.
|
||||
"""
|
||||
|
||||
def __init__(self, svg_file_name: str, configuration_file_name: Path):
|
||||
def __init__(self, svg_file_name: Path, configuration_file_name: Path):
|
||||
"""
|
||||
:param svg_file_name: input SVG file name with icons. File may contain
|
||||
any other irrelevant graphics.
|
||||
|
@ -102,7 +103,7 @@ class ShapeExtractor:
|
|||
self.configuration = ShapeConfiguration(configuration_file_name)
|
||||
self.shapes: Dict[str, Shape] = {}
|
||||
|
||||
with open(svg_file_name) as input_file:
|
||||
with svg_file_name.open() as input_file:
|
||||
content: Document = parse(input_file)
|
||||
for element in content.childNodes: # type: Element
|
||||
if element.nodeName != "svg":
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
Simple OpenStreetMap renderer.
|
||||
|
||||
Author: Sergey Vartanov (me@enzet.ru).
|
||||
"""
|
||||
from typing import Any, Dict
|
||||
|
||||
|
@ -21,6 +19,9 @@ from roentgen.osm_reader import Map
|
|||
from roentgen.point import Occupied, Point
|
||||
from roentgen.scheme import Scheme
|
||||
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
ICONS_FILE_NAME: str = "icons/icons.svg"
|
||||
TAGS_FILE_NAME: str = "scheme/default.yml"
|
||||
MISSING_TAGS_FILE_NAME: str = "missing_tags.yml"
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
"""
|
||||
Getting OpenStreetMap data from the web.
|
||||
|
||||
Author: Sergey Vartanov (me@enzet.ru).
|
||||
"""
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import urllib
|
||||
from pathlib import Path
|
||||
from typing import Dict, Optional
|
||||
|
||||
import urllib3
|
||||
|
||||
from roentgen.ui import error
|
||||
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
|
||||
def get_osm(boundary_box: str, to_update: bool = False) -> Optional[str]:
|
||||
"""
|
||||
|
@ -21,10 +22,10 @@ def get_osm(boundary_box: str, to_update: bool = False) -> Optional[str]:
|
|||
:param boundary_box: borders of the map part to download
|
||||
:param to_update: update cache files
|
||||
"""
|
||||
result_file_name = os.path.join("map", boundary_box + ".osm")
|
||||
result_file_name: Path = "map" / Path(boundary_box + ".osm")
|
||||
|
||||
if not to_update and os.path.isfile(result_file_name):
|
||||
return open(result_file_name).read()
|
||||
if not to_update and result_file_name.is_file():
|
||||
return result_file_name.open().read()
|
||||
|
||||
matcher = re.match(
|
||||
"(?P<left>[0-9.-]*),(?P<bottom>[0-9.-]*)," +
|
||||
|
@ -58,7 +59,7 @@ def get_osm(boundary_box: str, to_update: bool = False) -> Optional[str]:
|
|||
"api.openstreetmap.org/api/0.6/map",
|
||||
{"bbox": boundary_box}, is_secure=True)
|
||||
|
||||
open(result_file_name, "w+").write(content.decode("utf-8"))
|
||||
result_file_name.open("w+").write(content.decode("utf-8"))
|
||||
|
||||
return content.decode("utf-8")
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
"""
|
||||
Reading OpenStreetMap data from XML file.
|
||||
|
||||
Author: Sergey Vartanov (me@enzet.ru).
|
||||
"""
|
||||
import json
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Set, Union
|
||||
|
||||
import numpy as np
|
||||
|
@ -12,6 +11,9 @@ import numpy as np
|
|||
from roentgen.ui import progress_bar
|
||||
from roentgen.util import MinMax
|
||||
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
OSM_TIME_PATTERN: str = "%Y-%m-%dT%H:%M:%SZ"
|
||||
|
||||
|
||||
|
@ -67,7 +69,8 @@ class OSMNode(Tagged):
|
|||
self.visible = get_value("visible", text)
|
||||
self.changeset = get_value("changeset", text)
|
||||
self.timestamp = datetime.strptime(
|
||||
get_value("timestamp", text), OSM_TIME_PATTERN)
|
||||
get_value("timestamp", text), OSM_TIME_PATTERN
|
||||
)
|
||||
self.user = get_value("user", text)
|
||||
self.uid = get_value("uid", text)
|
||||
|
||||
|
@ -296,11 +299,11 @@ class OverpassReader:
|
|||
def __init__(self):
|
||||
self.map_ = Map()
|
||||
|
||||
def parse_json_file(self, file_name: str) -> Map:
|
||||
def parse_json_file(self, file_name: Path) -> Map:
|
||||
"""
|
||||
Parse JSON structure from the file and construct map.
|
||||
"""
|
||||
with open(file_name) as input_file:
|
||||
with file_name.open() as input_file:
|
||||
structure = json.load(input_file)
|
||||
|
||||
node_map = {}
|
||||
|
@ -332,7 +335,7 @@ class OSMReader:
|
|||
self.map_ = Map()
|
||||
|
||||
def parse_osm_file(
|
||||
self, file_name: str, parse_nodes: bool = True,
|
||||
self, file_name: Path, parse_nodes: bool = True,
|
||||
parse_ways: bool = True, parse_relations: bool = True,
|
||||
full: bool = False
|
||||
) -> Map:
|
||||
|
@ -341,7 +344,7 @@ class OSMReader:
|
|||
|
||||
:param file_name: input OSM XML file name
|
||||
"""
|
||||
with open(file_name) as input_file:
|
||||
with file_name.open() as input_file:
|
||||
lines_number: int = sum(1 for _ in input_file)
|
||||
|
||||
print(f"Parsing OSM file {file_name}...")
|
||||
|
@ -349,7 +352,7 @@ class OSMReader:
|
|||
|
||||
element: Optional[Union[OSMNode, OSMWay, OSMRelation]] = None
|
||||
|
||||
with open(file_name) as input_file:
|
||||
with file_name.open() as input_file:
|
||||
for line in input_file.readlines(): # type: str
|
||||
|
||||
line = line.strip()
|
||||
|
|
|
@ -11,6 +11,9 @@ from roentgen.icon import Icon, IconSet
|
|||
from roentgen.osm_reader import Tagged
|
||||
from roentgen.text import Label
|
||||
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
DEFAULT_FONT: str = "Roboto"
|
||||
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
"""
|
||||
Röntgen drawing scheme.
|
||||
|
||||
Author: Sergey Vartanov (me@enzet.ru).
|
||||
"""
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Set, Tuple, Union
|
||||
|
||||
import yaml
|
||||
|
@ -17,6 +16,9 @@ from roentgen.icon import (
|
|||
)
|
||||
from roentgen.text import Label, get_address, get_text
|
||||
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
|
||||
@dataclass
|
||||
class LineStyle:
|
||||
|
@ -103,12 +105,12 @@ class Scheme:
|
|||
|
||||
Specifies map colors and rules to draw icons for OpenStreetMap tags.
|
||||
"""
|
||||
def __init__(self, file_name: str):
|
||||
def __init__(self, file_name: Path):
|
||||
"""
|
||||
:param file_name: scheme file name with tags, colors, and tag key
|
||||
:param file_name: name of the scheme file with tags, colors, and tag key
|
||||
specification
|
||||
"""
|
||||
with open(file_name) as input_file:
|
||||
with file_name.open() as input_file:
|
||||
content: Dict[str, Any] = yaml.load(
|
||||
input_file.read(), Loader=yaml.FullLoader)
|
||||
|
||||
|
@ -198,8 +200,10 @@ class Scheme:
|
|||
processed: Set[str] = set()
|
||||
priority: int = 0
|
||||
|
||||
for index, matcher in enumerate(self.icons):
|
||||
index: int
|
||||
index: int = 0
|
||||
|
||||
for group in self.icons:
|
||||
for matcher in group["tags"]:
|
||||
matcher: Dict[str, Any]
|
||||
matched: bool = is_matched(matcher, tags)
|
||||
matcher_tags: Set[str] = matcher["tags"].keys()
|
||||
|
@ -238,6 +242,8 @@ class Scheme:
|
|||
if "set_main_color" in matcher:
|
||||
main_icon.recolor(self.get_color(matcher["set_main_color"]))
|
||||
|
||||
index += 1
|
||||
|
||||
color: Optional[Color] = None
|
||||
|
||||
for tag_key in tags: # type: str
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
"""
|
||||
OSM address tag processing.
|
||||
|
||||
Author: Sergey Vartanov (me@enzet.ru).
|
||||
"""
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from colour import Color
|
||||
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
DEFAULT_COLOR: Color = Color("#444444")
|
||||
|
||||
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
"""
|
||||
Author: Sergey Vartanov (me@enzet.ru).
|
||||
Command-line user interface.
|
||||
"""
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
from typing import List, Optional
|
||||
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
BOXES: List[str] = [" ", "▏", "▎", "▍", "▌", "▋", "▊", "▉"]
|
||||
BOXES_LENGTH: int = len(BOXES)
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
"""
|
||||
Röntgen utility file.
|
||||
|
||||
Author: Sergey Vartanov (me@enzet.ru).
|
||||
"""
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
|
||||
@dataclass
|
||||
class MinMax:
|
||||
|
|
|
@ -69,8 +69,8 @@ colors:
|
|||
|
||||
node_icons:
|
||||
|
||||
# No draw
|
||||
|
||||
- group: "No draw"
|
||||
tags:
|
||||
- tags: {type: multipolygon}
|
||||
draw: false
|
||||
- tags: {place: "*"}
|
||||
|
@ -78,8 +78,8 @@ node_icons:
|
|||
- tags: {building: "yes"}
|
||||
draw: false
|
||||
|
||||
# Transport hubs
|
||||
|
||||
- group: "Transport hubs"
|
||||
tags:
|
||||
- tags: {amenity: ferry_terminal}
|
||||
icon: [anchor]
|
||||
- tags: {amenity: ferry_terminal, cargo: vehicle}
|
||||
|
@ -133,30 +133,27 @@ node_icons:
|
|||
- tags: {highway: stop}
|
||||
icon: [stop]
|
||||
|
||||
# Big territory
|
||||
|
||||
- group: "Big territory"
|
||||
tags:
|
||||
- tags: {leisure: fishing}
|
||||
icon: [fishing_angle]
|
||||
- tags: {power: substation}
|
||||
icon: [electricity]
|
||||
# plant=*
|
||||
- tags: {plant: christmas_trees}
|
||||
icon: [{shape: christmas_tree, color: orchard_border_color}]
|
||||
# produce=*
|
||||
- tags: {produce: apple}
|
||||
icon: [{shape: apple, color: orchard_border_color}]
|
||||
- tags: {produce: christmas_trees}
|
||||
icon: [{shape: christmas_tree, color: orchard_border_color}]
|
||||
- tags: {produce: pear}
|
||||
icon: [{shape: pear, color: orchard_border_color}]
|
||||
# trees=*
|
||||
- tags: {trees: apple_trees}
|
||||
icon: [{shape: apple, color: orchard_border_color}]
|
||||
- tags: {trees: pear_trees}
|
||||
icon: [{shape: pear, color: orchard_border_color}]
|
||||
|
||||
# Bigger objects
|
||||
|
||||
- group: "Bigger objects"
|
||||
tags:
|
||||
- tags: {waterway: waterfall}
|
||||
icon: [{shape: waterfall, color: water_border_color}]
|
||||
- tags: {natural: cliff}
|
||||
|
@ -168,8 +165,8 @@ node_icons:
|
|||
- tags: {shop: mall, building: "yes"}
|
||||
icon: [bag]
|
||||
|
||||
# Important big objects
|
||||
|
||||
- group: "Important big objects"
|
||||
tags:
|
||||
- tags: {amenity: pharmacy}
|
||||
icon: [medicine_bottle]
|
||||
- tags: {amenity: embassy}
|
||||
|
@ -226,8 +223,8 @@ node_icons:
|
|||
- tags: {historic: tomb, tomb: mausoleum}
|
||||
icon: [mausoleum]
|
||||
|
||||
# Normal big objects
|
||||
|
||||
- group: "Normal big objects"
|
||||
tags:
|
||||
- tags: {shop: supermarket}
|
||||
icon: [supermarket_cart]
|
||||
- tags: {amenity: arts_centre}
|
||||
|
@ -324,8 +321,8 @@ node_icons:
|
|||
- tags: {shop: electronics}
|
||||
icon: [tv]
|
||||
|
||||
# Big objects not for all
|
||||
|
||||
- group: "Big objects not for all"
|
||||
tags:
|
||||
- tags: {building: apartments}
|
||||
icon: [apartments]
|
||||
- tags: {building: kindergarten}
|
||||
|
@ -342,8 +339,8 @@ node_icons:
|
|||
- tags: {office: telecommunication}
|
||||
icon: [telephone]
|
||||
|
||||
# Not important big objects
|
||||
|
||||
- group: "Not important big objects"
|
||||
tags:
|
||||
- tags: {man_made: tower}
|
||||
icon: [tower]
|
||||
- tags: {building: garages}
|
||||
|
@ -351,8 +348,8 @@ node_icons:
|
|||
- tags: {building: garage}
|
||||
icon: [garages]
|
||||
|
||||
# Emergency
|
||||
|
||||
- group: "Emergency"
|
||||
tags:
|
||||
- tags: {emergency: defibrillator}
|
||||
icon: [{shape: defibrillator, color: emergency_color}]
|
||||
- tags: {emergency: fire_extinguisher}
|
||||
|
@ -364,8 +361,8 @@ node_icons:
|
|||
- tags: {emergency: phone}
|
||||
icon: [{shape: sos_phone, color: emergency_color}]
|
||||
|
||||
# Transport-important middle objects
|
||||
|
||||
- group: "Transport-important middle objects"
|
||||
tags:
|
||||
- tags: {ford: "yes"}
|
||||
icon: [ford]
|
||||
- tags: {amenity: charging_station}
|
||||
|
@ -399,15 +396,15 @@ node_icons:
|
|||
- tags: {crossing_ref: toucan}
|
||||
icon: [toucan_crossing]
|
||||
|
||||
# Important middle objects
|
||||
|
||||
- group: "Important middle objects"
|
||||
tags:
|
||||
- tags: {tourism: attraction, attraction: amusement_ride}
|
||||
icon: [amusement_ride]
|
||||
- tags: {amenity: toilets}
|
||||
icon: [woman_and_man]
|
||||
|
||||
# Normal middle objects
|
||||
|
||||
- group: "Normal middle objects"
|
||||
tags:
|
||||
- tags: {shop: kiosk}
|
||||
icon: [kiosk]
|
||||
- tags: {building: "yes", shop: kiosk}
|
||||
|
@ -419,8 +416,8 @@ node_icons:
|
|||
- tags: {natural: cave_entrance}
|
||||
icon: [cave]
|
||||
|
||||
# Not important middle objects
|
||||
|
||||
- group: "Not important middle objects"
|
||||
tags:
|
||||
- tags: {building: ventilation_shaft}
|
||||
icon: [ventilation]
|
||||
- tags: {power: generator}
|
||||
|
@ -476,8 +473,8 @@ node_icons:
|
|||
- tags: {power: tower, design: portal_three-level}
|
||||
icon: [power_tower_portal_3_level]
|
||||
|
||||
# Important small objects
|
||||
|
||||
- group: "Important small objects"
|
||||
tags:
|
||||
- tags: {historic: memorial}
|
||||
icon: [memorial]
|
||||
- tags: {historic: memorial, memorial: plaque}
|
||||
|
@ -552,8 +549,8 @@ node_icons:
|
|||
- tags: {xmas:feature: tree}
|
||||
icon: {christmas_tree}
|
||||
|
||||
# Normal small objects
|
||||
|
||||
- group: "Normal small objects"
|
||||
tags:
|
||||
- tags: {amenity: binoculars}
|
||||
icon: [binoculars_on_pole]
|
||||
- tags: {amenity: post_box}
|
||||
|
@ -587,8 +584,8 @@ node_icons:
|
|||
- tags: {leisure: picnic_table}
|
||||
icon: [table]
|
||||
|
||||
# Entrances
|
||||
|
||||
- group: "Entrances"
|
||||
tags:
|
||||
- tags: {barrier: gate}
|
||||
icon: [gate]
|
||||
- tags: {entrance: main}
|
||||
|
@ -606,8 +603,8 @@ node_icons:
|
|||
- tags: {door: "no"}
|
||||
icon: [no_door]
|
||||
|
||||
# Not important small objects
|
||||
|
||||
- group: "Not important small objects"
|
||||
tags:
|
||||
- tags: {amenity: bench}
|
||||
icon: [bench]
|
||||
- tags: {amenity: bench, backrest: "yes"}
|
||||
|
@ -652,7 +649,7 @@ node_icons:
|
|||
icon: [lowered_kerb]
|
||||
- tags: {kerb: lowered}
|
||||
icon: [lowered_kerb]
|
||||
# Trees
|
||||
|
||||
- tags: {natural: tree}
|
||||
icon: [{shape: tree, color: tree_color}]
|
||||
- tags: {leaf_type: broadleaved}
|
||||
|
@ -679,7 +676,6 @@ node_icons:
|
|||
set_main_color: evergreen_color
|
||||
- tags: {natural: bush}
|
||||
icon: [{shape: bush, color: tree_color}]
|
||||
# Tree genus
|
||||
- tags: {natural: tree, genus: Betula}
|
||||
icon: [{shape: betula, color: tree_color}]
|
||||
- tags: {natural: tree, "genus:en": Birch}
|
||||
|
@ -734,13 +730,13 @@ node_icons:
|
|||
- tags: {barrier: bollard}
|
||||
icon: [bollard]
|
||||
|
||||
# Indoor
|
||||
|
||||
- group: "Indoor"
|
||||
tags:
|
||||
- tags: {door: "yes"}
|
||||
icon: [entrance]
|
||||
|
||||
# Add and over
|
||||
|
||||
- group: "Add and over"
|
||||
tags:
|
||||
- tags: {support: pole}
|
||||
over_icon: [support_pole]
|
||||
under_icon: [clock, information_board]
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
"""
|
||||
Test direction processing.
|
||||
|
||||
Author: Sergey Vartanov (me@enzet.ru).
|
||||
"""
|
||||
import numpy as np
|
||||
|
||||
from roentgen.direction import parse_vector
|
||||
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
|
||||
def test_compass_points_1() -> None:
|
||||
""" Test north direction. """
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""
|
||||
Test icon generation for nodes.
|
||||
|
||||
Author: Sergey Vartanov (me@enzet.ru).
|
||||
"""
|
||||
from os import makedirs
|
||||
from pathlib import Path
|
||||
|
@ -11,9 +9,12 @@ from roentgen.grid import draw_all_icons
|
|||
from roentgen.icon import ShapeExtractor
|
||||
from roentgen.scheme import Scheme
|
||||
|
||||
SCHEME: Scheme = Scheme("scheme/default.yml")
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
SCHEME: Scheme = Scheme(Path("scheme/default.yml"))
|
||||
ICON_EXTRACTOR: ShapeExtractor = ShapeExtractor(
|
||||
"icons/icons.svg", Path("icons/config.json")
|
||||
Path("icons/icons.svg"), Path("icons/config.json")
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
"""
|
||||
Test label generation for nodes.
|
||||
|
||||
Author: Sergey Vartanov (me@enzet.ru).
|
||||
"""
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
from roentgen.scheme import Scheme
|
||||
from roentgen.text import Label
|
||||
|
||||
SCHEME: Scheme = Scheme("scheme/default.yml")
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
SCHEME: Scheme = Scheme(Path("scheme/default.yml"))
|
||||
|
||||
|
||||
def construct_labels(tags) -> List[Label]:
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
"""
|
||||
Test text generation.
|
||||
|
||||
Author: Sergey Vartanov (me@enzet.ru).
|
||||
"""
|
||||
from roentgen.text import format_voltage
|
||||
|
||||
__author__ = "Sergey Vartanov"
|
||||
__email__ = "me@enzet.ru"
|
||||
|
||||
|
||||
def test_voltage() -> None:
|
||||
"""
|
||||
|
|