mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
224 lines
8.5 KiB
Python
224 lines
8.5 KiB
Python
import xml.etree.ElementTree as ET
|
|
|
|
from backend.magic_plan.models import (
|
|
MagicPlanDoor,
|
|
MagicPlanExploded,
|
|
MagicPlanExplodedOpening,
|
|
MagicPlanExplodedWall,
|
|
MagicPlanFloor,
|
|
MagicPlanFurniture,
|
|
MagicPlanMainDimension,
|
|
MagicPlanPlan,
|
|
MagicPlanRoom,
|
|
MagicPlanRoomPoint,
|
|
MagicPlanSymbolInstance,
|
|
MagicPlanWallPoint,
|
|
MagicPlanWindow,
|
|
)
|
|
|
|
|
|
def _values(el: ET.Element) -> dict[str, str]:
|
|
return {v.get("key", ""): (v.text or "") for v in el.findall("values/value")}
|
|
|
|
|
|
def _parse_room_point(el: ET.Element) -> MagicPlanRoomPoint:
|
|
return MagicPlanRoomPoint(
|
|
snapped_x=float(el.get("snappedX", "0")),
|
|
snapped_y=float(el.get("snappedY", "0")),
|
|
height=float(el.get("height", "0")),
|
|
uid=el.get("uid", ""),
|
|
values=_values(el),
|
|
)
|
|
|
|
|
|
def _parse_wall_point(el: ET.Element) -> MagicPlanWallPoint:
|
|
return MagicPlanWallPoint(
|
|
x=float(el.get("x", "0")),
|
|
y=float(el.get("y", "0")),
|
|
height=float(el.get("height", "0")),
|
|
)
|
|
|
|
|
|
def _parse_door(el: ET.Element) -> MagicPlanDoor:
|
|
return MagicPlanDoor(
|
|
wall_point_index=int(el.get("point", "0")),
|
|
type=el.get("type", ""),
|
|
u=float(el.get("u", "0")),
|
|
width=float(el.get("width", "0")),
|
|
depth=float(el.get("depth", "0")),
|
|
height=float(el.get("height", "0")),
|
|
orientation=int(el.get("orientation", "0")),
|
|
snapped_type=el.get("snappedType", ""),
|
|
snapped_position=float(el.get("snappedPosition", "0")),
|
|
snapped_width=float(el.get("snappedWidth", "0")),
|
|
snapped_depth=float(el.get("snappedDepth", "0")),
|
|
snapped_height=float(el.get("snappedHeight", "0")),
|
|
snapped_orientation=int(el.get("snappedOrientation", "0")),
|
|
inset_x=float(el.get("insetX", "0")),
|
|
inset_y=float(el.get("insetY", "0")),
|
|
inset_z=float(el.get("insetZ", "0")),
|
|
symbol_instance=el.get("symbolInstance", ""),
|
|
twin_wall_item_uid=el.get("twinWallItemUid"),
|
|
)
|
|
|
|
|
|
def _parse_window(el: ET.Element) -> MagicPlanWindow:
|
|
return MagicPlanWindow(
|
|
wall_point_index=int(el.get("point", "0")),
|
|
type=el.get("type", ""),
|
|
u=float(el.get("u", "0")),
|
|
width=float(el.get("width", "0")),
|
|
depth=float(el.get("depth", "0")),
|
|
height=float(el.get("height", "0")),
|
|
orientation=int(el.get("orientation", "0")),
|
|
snapped_type=el.get("snappedType", ""),
|
|
snapped_position=float(el.get("snappedPosition", "0")),
|
|
snapped_width=float(el.get("snappedWidth", "0")),
|
|
snapped_depth=float(el.get("snappedDepth", "0")),
|
|
snapped_height=float(el.get("snappedHeight", "0")),
|
|
snapped_orientation=int(el.get("snappedOrientation", "0")),
|
|
inset_x=float(el.get("insetX", "0")),
|
|
inset_y=float(el.get("insetY", "0")),
|
|
inset_z=float(el.get("insetZ", "0")),
|
|
symbol_instance=el.get("symbolInstance", ""),
|
|
)
|
|
|
|
|
|
def _parse_exploded_opening(el: ET.Element) -> MagicPlanExplodedOpening:
|
|
return MagicPlanExplodedOpening(
|
|
type=el.get("type", ""),
|
|
x1=float(el.get("x1", "0")),
|
|
y1=float(el.get("y1", "0")),
|
|
x2=float(el.get("x2", "0")),
|
|
y2=float(el.get("y2", "0")),
|
|
width=float(el.get("width", "0")),
|
|
depth=float(el.get("depth", "0")),
|
|
height=float(el.get("height", "0")),
|
|
inset_x=float(el.get("insetX", "0")),
|
|
inset_y=float(el.get("insetY", "0")),
|
|
orientation=int(el.get("orientation", "0")),
|
|
symbol_instance=el.get("symbolInstance", ""),
|
|
)
|
|
|
|
|
|
def _parse_furniture(el: ET.Element) -> MagicPlanFurniture:
|
|
return MagicPlanFurniture(
|
|
type=el.get("type", ""),
|
|
x=float(el.get("x", "0")),
|
|
y=float(el.get("y", "0")),
|
|
snapped_x=float(el.get("snappedX", "0")),
|
|
snapped_y=float(el.get("snappedY", "0")),
|
|
angle=float(el.get("angle", "0")),
|
|
width=float(el.get("width", "0")),
|
|
depth=float(el.get("depth", "0")),
|
|
height=float(el.get("height", "0")),
|
|
snapped_width=float(el.get("snappedWidth", "0")),
|
|
snapped_depth=float(el.get("snappedDepth", "0")),
|
|
snapped_height=float(el.get("snappedHeight", "0")),
|
|
size_lock_0=el.get("sizeLock0", ""),
|
|
size_lock_1=el.get("sizeLock1", ""),
|
|
size_lock_2=el.get("sizeLock2", ""),
|
|
symbol_instance=el.get("symbolInstance", ""),
|
|
)
|
|
|
|
|
|
def _parse_main_dimension(el: ET.Element) -> MagicPlanMainDimension:
|
|
return MagicPlanMainDimension(
|
|
from_point=int(el.get("from", "0")),
|
|
to_point=int(el.get("to", "0")),
|
|
dir_x=float(el.get("dir.x", "0")),
|
|
dir_y=float(el.get("dir.y", "0")),
|
|
value=float(el.get("value", "0")),
|
|
actual_value=float(el.get("actualValue", "0")),
|
|
is_set=el.get("isSet", "0") == "1",
|
|
)
|
|
|
|
|
|
def _parse_exploded_wall(el: ET.Element) -> MagicPlanExplodedWall:
|
|
type_el = el.find("type")
|
|
return MagicPlanExplodedWall(
|
|
wall_type=(type_el.text or "") if type_el is not None else "",
|
|
points=[_parse_wall_point(p) for p in el.findall("point")],
|
|
)
|
|
|
|
|
|
def _parse_exploded(el: ET.Element) -> MagicPlanExploded:
|
|
return MagicPlanExploded(
|
|
walls=[_parse_exploded_wall(w) for w in el.findall("wall")],
|
|
doors=[_parse_exploded_opening(d) for d in el.findall("door")],
|
|
windows=[_parse_exploded_opening(w) for w in el.findall("window")],
|
|
furniture=[_parse_furniture(f) for f in el.findall("furniture")],
|
|
)
|
|
|
|
|
|
def _parse_symbol_instance(el: ET.Element) -> MagicPlanSymbolInstance:
|
|
return MagicPlanSymbolInstance(
|
|
id=el.get("id", ""),
|
|
uid=el.get("uid", ""),
|
|
parent_uid=el.get("parentUid", ""),
|
|
symbol=el.get("symbol", ""),
|
|
values=_values(el),
|
|
)
|
|
|
|
|
|
def _parse_floor(el: ET.Element) -> MagicPlanFloor:
|
|
si_el = el.find("symbolInstance")
|
|
exploded_el = el.find("exploded")
|
|
return MagicPlanFloor(
|
|
uid=el.get("uid", ""),
|
|
name=el.findtext("name") or "",
|
|
floor_type=el.get("floorType", "0"),
|
|
rotation=float(el.get("rotation", "0")),
|
|
compass_angle=float(el.get("compassAngle", "0")),
|
|
area_without_walls=float(el.get("areaWithoutWalls", "0")),
|
|
area_with_interior_walls_only=float(el.get("areaWithInteriorWallsOnly", "0")),
|
|
area_with_walls=float(el.get("areaWithWalls", "0")),
|
|
symbol_instance=_parse_symbol_instance(si_el) if si_el is not None
|
|
else MagicPlanSymbolInstance(id="", uid="", parent_uid="", symbol="", values={}),
|
|
rooms=[_parse_room(r) for r in el.findall("floorRoom")],
|
|
furniture=[_parse_furniture(f) for f in el.findall("furniture")],
|
|
exploded=_parse_exploded(exploded_el) if exploded_el is not None
|
|
else MagicPlanExploded(walls=[], doors=[], windows=[], furniture=[]),
|
|
)
|
|
|
|
|
|
def _parse_room(el: ET.Element) -> MagicPlanRoom:
|
|
return MagicPlanRoom(
|
|
uid=el.get("uid", ""),
|
|
type=el.get("type", ""),
|
|
x=float(el.get("x", "0")),
|
|
y=float(el.get("y", "0")),
|
|
rotation=float(el.get("rotation", "0")),
|
|
was_modified=el.get("wasModified", "0") == "1",
|
|
linked_room_0=el.get("linkedRoom0", "-1"),
|
|
linked_room_1=el.get("linkedRoom1", "-1"),
|
|
area=float(el.get("area", "0")),
|
|
perimeter=float(el.get("perimeter", "0")),
|
|
values=_values(el),
|
|
points=[_parse_room_point(p) for p in el.findall("point")],
|
|
doors=[_parse_door(d) for d in el.findall("door")],
|
|
windows=[_parse_window(w) for w in el.findall("window")],
|
|
furniture=[_parse_furniture(f) for f in el.findall("furniture")],
|
|
main_dimensions=[_parse_main_dimension(d) for d in el.findall("mainDimension")],
|
|
)
|
|
|
|
|
|
def parse_magicplan_xml(xml_str: str) -> MagicPlanPlan:
|
|
root = ET.fromstring(xml_str)
|
|
irp_el = root.find("interiorRoomPoints")
|
|
return MagicPlanPlan(
|
|
id=root.get("id", ""),
|
|
uid=root.get("uid", ""),
|
|
name=root.get("name", ""),
|
|
type=root.get("type", ""),
|
|
interior_wall_width=float(root.get("interiorWallWidth", "0")),
|
|
exterior_wall_width=float(root.get("exteriorWallWidth", "0")),
|
|
schematic=root.get("schematic", "0") == "1",
|
|
has_land_survey_address=root.get("hasLandSurveyAddress", "0") == "1",
|
|
last_patch_identifier=root.get("lastPatchIdentifier", ""),
|
|
last_roll_identifier=root.get("lastRollIdentifier", ""),
|
|
values=_values(root),
|
|
floors=[_parse_floor(f) for f in root.findall("floor")],
|
|
interior_room_floors=[_parse_floor(f) for f in irp_el.findall("floor")]
|
|
if irp_el is not None else [],
|
|
)
|