mirror of
https://github.com/enzet/map-machine.git
synced 2025-06-14 00:31:52 +02:00
Improve construction drawing.
Draw buildings under construction without roof.
This commit is contained in:
parent
f9d9442da3
commit
7fbc7cb96f
3 changed files with 37 additions and 19 deletions
|
@ -11,7 +11,7 @@ import numpy as np
|
||||||
from colour import Color
|
from colour import Color
|
||||||
|
|
||||||
from map_machine.color import get_gradient_color
|
from map_machine.color import get_gradient_color
|
||||||
from map_machine.feature.building import Building
|
from map_machine.feature.building import Building, BUILDING_SCALE
|
||||||
from map_machine.feature.crater import Crater
|
from map_machine.feature.crater import Crater
|
||||||
from map_machine.feature.direction import DirectionSector
|
from map_machine.feature.direction import DirectionSector
|
||||||
from map_machine.feature.road import Road, Roads
|
from map_machine.feature.road import Road, Roads
|
||||||
|
@ -189,7 +189,7 @@ class Constructor:
|
||||||
self.craters: list[Crater] = []
|
self.craters: list[Crater] = []
|
||||||
self.direction_sectors: list[DirectionSector] = []
|
self.direction_sectors: list[DirectionSector] = []
|
||||||
|
|
||||||
self.heights: set[float] = {1.0, 2.0}
|
self.heights: set[float] = {0.25 / BUILDING_SCALE, 0.5 / BUILDING_SCALE}
|
||||||
|
|
||||||
def add_building(self, building: Building) -> None:
|
def add_building(self, building: Building) -> None:
|
||||||
"""Add building and update levels."""
|
"""Add building and update levels."""
|
||||||
|
|
|
@ -16,8 +16,10 @@ from map_machine.geometry.vector import Segment
|
||||||
from map_machine.osm.osm_reader import OSMNode
|
from map_machine.osm.osm_reader import OSMNode
|
||||||
from map_machine.scheme import Scheme
|
from map_machine.scheme import Scheme
|
||||||
|
|
||||||
BUILDING_HEIGHT_SCALE: float = 2.5
|
|
||||||
BUILDING_MINIMAL_HEIGHT: float = 8.0
|
BUILDING_MINIMAL_HEIGHT: float = 8.0
|
||||||
|
BUILDING_SCALE: float = 1.0
|
||||||
|
LEVEL_HEIGHT: float = 2.5
|
||||||
|
SHADE_SCALE: float = 0.4
|
||||||
|
|
||||||
|
|
||||||
class Building(Figure):
|
class Building(Figure):
|
||||||
|
@ -33,7 +35,10 @@ class Building(Figure):
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(tags, inners, outers)
|
super().__init__(tags, inners, outers)
|
||||||
|
|
||||||
self.is_construction: bool = tags.get("building") == "construction"
|
self.is_construction: bool = (
|
||||||
|
tags.get("building") == "construction"
|
||||||
|
or tags.get("construction") == "yes"
|
||||||
|
)
|
||||||
|
|
||||||
if self.is_construction:
|
if self.is_construction:
|
||||||
self.fill: Color = scheme.get_color("building_construction_color")
|
self.fill: Color = scheme.get_color("building_construction_color")
|
||||||
|
@ -67,11 +72,11 @@ class Building(Figure):
|
||||||
|
|
||||||
levels: Optional[str] = self.get_float("building:levels")
|
levels: Optional[str] = self.get_float("building:levels")
|
||||||
if levels:
|
if levels:
|
||||||
self.height = float(levels) * BUILDING_HEIGHT_SCALE
|
self.height = float(levels) * LEVEL_HEIGHT
|
||||||
|
|
||||||
levels: Optional[str] = self.get_float("building:min_level")
|
levels: Optional[str] = self.get_float("building:min_level")
|
||||||
if levels:
|
if levels:
|
||||||
self.min_height = float(levels) * BUILDING_HEIGHT_SCALE
|
self.min_height = float(levels) * LEVEL_HEIGHT
|
||||||
|
|
||||||
height: Optional[float] = self.get_length("height")
|
height: Optional[float] = self.get_length("height")
|
||||||
if height:
|
if height:
|
||||||
|
@ -93,7 +98,7 @@ class Building(Figure):
|
||||||
|
|
||||||
def draw_shade(self, building_shade: Group, flinger: Flinger) -> None:
|
def draw_shade(self, building_shade: Group, flinger: Flinger) -> None:
|
||||||
"""Draw shade casted by the building."""
|
"""Draw shade casted by the building."""
|
||||||
scale: float = flinger.get_scale() / 3.0
|
scale: float = flinger.get_scale() * SHADE_SCALE
|
||||||
shift_1: np.ndarray = np.array((scale * self.min_height, 0.0))
|
shift_1: np.ndarray = np.array((scale * self.min_height, 0.0))
|
||||||
shift_2: np.ndarray = np.array((scale * self.height, 0.0))
|
shift_2: np.ndarray = np.array((scale * self.height, 0.0))
|
||||||
commands: str = self.get_path(flinger, shift_1)
|
commands: str = self.get_path(flinger, shift_1)
|
||||||
|
@ -123,17 +128,28 @@ class Building(Figure):
|
||||||
self, svg: Drawing, height: float, previous_height: float, scale: float
|
self, svg: Drawing, height: float, previous_height: float, scale: float
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Draw building walls."""
|
"""Draw building walls."""
|
||||||
shift_1: np.ndarray = np.array((0.0, -previous_height * scale))
|
shift_1: np.ndarray = np.array(
|
||||||
shift_2: np.ndarray = np.array((0.0, -height * scale))
|
(0.0, -previous_height * scale * BUILDING_SCALE)
|
||||||
|
)
|
||||||
|
shift_2: np.ndarray = np.array((0.0, -height * scale * BUILDING_SCALE))
|
||||||
for segment in self.parts:
|
for segment in self.parts:
|
||||||
fill: Color
|
fill: str
|
||||||
if height <= 1.0:
|
if self.is_construction:
|
||||||
fill = self.wall_bottom_color_1
|
color_part: float = segment.angle * 0.2
|
||||||
elif height <= 2.0:
|
fill = Color(
|
||||||
fill = self.wall_bottom_color_2
|
rgb=(
|
||||||
|
0x84 / 0xFF + color_part,
|
||||||
|
0x80 / 0xFF + color_part,
|
||||||
|
0x7C / 0xFF + color_part,
|
||||||
|
)
|
||||||
|
).hex
|
||||||
|
elif height <= 0.25 / BUILDING_SCALE:
|
||||||
|
fill = self.wall_bottom_color_1.hex
|
||||||
|
elif height <= 0.5 / BUILDING_SCALE:
|
||||||
|
fill = self.wall_bottom_color_2.hex
|
||||||
else:
|
else:
|
||||||
color_part: float = self.wall_color_start + segment.angle * 0.2
|
color_part: float = self.wall_color_start + segment.angle * 0.2
|
||||||
fill = Color(rgb=(color_part, color_part, color_part))
|
fill = Color(rgb=(color_part, color_part, color_part)).hex
|
||||||
|
|
||||||
command = (
|
command = (
|
||||||
"M",
|
"M",
|
||||||
|
@ -147,8 +163,8 @@ class Building(Figure):
|
||||||
)
|
)
|
||||||
path: Path = svg.path(
|
path: Path = svg.path(
|
||||||
d=command,
|
d=command,
|
||||||
fill=fill.hex,
|
fill=fill,
|
||||||
stroke=fill.hex,
|
stroke=fill,
|
||||||
stroke_width=1,
|
stroke_width=1,
|
||||||
stroke_linejoin="round",
|
stroke_linejoin="round",
|
||||||
)
|
)
|
||||||
|
@ -157,7 +173,9 @@ class Building(Figure):
|
||||||
def draw_roof(self, svg: Drawing, flinger: Flinger, scale: float) -> None:
|
def draw_roof(self, svg: Drawing, flinger: Flinger, scale: float) -> None:
|
||||||
"""Draw building roof."""
|
"""Draw building roof."""
|
||||||
path: Path = Path(
|
path: Path = Path(
|
||||||
d=self.get_path(flinger, np.array([0.0, -self.height * scale])),
|
d=self.get_path(
|
||||||
|
flinger, np.array([0.0, -self.height * scale * BUILDING_SCALE])
|
||||||
|
),
|
||||||
stroke=self.stroke,
|
stroke=self.stroke,
|
||||||
fill="none" if self.is_construction else self.fill,
|
fill="none" if self.is_construction else self.fill,
|
||||||
stroke_linejoin="round",
|
stroke_linejoin="round",
|
||||||
|
|
|
@ -124,7 +124,7 @@ class Map:
|
||||||
|
|
||||||
logging.info("Drawing buildings...")
|
logging.info("Drawing buildings...")
|
||||||
|
|
||||||
scale: float = self.flinger.get_scale() / 3.0
|
scale: float = self.flinger.get_scale()
|
||||||
building_shade: Group = Group(opacity=0.1)
|
building_shade: Group = Group(opacity=0.1)
|
||||||
for building in constructor.buildings:
|
for building in constructor.buildings:
|
||||||
building.draw_shade(building_shade, self.flinger)
|
building.draw_shade(building_shade, self.flinger)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue