dict_manager.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. import json
  2. import random
  3. import time
  4. from abc import ABC, abstractmethod
  5. import yaml
  6. from tqdm import tqdm
  7. import core
  8. from core import distance
  9. from entity.Line import Line
  10. from entity.Node import Node
  11. from entity.primitives import Tun2d, Window, Gate, Sealed, WindBridge, TunText, AirFlow, Shaft, Fan, AirDuct, Drill, \
  12. Face, Empty
  13. standard_width = 5
  14. class DictManager(ABC):
  15. def __init__(self, original_data):
  16. self.original_data = original_data
  17. self.layer_map = self.get_layer_map()
  18. self.tun_dict = {}
  19. self.air_flow_list = []
  20. self.window_list = []
  21. self.auto_window_list = []
  22. self.gate_list = []
  23. self.auto_gate_list = []
  24. self.fan_list = []
  25. self.wind_bridge_list = []
  26. self.air_duct_list = []
  27. self.sealed_list = []
  28. self.tun_text_list = []
  29. self.air_duct_list = []
  30. self.drill_list = []
  31. self.face_list = []
  32. self.empty_list = []
  33. def get_layer_map(self):
  34. layer_list = self.original_data["layerMap"]
  35. layer_map = {}
  36. div_index = 0
  37. for layer in layer_list:
  38. layer[1]['divIndex'] = div_index
  39. layer_map[layer[0]] = layer[1]
  40. div_index = div_index + 1
  41. return layer_map
  42. class DictManger2D(DictManager):
  43. def __init__(self, original_data):
  44. super().__init__(original_data)
  45. self.shaft_list = []
  46. self.get_tuns()
  47. self.get_tun_text()
  48. self.get_windows()
  49. self.get_gates()
  50. self.get_sealed()
  51. self.get_wind_bridges()
  52. self.get_air_flow()
  53. self.get_shaft()
  54. self.get_fans()
  55. self.get_duct_list()
  56. self.get_drill_line()
  57. self.get_face_empty()
  58. def get_tuns(self):
  59. node_list = self.original_data["tunsMap"]
  60. for node in tqdm(node_list, desc=' 【巷道读取中】'):
  61. node = node[1]
  62. if node["tunType"] == '1': continue
  63. if len(node["vec34"]) < 2: continue
  64. divIndex = self.layer_map[node['nlayerid']]['divIndex']
  65. color = self.layer_map[node['nlayerid']]['ncolor']
  66. color = core.hex_to_rgb(color)
  67. from_ = (node["nfrom"]["x"], node["nfrom"]["z"])
  68. to_ = (node["nto"]["x"], node["nto"]["z"])
  69. vec_middle = from_, to_
  70. center = core.find_point_on_line(from_, to_, 1 / 2)
  71. #
  72. center_node = Node(center, '2d', divIndex)
  73. middle_line = Line(vec_middle, '2d', divIndex)
  74. vec12_ = (node["vec12"][0]['x'], node["vec12"][0]['z']), (node["vec12"][1]['x'], node["vec12"][1]['z'])
  75. vec34_ = (node["vec34"][0]['x'], node["vec34"][0]['z']), (node["vec34"][1]['x'], node["vec34"][1]['z'])
  76. width = core.min_distance_between_segments(vec12_, vec34_)
  77. vec_list = []
  78. layer_vec_list = []
  79. if 'headVecList' in node and node['headVecList'] is not None:
  80. vec_head_ = (node['headVecList'][0]["x"], node['headVecList'][0]["z"]), (
  81. node['headVecList'][1]["x"], node['headVecList'][1]["z"])
  82. vec_head_line = Line(vec_head_, '2d', divIndex)
  83. else:
  84. NoneLine = (0, 0), (0, 0)
  85. vec_head_line = Line(NoneLine, '2d', divIndex)
  86. vec_list.append(vec_head_line)
  87. layer_vec_list.append(vec_head_line)
  88. for i in range(0, len(node["vec12"]), 2):
  89. vec12_ = (node["vec12"][i]['x'], node["vec12"][i]['z']), (
  90. node["vec12"][i + 1]['x'], node["vec12"][i + 1]['z'])
  91. vec12_line = Line(vec12_, '2d', divIndex)
  92. vec_list.append(vec12_line)
  93. for i in range(0, len(node["vec34"]), 2):
  94. vec34_ = (node["vec34"][i]['x'], node["vec34"][i]['z']), (
  95. node["vec34"][i + 1]['x'], node["vec34"][i + 1]['z'])
  96. vec34_line = Line(vec34_, '2d', divIndex)
  97. vec_list.append(vec34_line)
  98. for i in range(0, len(node["layerVec12"]), 2):
  99. vec12_ = (node["layerVec12"][i]['x'], node["layerVec12"][i]['z']), (
  100. node["layerVec12"][i + 1]['x'], node["layerVec12"][i + 1]['z'])
  101. vec12_line = Line(vec12_, '2d', divIndex)
  102. layer_vec_list.append(vec12_line)
  103. for i in range(0, len(node["layerVec34"]), 2):
  104. vec34_ = (node["layerVec34"][i]['x'], node["layerVec34"][i]['z']), (
  105. node["layerVec34"][i + 1]['x'], node["layerVec34"][i + 1]['z'])
  106. vec34_line = Line(vec34_, '2d', divIndex)
  107. layer_vec_list.append(vec34_line)
  108. tun = Tun2d(node["ntunid"], node["nlayerid"], node["strname"], center_node, middle_line, vec_list,
  109. layer_vec_list,
  110. node['fq'], color, width, node["arrowShow"], node['nairtype'])
  111. self.tun_dict[tun.id] = tun
  112. def _process_vent_graph(self, layer_map, item_type, desc, callback):
  113. """
  114. 通用方法:处理 layer_map 中的 items(windows 或 gates)
  115. :param layer_map: 图层映射数据
  116. :param item_type: 项目类型('windows' 或 'gates')
  117. :param desc: tqdm 进度条描述
  118. :param callback: 处理每个项目的回调函数
  119. """
  120. for layer in tqdm(layer_map, desc=desc):
  121. items = layer[1][item_type]
  122. for item in items:
  123. tun = self.tun_dict.get(item["ntunid"])
  124. if tun is None:
  125. continue
  126. divIndex = self.layer_map[item['nlayerid']]['divIndex']
  127. center = Node((item['x'], item['z']), '2d', divIndex)
  128. color = core.hex_to_rgb(self.layer_map[item['nlayerid']]['ncolor'])
  129. # 调用回调函数处理具体逻辑
  130. callback(item, tun, center, color)
  131. def get_windows(self):
  132. """
  133. 获取风窗数据
  134. """
  135. def process_window(window, tun, center, color):
  136. window_obj = Window(
  137. window['id'], window["nlayerid"], window["strname"],
  138. center, tun.middle_line, tun.width, color
  139. )
  140. if window['bautowindow'] ==1:
  141. self.auto_window_list.append(window_obj)
  142. else:
  143. self.window_list.append(window_obj)
  144. self._process_vent_graph(self.original_data["layerMap"], 'windows', '【风窗读取中】', process_window)
  145. def get_gates(self):
  146. """
  147. 获取门数据
  148. """
  149. def process_gate(gate, tun, center, color):
  150. gate_obj = Gate(
  151. gate['id'], gate["nlayerid"], gate["strname"],
  152. center, tun.middle_line, tun.width, color
  153. )
  154. if gate['ndoortype'] ==1:
  155. self.auto_gate_list.append(gate_obj)
  156. else:
  157. self.gate_list.append(gate_obj)
  158. self._process_vent_graph(self.original_data["layerMap"], 'gates', '【风门读取中】', process_gate)
  159. def get_sealed(self):
  160. def process_sealed(sealed, tun, center, color):
  161. sealed_obj = Sealed(
  162. sealed['id'], sealed["nlayerid"], sealed["strname"],
  163. center, tun.middle_line, tun.width, color, tun.id
  164. )
  165. self.sealed_list.append(sealed_obj)
  166. self._process_vent_graph(self.original_data["layerMap"], 'obfurages', '【密闭读取中】', process_sealed)
  167. def get_wind_bridges(self):
  168. for layer in tqdm(self.original_data['layerMap'], '【风桥读取中】'):
  169. layer = layer[1]
  170. wb_list = layer['crossNodes']
  171. for wb in wb_list:
  172. divIndex = self.layer_map[wb['layerId']]['divIndex']
  173. center = Node((wb['crossPoint']['x'], -wb['crossPoint']['y']), '2d', divIndex)
  174. tun = self.tun_dict.get(wb['tun1Id'])
  175. color = self.layer_map[wb['layerId']]['ncolor']
  176. color = core.hex_to_rgb(color)
  177. wb_obj = WindBridge(
  178. wb['tun1Id'], wb['layerId'], '', center, tun.middle_line, tun.width, color
  179. )
  180. self.wind_bridge_list.append(wb_obj)
  181. def get_tun_text(self):
  182. node_list = self.original_data["tunsMap"]
  183. tun_text_dict = {}
  184. for node in tqdm(node_list, desc=' 【巷道文字读取中】'):
  185. node = node[1]
  186. if node["tunType"] == '1': continue
  187. tun = self.tun_dict.get(node["ntunid"])
  188. if tun is None: continue
  189. # if node['nusingtype'] == "1":
  190. # fq = node['freportq'] * 60
  191. # else:
  192. fq = node['fq'] * 60
  193. formatted_fq = round(fq, 1)
  194. tun.fq = formatted_fq
  195. fq_text = str(formatted_fq) + "m³/min"
  196. fq_v = node['fq']
  197. tun_key = node["strname"] + " " + fq_text
  198. if tun_key not in tun_text_dict:
  199. # 如果不在,则初始化一个新的空列表作为值
  200. tun_text_dict[tun_key] = {
  201. "id": tun.id,
  202. "text": node["strname"] + " " + fq_text,
  203. "name": tun.name,
  204. "layer_id": tun.layer_id,
  205. "width": standard_width,
  206. "color": tun.color,
  207. "value": formatted_fq,
  208. "tun_middle_lines": []
  209. }
  210. from_ = (node["nfrom"]["x"], node["nfrom"]["z"])
  211. to_ = (node["nto"]["x"], node["nto"]["z"])
  212. # 将 from_ 和 to_ 坐标添加到 tun_text 对应的列表中
  213. tun_text_dict[tun_key]['tun_middle_lines'].extend([from_, to_])
  214. for tun_text in tqdm(tun_text_dict.values(), desc=' 【巷道文字读取中】'):
  215. tun_middle_lines = tun_text['tun_middle_lines']
  216. divIndex = self.layer_map[tun_text['layer_id']]['divIndex']
  217. center = core.find_point_on_line(tun_middle_lines[0], tun_middle_lines[1], 1 / 2)
  218. #
  219. center_node = Node(center, '2d', divIndex)
  220. middle_line = Line(tun_middle_lines, '2d', divIndex)
  221. tt = TunText(tun_text['id'], tun_text['layer_id'], tun_text['text'], center_node, middle_line,
  222. tun_text['width'], tun_text['color'], tun_text['value'])
  223. tun_length = core.distance(tun_middle_lines[0], tun_middle_lines[1])
  224. text_len = len(tun_text['text']) * float(tun_text['width'])
  225. if tun_length * 0.8 > text_len:
  226. self.tun_text_list.append(tt)
  227. def get_air_flow(self):
  228. sealed_tun_ids = [obj.from_tun_id for obj in self.sealed_list]
  229. for tun in tqdm(self.tun_dict.values(), '【风流读取中】'):
  230. if tun.arrow_show == 0: continue;
  231. if tun.id in sealed_tun_ids: continue # 密闭空间不画风流
  232. if tun.fq == 0: continue
  233. tun_len = core.distance(tun.middle_line.original_line[0], tun.middle_line.original_line[1])
  234. if tun_len < 7 * tun.width: continue
  235. divIndex = self.layer_map[tun.layer_id]['divIndex']
  236. if tun_len < 50 * tun.width:
  237. center = tun.center
  238. air_flow = AirFlow(core.get_random_id(), tun.layer_id, '', center, tun.middle_line, tun.width,
  239. tun.color, tun.air_type)
  240. self.air_flow_list.append(air_flow)
  241. else:
  242. space = int(tun_len // (50 * tun.width))
  243. points = core.divide_segment(tun.middle_line.original_line[0], tun.middle_line.original_line[1], space)[
  244. 1:-1]
  245. for i in range(len(points)):
  246. center = Node(points[i], '2d', divIndex)
  247. air_flow = AirFlow(core.get_random_id(), tun.layer_id, '', center, tun.middle_line, standard_width,
  248. tun.color,
  249. tun.air_type)
  250. self.air_flow_list.append(air_flow)
  251. def get_shaft(self):
  252. node_list = self.original_data["tunsMap"]
  253. for node in tqdm(node_list, desc=' 【立井读取中】'):
  254. node = node[1]
  255. if node["tunType"] == '1':
  256. divIndex = self.layer_map[node["nlayerid"]]['divIndex']
  257. center = Node((node["nfrom"]["x"], node["nfrom"]["z"]), '2d', divIndex)
  258. color = self.layer_map[node['nlayerid']]['ncolor']
  259. color = core.hex_to_rgb(color)
  260. none_line = Line(((0, 0), (0, 0)), '2d', 0)
  261. shaft = Shaft(node["ntunid"], node["nlayerid"], node["strname"], center, none_line, node["fwidth"],
  262. color)
  263. self.shaft_list.append(shaft)
  264. def get_fans(self):
  265. def process(fan, tun, center, color):
  266. fan_obj = Fan(
  267. fan['id'], fan["nlayerid"], fan["strname"],
  268. center, tun.middle_line, tun.width, color, fan['strtype']
  269. )
  270. self.fan_list.append(fan_obj)
  271. self._process_vent_graph(self.original_data["layerMap"], 'fans', '【风扇扇读取中】', process)
  272. def get_duct_list(self):
  273. layer_map = self.original_data["layerMap"]
  274. for layer in tqdm(layer_map, desc=' 【风筒读取中】'):
  275. fans = layer[1]["fans"]
  276. for f in fans:
  277. if 'fanlocal' not in f['strtype']: continue
  278. tun = self.tun_dict.get(f["ntunid"])
  279. if tun is None: continue
  280. path_list = []
  281. divIndex = self.layer_map[f['nlayerid']]['divIndex']
  282. for path in f['localFanCylinderPath']:
  283. from_to = (path[0]['x'], path[0]['z']), (path[1]['x'], path[1]['z'])
  284. path_line = Line(from_to, '2d', divIndex)
  285. path_list.append(path_line)
  286. no_center = Node((0, 0), '2d', divIndex)
  287. no_line = Line(((0, 0), (0, 0)), '2d', divIndex)
  288. air_duct = AirDuct(f['id'], f['nlayerid'], f['strname'], no_center, no_line, tun.width, tun.color,
  289. path_list)
  290. self.air_duct_list.append(air_duct)
  291. def get_drill_line(self):
  292. layer_map = self.original_data["layerMap"]
  293. for layer in tqdm(layer_map, desc='【钻孔轨迹读取中】'):
  294. if "specialdevices" not in layer[1]: continue
  295. specialdevices = layer[1]['specialdevices']
  296. for device in specialdevices:
  297. if "drills" not in device: continue
  298. drills = device['drills']
  299. for drill in drills:
  300. id_ = drill['id']
  301. layer_id = layer[0]
  302. divIndex = self.layer_map[layer_id]['divIndex']
  303. path_list = []
  304. for zk in drill['zkList']:
  305. node_list = []
  306. for n in zk:
  307. node = Node((n['x'], n['z']), '2d', divIndex)
  308. node_list.append(node)
  309. path_list.append(node_list)
  310. drill_obj = Drill(id_, layer_id, path_list, (0, 0, 0))
  311. self.drill_list.append(drill_obj)
  312. def get_face_empty(self):
  313. layer_map = self.original_data["layerMap"]
  314. for layer in tqdm(layer_map, desc='【钻孔轨迹读取中】'):
  315. if "specialdevices" not in layer[1]: continue
  316. specialdevices = layer[1]['specialdevices']
  317. for device in specialdevices:
  318. if "position" not in device: continue
  319. layer_id = device['nlayerid']
  320. divIndex = self.layer_map[layer_id]['divIndex']
  321. position = device['position']
  322. json_obj = json.loads(position)
  323. node_list = []
  324. if "tunPaths" not in json_obj: continue
  325. for n in json_obj['tunPaths']:
  326. node = Node((n['x'], n['z']), '2d', divIndex)
  327. node_list.append(node)
  328. face = Face(layer_id, node_list, (255, 255, 255))
  329. self.face_list.append(face)
  330. node_list = []
  331. if "emptyPaths" not in json_obj: continue
  332. for n in json_obj['emptyPaths']:
  333. node = Node((n['x'], n['z']), '2d', divIndex)
  334. node_list.append(node)
  335. empty = Empty(layer_id, node_list, (255, 255, 255))
  336. self.empty_list.append(empty)
  337. # drill_obj = Face(id_, layer_id, path_list, (0, 0, 0))
  338. # for drill in drills:
  339. # id_ = drill['id']
  340. # layer_id = layer[0]
  341. # divIndex = self.layer_map[layer_id]['divIndex']
  342. # path_list = []
  343. # for zk in drill['zkList']:
  344. # node_list = []
  345. # for n in zk:
  346. # node = Node((n['x'],n['z']),'2d',divIndex)
  347. # node_list.append(node)
  348. # path_list.append(node_list)
  349. # drill_obj = Drill(id_,layer_id,path_list,(0,0,0))
  350. # self.drill_list.append(drill_obj)