Merge main.

This commit is contained in:
Sergey Vartanov 2021-09-24 06:38:06 +03:00
commit a7b3c707cf
12 changed files with 378 additions and 90 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

After

Width:  |  Height:  |  Size: 213 KiB

Before After
Before After

View file

@ -12,3 +12,18 @@ __doc_url__ = f"{__url__}/blob/main/README.md"
__author__ = "Sergey Vartanov"
__email__ = "me@enzet.ru"
__version__ = "0.1.3"
REQUIREMENTS = [
"CairoSVG>=2.5.0",
"colour>=0.1.5",
"numpy>=1.18.1",
"Pillow>=8.2.0",
"portolan>=1.0.1",
"pycairo",
"pytest>=6.2.2",
"PyYAML>=4.2b1",
"setuptools>=51.0.0",
"Shapely>=1.7.1",
"svgwrite>=1.4",
"urllib3>=1.25.6",
]

View file

@ -499,7 +499,7 @@ def check_level_overground(tags: Dict[str, Any]) -> bool:
try:
levels: map = map(float, tags["level"].replace(",", ".").split(";"))
for level in levels:
if level <= 0:
if level < 0:
return False
except ValueError:
pass

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Before After
Before After

View file

@ -34,6 +34,7 @@ class BuildingMode(Enum):
Building drawing mode.
"""
NO: str = "no"
FLAT: str = "flat"
ISOMETRIC: str = "isometric"
ISOMETRIC_NO_PARTS: str = "isometric-no-parts"
@ -55,10 +56,11 @@ class MapConfiguration:
show_tooltips: bool = False
country: str = "world"
ignore_level_matching: bool = False
draw_roofs: bool = True
@classmethod
def from_options(
cls, options: argparse.Namespace, zoom_level: int
cls, options: argparse.Namespace, zoom_level: float
) -> "MapConfiguration":
"""Initialize from command-line options."""
return cls(
@ -69,8 +71,10 @@ class MapConfiguration:
options.overlap,
options.level,
options.seed,
options.show_tooltips,
options.tooltips,
options.country,
options.ignore_level_matching,
options.roofs,
)
def is_wireframe(self) -> bool:

View file

@ -125,6 +125,8 @@ class Map:
def draw_buildings(self, constructor: Constructor) -> None:
"""Draw buildings: shade, walls, and roof."""
if self.configuration.building_mode == BuildingMode.NO:
return
if self.configuration.building_mode == BuildingMode.FLAT:
for building in constructor.buildings:
building.draw(self.svg, self.flinger)
@ -146,9 +148,10 @@ class Map:
continue
building.draw_walls(self.svg, height, previous_height, scale)
for building in constructor.buildings:
if building.height == height:
building.draw_roof(self.svg, self.flinger, scale)
if self.configuration.draw_roofs:
for building in constructor.buildings:
if building.height == height:
building.draw_roof(self.svg, self.flinger, scale)
previous_height = height
@ -191,7 +194,7 @@ def ui(arguments: argparse.Namespace) -> None:
:param arguments: command-line arguments
"""
configuration: MapConfiguration = MapConfiguration.from_options(
arguments, int(arguments.zoom)
arguments, float(arguments.zoom)
)
cache_path: Path = Path(arguments.cache)
cache_path.mkdir(parents=True, exist_ok=True)

View file

@ -407,9 +407,7 @@ class Scheme:
extra_icons: List[Icon] = []
priority: int = 0
index: int = 0
for matcher in self.node_matchers:
for index, matcher in enumerate(self.node_matchers):
if not matcher.replace_shapes and main_icon:
continue
if not matcher.is_matched(tags, configuration):
@ -449,8 +447,6 @@ class Scheme:
if matcher.set_opacity and main_icon:
main_icon.opacity = matcher.set_opacity
index += 1
color: Optional[Color] = None
if "material" in tags:
@ -464,7 +460,7 @@ class Scheme:
color = self.get_color(tags[tag_key])
processed.add(tag_key)
for color_tag_key in ["color", "colour"]:
for color_tag_key in ["colour", "color", "building:colour"]:
if color_tag_key in tags:
color = self.get_color(tags[color_tag_key])
processed.add(color_tag_key)

View file

@ -1102,8 +1102,16 @@ node_icons:
shapes: [picture]
- tags: {tourism: artwork, artwork_type: statue}
shapes: [statue]
- tags: {exhibit: artwork, artwork_type: statue}
shapes: [statue_exhibit]
- tags: {tourism: artwork, artwork_type: sculpture}
shapes: [statue]
- tags: {exhibit: artwork, artwork_type: sculpture}
shapes: [statue_exhibit]
- tags: {exhibit: artwork, artwork_type: painting}
shapes: [picture]
- tags: {exhibit: artwork, artwork_type: stained_glass}
shapes: [stained_glass]
- tags: {tourism: attraction}
shapes: [photo_camera]
- tags: {xmas:feature: tree}
@ -1174,12 +1182,18 @@ node_icons:
shapes: [gate]
- tags: {barrier: gate}
shapes: [gate]
- tags: {entrance: garage}
shapes: [garage_door]
- tags: {entrance: main}
shapes: [main_entrance]
- tags: {barrier: entrance}
shapes: [entrance]
- tags: {barrier: door}
shapes: [entrance]
- tags: {entrance: "yes"}
shapes: [entrance]
- tags: {entrance: shop}
shapes: [entrance]
- tags: {entrance: exit}
shapes: [exit]
- tags: {entrance: service}
@ -1249,6 +1263,56 @@ node_icons:
- tags: {kerb: lowered}
shapes: [lowered_kerb]
- tags: {railway: buffer_stop}
shapes: [buffer_stop]
- tags: {traffic_sign: city_limit}
shapes: [city_limit_sign]
- tags: {traffic_sign: maxspeed, maxspeed: "30"}
shapes: [
circle_11,
{shape: digit_3, offset: [-2, 0], color: "#FFFFFF"},
{shape: digit_0, offset: [2, 0], color: "#FFFFFF"},
]
- tags: {traffic_sign: maxspeed, maxspeed: "40"}
shapes: [
circle_11,
{shape: digit_4, offset: [-2, 0], color: "#FFFFFF"},
{shape: digit_0, offset: [2, 0], color: "#FFFFFF"},
]
- tags: {traffic_sign: maxspeed, maxspeed: "50"}
shapes: [
circle_11,
{shape: digit_5, offset: [-2, 0], color: "#FFFFFF"},
{shape: digit_0, offset: [2, 0], color: "#FFFFFF"},
]
- tags: {traffic_sign: maxspeed, maxspeed: "60"}
shapes: [
circle_11,
{shape: digit_6, offset: [-2, 0], color: "#FFFFFF"},
{shape: digit_0, offset: [2, 0], color: "#FFFFFF"},
]
- tags: {traffic_sign: maxspeed, maxspeed: "40_mph"}
shapes: [
speed_limit_mph,
{shape: digit_4, offset: [-2, 2]},
{shape: digit_0, offset: [2, 2]},
]
- tags: {traffic_sign: stop}
shapes: [stop]
- tags: {highway: give_way}
shapes: [triangle_down_hollow]
- tags: {noexit: "yes"}
shapes: [noexit]
- tags: {barrier: block}
shapes: [block]
- tags: {barrier: rock}
shapes: [stone]
- tags: {barrier: bollard}
shapes: [bollard]
- group: "Trees"
start_zoom_level: 18
tags:
- tags: {natural: tree}
shapes: [{shape: tree, color: tree_color}]
- tags: {leaf_type: broadleaved}
@ -1298,58 +1362,13 @@ node_icons:
shapes: [{shape: tree, color: tree_color}]
add_shapes: [{shape: pear, color: tree_color}]
- tags: {railway: buffer_stop}
shapes: [buffer_stop]
- tags: {traffic_sign: city_limit}
shapes: [city_limit_sign]
- tags: {traffic_sign: maxspeed, maxspeed: "30"}
shapes: [
circle_11,
{shape: digit_3, offset: [-2, 0], color: "#FFFFFF"},
{shape: digit_0, offset: [2, 0], color: "#FFFFFF"},
]
- tags: {traffic_sign: maxspeed, maxspeed: "40"}
shapes: [
circle_11,
{shape: digit_4, offset: [-2, 0], color: "#FFFFFF"},
{shape: digit_0, offset: [2, 0], color: "#FFFFFF"},
]
- tags: {traffic_sign: maxspeed, maxspeed: "50"}
shapes: [
circle_11,
{shape: digit_5, offset: [-2, 0], color: "#FFFFFF"},
{shape: digit_0, offset: [2, 0], color: "#FFFFFF"},
]
- tags: {traffic_sign: maxspeed, maxspeed: "60"}
shapes: [
circle_11,
{shape: digit_6, offset: [-2, 0], color: "#FFFFFF"},
{shape: digit_0, offset: [2, 0], color: "#FFFFFF"},
]
- tags: {traffic_sign: maxspeed, maxspeed: "40_mph"}
shapes: [
speed_limit_mph,
{shape: digit_4, offset: [-2, 2]},
{shape: digit_0, offset: [2, 2]},
]
- tags: {traffic_sign: stop}
shapes: [stop]
- tags: {highway: give_way}
shapes: [triangle_down_hollow]
- tags: {noexit: "yes"}
shapes: [noexit]
- tags: {barrier: block}
shapes: [block]
- tags: {barrier: rock}
shapes: [stone]
- tags: {barrier: bollard}
shapes: [bollard]
- group: "Indoor"
start_zoom_level: 18
tags:
- tags: {door: "yes"}
shapes: [entrance]
- tags: {indoor: pillar}
shapes: [pillar]
- group: "Add and over"
tags:

View file

@ -21,7 +21,7 @@ COMMANDS: Dict[str, List[str]] = {
"render",
"-b",
"10.000,20.000,10.001,20.001",
"--show-tooltips",
"--tooltips",
],
"icons": ["icons"],
"mapcss": ["mapcss"],
@ -116,14 +116,14 @@ def add_map_arguments(parser: argparse.ArgumentParser) -> None:
metavar="<string>",
)
parser.add_argument(
"--show-tooltips",
"--tooltips",
help="add tooltips with tags for icons in SVG files",
action="store_true",
default=False,
)
parser.add_argument(
"--no-show-tooltips",
dest="show_tooltips",
"--no-tooltips",
dest="tooltips",
help="don't add tooltips with tags for icons in SVG files",
action="store_false",
)
@ -133,6 +133,30 @@ def add_map_arguments(parser: argparse.ArgumentParser) -> None:
"used for location restrictions",
default="world",
)
parser.add_argument(
"--ignore-level-matching",
help="draw all map features ignoring the current level",
action="store_true",
default=False,
)
parser.add_argument(
"--no-ignore-level-matching",
dest="ignore_level_matching",
help="draw all map features taking into account the current level",
action="store_false",
)
parser.add_argument(
"--roofs",
help="draw building roofs",
action="store_true",
default=True,
)
parser.add_argument(
"--no-roofs",
dest="roofs",
help="don't draw building roofs",
action="store_false",
)
def add_tile_arguments(parser: argparse.ArgumentParser) -> None:
@ -166,7 +190,7 @@ def add_tile_arguments(parser: argparse.ArgumentParser) -> None:
"-z",
"--zoom",
type=str,
metavar="<integer>",
metavar="<range>",
help="OSM zoom levels; can be list of numbers or ranges, e.g. `16-18`, "
"`16,17,18`, or `16,18-20`",
default="18",
@ -240,8 +264,8 @@ def add_render_arguments(parser: argparse.ArgumentParser) -> None:
parser.add_argument(
"-z",
"--zoom",
type=int,
metavar="<integer>",
type=float,
metavar="<float>",
help="OSM zoom level",
default=18,
)

View file

@ -1,12 +1,12 @@
CairoSVG>=2.5.0
colour~=0.1.5
colour>=0.1.5
numpy>=1.18.1
Pillow>=8.2.0
portolan~=1.0.1
portolan>=1.0.1
pycairo
pytest~=6.2.2
pytest>=6.2.2
PyYAML>=4.2b1
setuptools>=51.0.0
Shapely>=1.7.1
svgwrite~=1.4
svgwrite>=1.4
urllib3>=1.25.6

View file

@ -11,6 +11,7 @@ from map_machine import (
__email__,
__url__,
__version__,
REQUIREMENTS,
)
with Path("README.md").open() as input_file:
@ -50,16 +51,5 @@ setup(
],
},
python_requires=">=3.8",
install_requires=[
"CairoSVG>=2.5.0",
"colour>=0.1.5",
"numpy>=1.18.1",
"Pillow>=8.2.0",
"portolan>=1.0.1",
"pycairo",
"pytest>=6.2.2",
"PyYAML>=4.2b1",
"svgwrite>=1.4",
"urllib3>=1.25.6",
],
install_requires=REQUIREMENTS,
)

View file

@ -0,0 +1,13 @@
from map_machine import REQUIREMENTS
from pathlib import Path
from typing import List
def test_requirements() -> None:
requirements: List[str]
with Path("requirements.txt").open() as requirements_file:
requirements = list(
map(lambda x: x[:-1], requirements_file.readlines())
)
assert requirements == REQUIREMENTS