Model/domain/magicplan/mapper.py
2026-05-11 15:37:51 +00:00

67 lines
2 KiB
Python

from typing import Optional
import datatypes.magicplan.api.response as api
from datatypes.magicplan.api.response import MagicPlanPlan
from domain.magicplan.models import Plan, Floor, Room, Window, Door
def map_plan(mp: MagicPlanPlan) -> Plan:
return Plan(
uid=mp.plan.id,
name=mp.plan.name,
address=_map_address(mp.plan.address),
postcode=mp.plan.address.postal_code if mp.plan.address else None,
floors=[_map_floor(f) for f in mp.plan_detail.plan.floors],
)
def _map_address(addr: Optional[api.Address]) -> Optional[str]:
if addr is None:
return None
street = " ".join(p for p in [addr.street_number, addr.street] if p) or None
parts = [p for p in [street, addr.city, addr.country] if p]
return ", ".join(parts) if parts else None
def _map_floor(f: api.Floor) -> Floor:
return Floor(
level=f.level,
name=f.name,
rooms=[_map_room(r) for r in f.rooms],
)
def _map_room(r: api.Room) -> Room:
width, length = _parse_dimensions(r.dimensions)
return Room(
name=r.name,
width_m=width,
length_m=length,
area_m2=round(r.area, 2),
windows=[
_map_window(wi) for wi in r.wall_items if wi.symbol.id.startswith("window")
],
doors=[_map_door(wi) for wi in r.wall_items if wi.symbol.id.startswith("door")],
)
def _parse_dimensions(dimensions: Optional[str]) -> tuple[float, float]:
if not dimensions:
return 0.0, 0.0
parts = dimensions.split(" x ")
width = round(float(parts[0].split(" m")[0]), 2)
length = round(float(parts[1].split(" m")[0]), 2)
return width, length
def _map_window(wi: api.WallItem) -> Window:
return Window(
width_m=round(wi.size.x, 2),
height_m=round(wi.size.z, 2),
area_m2=round(wi.size.x * wi.size.z, 2),
opening_type=wi.symbol.id.removeprefix("window"),
)
def _map_door(wi: api.WallItem) -> Door:
return Door(width_mm=round(wi.size.x, 2))