-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathBimDataModel.py
110 lines (86 loc) · 3.27 KB
/
BimDataModel.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
from dataclasses import dataclass
from enum import Enum, unique
from typing import Sequence, List, Tuple
from uuid import UUID
import json
@dataclass(frozen=True) # pyright: ignore [reportUntypedClassDecorator, reportGeneralTypeIssues]
class BPoint:
x: float
y: float
z: float = 0.0
@staticmethod
def from_simple_point(p: Tuple[float, float]) -> "BPoint":
return BPoint(p[0], p[1]) # pyright: ignore [reportGeneralTypeIssues]
@unique
class BSign(Enum):
DoorWay = 0
DoorWayInt = 1
DoorWayOut = 2
Room = 3
Staircase = 4
@classmethod
def from_str(cls, name: str) -> "BSign":
return cls[name]
@dataclass(frozen=True)
class BBuildElement:
id: UUID
sign: BSign
output: List[UUID]
points: List[BPoint]
name: str = ""
sizeZ: float = 0.0
@dataclass(frozen=True)
class BLevel:
name: str
elements: Sequence[BBuildElement]
zlevel: float = 0.0
@dataclass(frozen=True)
class BBuilding:
levels: Sequence[BLevel]
name: str
addr: str = ""
class JsonParseError(ValueError):
def __init__(self, *args: object) -> None:
super().__init__(*args)
def mapping_building(file_buildingjson: str) -> BBuilding:
building: BBuilding
bad_elements: List[Tuple[BSign, str, str, str]] = list()
with open(file_buildingjson, "r", encoding="utf8") as json_file:
rjson = json.load(json_file)
_levels: List[BLevel] = list()
for level in rjson["Level"]:
_elements: List[BBuildElement] = list()
for element in level["BuildElement"]:
_sign = BSign.from_str(element["Sign"])
_sizeZ = element["SizeZ"] if not (_sign == BSign.DoorWay) else 0.0
try:
build_element = BBuildElement(
id=UUID(element["Id"]),
sign=_sign,
name=element["Name"],
sizeZ=_sizeZ,
output=[UUID(uuid) for uuid in element["Output"]],
points=[
BPoint(p["x"], p["y"], level["ZLevel"]) # pyright: ignore [reportGeneralTypeIssues]
for p in element["XY"][0]["points"]
],
)
_elements.append(build_element)
except JsonParseError:
bad_elements.append((_sign, element["Name"], element["Id"], level["ZLevel"]))
_levels.append(BLevel(name=level["NameLevel"], zlevel=level["ZLevel"], elements=_elements))
building = BBuilding(name=rjson["NameBuilding"], levels=_levels)
if len(bad_elements) > 0:
import inspect
from types import FrameType
from typing import Union
frame: Union[FrameType, None] = inspect.currentframe()
print(
f">UnknownException[{__file__}:{frame.f_lineno if frame is not None else ()}]. Please check elements from list bellow:"
)
for sign, name, id, level in bad_elements:
print(f"{sign.name}({id}), name={name}, level={level})")
print(">>QGIS expression for find bad elements (use 'Select Features Using Expression'):")
print(" or ".join(f"id is '{id}'" for _, _, id, _ in bad_elements))
exit()
return building