|
@@ -0,0 +1,119 @@
|
|
|
+
|
|
|
+from shapely.geometry import Polygon
|
|
|
+import json
|
|
|
+
|
|
|
+
|
|
|
+column_space_id = 'space_id'
|
|
|
+column_outline = 'outline'
|
|
|
+column_floor_id = 'floor_id'
|
|
|
+column_revit_id = 'revit_id'
|
|
|
+
|
|
|
+
|
|
|
+# 获取Polygon对象
|
|
|
+def get_polygon(single_poly):
|
|
|
+ poly_len = len(single_poly)
|
|
|
+ poly = []
|
|
|
+ for i in range(poly_len):
|
|
|
+ pair = single_poly[i]
|
|
|
+ poly.append((pair["X"], pair["Y"]))
|
|
|
+ return Polygon(poly)
|
|
|
+
|
|
|
+# 在polygon1包含polygon2的时候, 检测是否polygon1内的空洞也包含polygon2
|
|
|
+def is_include(polygon1, poly2):
|
|
|
+ length1 = len(polygon1)
|
|
|
+ for i in range(1, length1):
|
|
|
+ poly1 = get_polygon(polygon1[i])
|
|
|
+ if poly1.overlaps(poly2):
|
|
|
+ return True
|
|
|
+ if poly1.equals(poly2) or poly1.contains(poly2):
|
|
|
+ return False
|
|
|
+ return True
|
|
|
+
|
|
|
+def is_sub_outline_overlap(polygon1, polygon2):
|
|
|
+ poly1 = get_polygon(polygon1[0])
|
|
|
+ poly2 = get_polygon(polygon2[0])
|
|
|
+ if poly1.overlaps(poly2) or poly1.equals(poly2):
|
|
|
+ return True
|
|
|
+ if poly1.contains(poly2) or poly1.equals(poly2):
|
|
|
+ return is_include(polygon1, poly2)
|
|
|
+ if poly2.contains(poly1) or poly2.equals(poly1):
|
|
|
+ return is_include(polygon2, poly1)
|
|
|
+ return False
|
|
|
+
|
|
|
+# 是否面积有重叠
|
|
|
+def is_overlap(polygon1, ispace_polygon):
|
|
|
+ length1 = len(polygon1)
|
|
|
+ length2 = len(ispace_polygon)
|
|
|
+ if length1 == 0 or length2 == 0:
|
|
|
+ return False
|
|
|
+
|
|
|
+ for i in range(length1):
|
|
|
+ for j in range(length2):
|
|
|
+ if is_sub_outline_overlap(polygon1[i], ispace_polygon):
|
|
|
+ return True
|
|
|
+ return False
|
|
|
+
|
|
|
+# 根据业务空间轮廓和元空间轮廓是否有重叠部分来判断关系
|
|
|
+# 返回dict, 格式 {space_id --> {ispace_id}}
|
|
|
+def build_rel_space_ispace(space_data, ispace_data):
|
|
|
+ rel_dict = {}
|
|
|
+ for space in space_data:
|
|
|
+ space_id = space.get(column_space_id)
|
|
|
+ for ispace in ispace_data:
|
|
|
+ space_outline = json.loads(space.get(column_outline))
|
|
|
+ ispace_outline = json.loads(ispace.get(column_outline))
|
|
|
+ if is_overlap(space_outline, ispace_outline):
|
|
|
+ if space_id not in rel_dict:
|
|
|
+ rel_dict[space_id] = set()
|
|
|
+ revit_set = rel_dict.get(space_id)
|
|
|
+ revit_set.add(ispace.get(column_revit_id))
|
|
|
+ return rel_dict
|
|
|
+
|
|
|
+# 返回被删除的元空间的revit_id
|
|
|
+def get_deleted_ispace_revit_id(new_ispace_data, prev_ispace_data):
|
|
|
+ deleted = []
|
|
|
+ prev_ispace_revit_id_set = set()
|
|
|
+ for prev_ispace in prev_ispace_data:
|
|
|
+ prev_ispace_revit_id_set.add(prev_ispace.get(column_revit_id))
|
|
|
+ for new_ispace in new_ispace_data:
|
|
|
+ prev_id = new_ispace.get(column_revit_id)
|
|
|
+ if prev_id in prev_ispace_revit_id_set:
|
|
|
+ prev_ispace_revit_id_set.remove(prev_id)
|
|
|
+ deleted.extend(prev_ispace_revit_id_set)
|
|
|
+ return deleted
|
|
|
+
|
|
|
+# 返回被修改的元空间的revit_id
|
|
|
+def get_updated_ispace_revit_id(new_ispace_data, prev_ispace_data):
|
|
|
+ updated = []
|
|
|
+ new_ispace_dict = {}
|
|
|
+ prev_ispace_dict = {}
|
|
|
+ for prev_ispace in prev_ispace_data:
|
|
|
+ prev_id = prev_ispace.get(column_revit_id)
|
|
|
+ prev_outline = json.loads(prev_ispace.get(column_revit_id))
|
|
|
+ prev_ispace_dict[prev_id] = prev_outline
|
|
|
+ for new_ispace in new_ispace_data:
|
|
|
+ new_id = new_ispace.get(column_revit_id)
|
|
|
+ new_outline = json.loads(new_ispace.get(column_revit_id))
|
|
|
+ new_ispace_dict[new_id] = new_outline
|
|
|
+ for prev_id, prev_outline in prev_ispace_dict.items():
|
|
|
+ if prev_id in new_ispace_dict:
|
|
|
+ new_outline = new_ispace_dict.get(prev_id)
|
|
|
+ prev_poly = get_polygon(prev_outline[0])
|
|
|
+ new_poly = get_polygon(new_outline[0])
|
|
|
+ if not prev_poly.equals(new_poly):
|
|
|
+ updated.append(prev_id)
|
|
|
+ return updated
|
|
|
+
|
|
|
+# 获取受影响的业务空间的id数组
|
|
|
+# space_data是可能受影响的业务空间的数据, new_ispace_data 是新模型的元空间数据, prev_ispace_data是上一个模型的元空间数据
|
|
|
+def get_affected_spaced(space_data, new_ispace_data, prev_ispace_data):
|
|
|
+ affected_spaces = []
|
|
|
+ space_ispace_rel = build_rel_space_ispace(space_data, prev_ispace_data)
|
|
|
+ affected_ispace_revit_id = get_deleted_ispace_revit_id(new_ispace_data, prev_ispace_data)
|
|
|
+ affected_ispace_revit_id.extend(get_updated_ispace_revit_id(new_ispace_data, prev_ispace_data))
|
|
|
+ for space_id, ispace_id_dict in space_ispace_rel.items():
|
|
|
+ for revit_id in affected_ispace_revit_id:
|
|
|
+ if revit_id in ispace_id_dict:
|
|
|
+ affected_spaces.append(space_id)
|
|
|
+ break
|
|
|
+ return affected_spaces
|