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" __author__ = "Sergey Vartanov"
__email__ = "me@enzet.ru" __email__ = "me@enzet.ru"
__version__ = "0.1.3" __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: try:
levels: map = map(float, tags["level"].replace(",", ".").split(";")) levels: map = map(float, tags["level"].replace(",", ".").split(";"))
for level in levels: for level in levels:
if level <= 0: if level < 0:
return False return False
except ValueError: except ValueError:
pass 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. Building drawing mode.
""" """
NO: str = "no"
FLAT: str = "flat" FLAT: str = "flat"
ISOMETRIC: str = "isometric" ISOMETRIC: str = "isometric"
ISOMETRIC_NO_PARTS: str = "isometric-no-parts" ISOMETRIC_NO_PARTS: str = "isometric-no-parts"
@ -55,10 +56,11 @@ class MapConfiguration:
show_tooltips: bool = False show_tooltips: bool = False
country: str = "world" country: str = "world"
ignore_level_matching: bool = False ignore_level_matching: bool = False
draw_roofs: bool = True
@classmethod @classmethod
def from_options( def from_options(
cls, options: argparse.Namespace, zoom_level: int cls, options: argparse.Namespace, zoom_level: float
) -> "MapConfiguration": ) -> "MapConfiguration":
"""Initialize from command-line options.""" """Initialize from command-line options."""
return cls( return cls(
@ -69,8 +71,10 @@ class MapConfiguration:
options.overlap, options.overlap,
options.level, options.level,
options.seed, options.seed,
options.show_tooltips, options.tooltips,
options.country, options.country,
options.ignore_level_matching,
options.roofs,
) )
def is_wireframe(self) -> bool: def is_wireframe(self) -> bool:

View file

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

View file

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

View file

@ -1102,8 +1102,16 @@ node_icons:
shapes: [picture] shapes: [picture]
- tags: {tourism: artwork, artwork_type: statue} - tags: {tourism: artwork, artwork_type: statue}
shapes: [statue] shapes: [statue]
- tags: {exhibit: artwork, artwork_type: statue}
shapes: [statue_exhibit]
- tags: {tourism: artwork, artwork_type: sculpture} - tags: {tourism: artwork, artwork_type: sculpture}
shapes: [statue] 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} - tags: {tourism: attraction}
shapes: [photo_camera] shapes: [photo_camera]
- tags: {xmas:feature: tree} - tags: {xmas:feature: tree}
@ -1174,12 +1182,18 @@ node_icons:
shapes: [gate] shapes: [gate]
- tags: {barrier: gate} - tags: {barrier: gate}
shapes: [gate] shapes: [gate]
- tags: {entrance: garage}
shapes: [garage_door]
- tags: {entrance: main} - tags: {entrance: main}
shapes: [main_entrance] shapes: [main_entrance]
- tags: {barrier: entrance} - tags: {barrier: entrance}
shapes: [entrance] shapes: [entrance]
- tags: {barrier: door}
shapes: [entrance]
- tags: {entrance: "yes"} - tags: {entrance: "yes"}
shapes: [entrance] shapes: [entrance]
- tags: {entrance: shop}
shapes: [entrance]
- tags: {entrance: exit} - tags: {entrance: exit}
shapes: [exit] shapes: [exit]
- tags: {entrance: service} - tags: {entrance: service}
@ -1249,6 +1263,56 @@ node_icons:
- tags: {kerb: lowered} - tags: {kerb: lowered}
shapes: [lowered_kerb] 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} - tags: {natural: tree}
shapes: [{shape: tree, color: tree_color}] shapes: [{shape: tree, color: tree_color}]
- tags: {leaf_type: broadleaved} - tags: {leaf_type: broadleaved}
@ -1298,58 +1362,13 @@ node_icons:
shapes: [{shape: tree, color: tree_color}] shapes: [{shape: tree, color: tree_color}]
add_shapes: [{shape: pear, 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" - group: "Indoor"
start_zoom_level: 18 start_zoom_level: 18
tags: tags:
- tags: {door: "yes"} - tags: {door: "yes"}
shapes: [entrance] shapes: [entrance]
- tags: {indoor: pillar}
shapes: [pillar]
- group: "Add and over" - group: "Add and over"
tags: tags:

View file

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

View file

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

View file

@ -11,6 +11,7 @@ from map_machine import (
__email__, __email__,
__url__, __url__,
__version__, __version__,
REQUIREMENTS,
) )
with Path("README.md").open() as input_file: with Path("README.md").open() as input_file:
@ -50,16 +51,5 @@ setup(
], ],
}, },
python_requires=">=3.8", python_requires=">=3.8",
install_requires=[ install_requires=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",
"svgwrite>=1.4",
"urllib3>=1.25.6",
],
) )

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