mirror of
https://github.com/enzet/map-machine.git
synced 2025-05-31 01:46:26 +02:00
Merge main.
This commit is contained in:
commit
a7b3c707cf
12 changed files with 378 additions and 90 deletions
BIN
doc/colors.png
BIN
doc/colors.png
Binary file not shown.
Before Width: | Height: | Size: 256 KiB After Width: | Height: | Size: 213 KiB |
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -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 |
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
14
setup.py
14
setup.py
|
@ -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,
|
||||
)
|
||||
|
|
13
tests/test_requirements.py
Normal file
13
tests/test_requirements.py
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue