瀏覽代碼

Merge remote-tracking branch 'origin/master'

jxing 5 年之前
父節點
當前提交
eed9183791
共有 3 個文件被更改,包括 269 次插入219 次删除
  1. 20 20
      src/affected_space/affected_space.py
  2. 174 165
      src/affected_space/function.py
  3. 75 34
      src/affected_space/test.py

+ 20 - 20
src/affected_space/affected_space.py

@@ -6,7 +6,7 @@ import json
 column_space_id = 'space_id'
 column_outline = 'outline'
 column_floor_id = 'floor_id'
-column_revit_id = 'revit_id'
+column_source_id = 'source_id'
 
 
 # 获取Polygon对象
@@ -66,34 +66,34 @@ def build_rel_space_ispace(space_data, ispace_data):
                 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))
+                revit_set.add(ispace.get(column_source_id))
     return rel_dict
 
-# 返回被删除的元空间的revit_id
-def get_deleted_ispace_revit_id(new_ispace_data, prev_ispace_data):
+# 返回被删除的元空间的source_id
+def get_deleted_ispace_source_id(new_ispace_data, prev_ispace_data):
     deleted = []
-    prev_ispace_revit_id_set = set()
+    prev_ispace_source_id_set = set()
     for prev_ispace in prev_ispace_data:
-        prev_ispace_revit_id_set.add(prev_ispace.get(column_revit_id))
+        prev_ispace_source_id_set.add(prev_ispace.get(column_source_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)
+        prev_id = new_ispace.get(column_source_id)
+        if prev_id in prev_ispace_source_id_set:
+            prev_ispace_source_id_set.remove(prev_id)
+    deleted.extend(prev_ispace_source_id_set)
     return deleted
 
-# 返回被修改的元空间的revit_id
-def get_updated_ispace_revit_id(new_ispace_data, prev_ispace_data):
+# 返回被修改的元空间的source_id
+def get_updated_ispace_source_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_id = prev_ispace.get(column_source_id)
+        prev_outline = json.loads(prev_ispace.get(column_outline))
         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_id = new_ispace.get(column_source_id)
+        new_outline = json.loads(new_ispace.get(column_outline))
         new_ispace_dict[new_id] = new_outline
     for prev_id, prev_outline in prev_ispace_dict.items():
         if prev_id in new_ispace_dict:
@@ -109,11 +109,11 @@ def get_updated_ispace_revit_id(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))
+    affected_ispace_source_id = get_deleted_ispace_source_id(new_ispace_data, prev_ispace_data)
+    affected_ispace_source_id.extend(get_updated_ispace_source_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:
+        for source_id in affected_ispace_source_id:
+            if source_id in ispace_id_dict:
                 affected_spaces.append(space_id)
                 break
     return affected_spaces

+ 174 - 165
src/affected_space/function.py

@@ -1,182 +1,191 @@
 # floor_id 是revit的楼层id
 
-CREATE OR REPLACE FUNCTION rel_affected_space(project_id character varying, floor_id character varying) RETURNS boolean AS
+CREATE OR REPLACE FUNCTION rel_affected_space(floor_id character varying) RETURNS boolean AS
 $$
+from relations.src.affected_space.affected_space import get_affected_spaced
 from shapely.geometry import Polygon
 import json
 
-# try:
-# 获取当前楼层绑定的数据中心楼层的id
-floor_plan = plpy.prepare("SELECT current_model_id, bind_floor_ids FROM revit.model_floor where id = $1", ["text"])
-floor_data = floor_plan.execute([floor_id])
-if len(floor_data) != 1:
-    plpy.info("no floor")
-    return True
-floor_arr = json.loads(floor_data[0]['bind_floor_ids'])
-if len(floor_arr) == 0:
-    plpy.info("no binding floor")
-    return True
-floor_str = ""
-for fl in floor_arr:
-    floor_str = (floor_str + fl + ',')
-floor_str = floor_str.strip(',')
-plpy.info(floor_str)
-# 获取当前模型和前一个版本的模型id
-model_plan = plpy.prepare("select id from revit.model_file where model_floor_id = $1 and removed = false and status = 4 and version is not null order by version desc", ["text"])
-model_data = model_plan.execute([floor_id], 2)
-if len(model_data) != 2:
-    plpy.info("no previous model")
-    return True
-sql_str = "select rel.floor_id, rel.space_id, sp.outline from r_sp_in_fl rel left join zone_space_base sp on rel.space_id = sp.id where rel.floor_id in (" + floor_str + ")"
-# 查询出来的跟模型可能相关的所有业务空间
-space_data = plpy.execute(sql_str)
-if len(space_data) == 0:
-    plpy.info("no space relation under binding floor")
-    return True
-plpy.info(space_data)
-plpy.info(len(space_data))
-# 获取新模型的元空间
-new_ispace_plan = plpy.prepare("select revit_id, outline where model_id = $1", ["text"])
-new_ispace_data = new_ispace_plan.execute([model_data[0]['id']])
-
-# 获取旧模型的所有元空间
-prev_ispace_plan = plpy.prepare("select revit_id, outline where model_id = $1", ["text"])
-prev_ispace_data = prev_ispace_plan.execute([model_data[1]['id']])
-
-affected_space_ids = get_affected_spaced(space_data, new_ispace_data, prev_ispace_data)
-
-plpy.info(affected_space_ids)
-for space_id in affected_space_ids:
-    space_plan = plpy.prepare("update zone_space_base set state = 1 where id = $1", ["text"])
-    space_plan.execute([space_id])
-
-return True
-# except Exception as e:
-#     plpy.info(e)
-#     return False
-$$
-LANGUAGE 'plpython3u' VOLATILE;
-
-space_outline_json_map = dict()
-result_arr = []
-# 每个楼层的每个业务空间分别和别的楼层的每个业务空间判断is_vertically_overlap
-# 将结果是true的两个业务空间保存起来
-for building_id, floor_map in row_map.items():
-    for floor_id, type_map in floor_map.items():
-        for object_type, row_arr in type_map.items():
-            # 要被对比的楼层
-            for other_floor_id in floor_map.keys():
-                if other_floor_id == floor_id:
-                    continue
-                other_type_map = floor_map.get(other_floor_id)
-                if object_type not in other_type_map:
-                    continue
-                other_row_arr = other_type_map.get(object_type)
-                for row in row_arr:
-                    for other_row in other_row_arr:
-                        space_id = row['space_id']
-                        other_space_id = other_row['space_id']
-                        if space_id == other_space_id:
-                            continue
-                        if space_id not in space_outline_json_map:
-                            outline_json = json.loads(row['outline'])
-                            space_outline_json_map[space_id] = outline_json
-                        if other_space_id not in space_outline_json_map:
-                            other_outline_json = json.loads(other_row['outline'])
-                            space_outline_json_map[other_space_id] = other_outline_json
-                        outline = space_outline_json_map[space_id]
-                        other_outline = space_outline_json_map[other_space_id]
-                        if is_vertically_overlap(outline, other_outline):
-                            single_result = []
-                            single_result.append(space_id)
-                            single_result.append(other_space_id)
-                            single_result.append(object_type)
-                            result_arr.append(single_result)
-if len(result_arr) == 0:
-    return True
-# 删除旧业务空间的垂直交通关系(自动计算的), 添加新关系
-# 将下面对数据库的操作作为一个事务, 出异常则自动rollback
-with plpy.subtransaction():
-    del_plan = plpy.prepare("delete from r_sp_vertical_sp where project_id = $1 and sign = 2", ["text"])
-    del_plan.execute([project_id])
-    for single_result in result_arr:
-        del_manual_plan = plpy.prepare(
-            "delete from r_sp_vertical_sp where (space_id = $1 and space_other_id = $2) or (space_other_id = $1 and space_id = $2)",
-            ["text", "text"])
-        del_manual_plan.execute([single_result[0], single_result[1]])
-        insert_plan = plpy.prepare(
-            "insert into r_sp_vertical_sp(space_id, space_other_id, project_id, sign, object_type) values($1, $2, $3, 2, $4)",
-            ["text", "text", "text", "text"])
-        insert_plan.execute([single_result[0], single_result[1], project_id, single_result[2]])
-
-
-
-
-
+try:
+    # 获取当前楼层绑定的数据中心楼层的id
+    floor_plan = plpy.prepare("SELECT id FROM public.floor where model_id = $1", ["text"])
+    floor_data = floor_plan.execute([floor_id])
+    floor_arr = []
+    for fl_row in floor_data:
+        floor_arr.append(fl_row['id'])
 
+    if len(floor_arr) == 0:
+        plpy.info("no binding floor")
+        return True
+    floor_str = ""
+    for fl in floor_arr:
+        floor_str = (floor_str + "'" + fl + "',")
+    floor_str = floor_str.strip(',')
+    plpy.info(floor_str)
+    # 获取当前模型和前一个版本的模型id
+    model_plan = plpy.prepare("select id from revit.model_file where model_floor_id = $1 and removed = false and status = 4 and version is not null order by version desc", ["text"])
+    model_data = model_plan.execute([floor_id], 2)
+    if len(model_data) != 2:
+        plpy.info("no previous model")
+        return True
+    sql_str = "select rel.floor_id, rel.space_id, sp.outline from r_sp_in_fl rel left join zone_space_base sp on rel.space_id = sp.id where rel.floor_id in (" + floor_str + ")"
+    # 查询出来的跟模型可能相关的所有业务空间
+    space_data = plpy.execute(sql_str)
+    if len(space_data) == 0:
+        plpy.info("no space relation under binding floor")
+        return True
+    plpy.info('space data count : {0}'.format(len(space_data)))
+    # 获取新模型的元空间
+    new_ispace_plan = plpy.prepare("select source_id, outline from revit.space where model_id = $1", ["text"])
+    new_ispace_data = new_ispace_plan.execute([model_data[0]['id']])
+    plpy.info('new_ispace_data count : {0}'.format(len(new_ispace_data)))
+    # 获取旧模型的所有元空间
+    prev_ispace_plan = plpy.prepare("select source_id, outline from revit.space where model_id = $1", ["text"])
+    prev_ispace_data = prev_ispace_plan.execute([model_data[1]['id']])
+    plpy.info('prev_ispace_data count : {0}'.format(len(prev_ispace_data)))
+    if len(prev_ispace_data) == 0:
+        plpy.info("no prev ispace data")
+        return True
 
+    affected_space_ids = get_affected_spaced(space_data, new_ispace_data, prev_ispace_data)
 
 
 
-# 获取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)
+    plpy.info('affected_space_ids count : {0}'.format(len(affected_space_ids)))
+    for space_id in affected_space_ids:
+        space_plan = plpy.prepare("update zone_space_base set state = 1 where id = $1", ["text"])
+        space_plan.execute([space_id])
 
-# 在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)
+except Exception as e:
+    plpy.info(e)
     return False
+$$
+LANGUAGE 'plpython3u' VOLATILE;
 
-# 是否垂直方向上面积有重叠
-def is_vertically_overlap(polygon1, polygon2):
-    length1 = len(polygon1)
-    length2 = len(polygon2)
-    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], polygon2[j]):
-                return True
-    return False
 
-# building -> floor -> object_type -> [space_id]
-def compose_dict(zone_data):
-    building_map = dict()
-    for row in zone_data:
-        building_id = row['building_id']
-        floor_id = row['floor_id']
-        object_type = row['object_type']
-        if building_id not in building_map:
-            building_map[building_id] = dict()
-        floor_map = building_map[building_id]
-        if floor_id not in floor_map:
-            floor_map[floor_id] = dict()
-        type_map = floor_map[floor_id]
-        if object_type not in type_map:
-            type_map[object_type] = []
-        arr = type_map[object_type]
-        arr.append(row)
-    return building_map
+#
+# space_outline_json_map = dict()
+# result_arr = []
+# # 每个楼层的每个业务空间分别和别的楼层的每个业务空间判断is_vertically_overlap
+# # 将结果是true的两个业务空间保存起来
+# for building_id, floor_map in row_map.items():
+#     for floor_id, type_map in floor_map.items():
+#         for object_type, row_arr in type_map.items():
+#             # 要被对比的楼层
+#             for other_floor_id in floor_map.keys():
+#                 if other_floor_id == floor_id:
+#                     continue
+#                 other_type_map = floor_map.get(other_floor_id)
+#                 if object_type not in other_type_map:
+#                     continue
+#                 other_row_arr = other_type_map.get(object_type)
+#                 for row in row_arr:
+#                     for other_row in other_row_arr:
+#                         space_id = row['space_id']
+#                         other_space_id = other_row['space_id']
+#                         if space_id == other_space_id:
+#                             continue
+#                         if space_id not in space_outline_json_map:
+#                             outline_json = json.loads(row['outline'])
+#                             space_outline_json_map[space_id] = outline_json
+#                         if other_space_id not in space_outline_json_map:
+#                             other_outline_json = json.loads(other_row['outline'])
+#                             space_outline_json_map[other_space_id] = other_outline_json
+#                         outline = space_outline_json_map[space_id]
+#                         other_outline = space_outline_json_map[other_space_id]
+#                         if is_vertically_overlap(outline, other_outline):
+#                             single_result = []
+#                             single_result.append(space_id)
+#                             single_result.append(other_space_id)
+#                             single_result.append(object_type)
+#                             result_arr.append(single_result)
+# if len(result_arr) == 0:
+#     return True
+# # 删除旧业务空间的垂直交通关系(自动计算的), 添加新关系
+# # 将下面对数据库的操作作为一个事务, 出异常则自动rollback
+# with plpy.subtransaction():
+#     del_plan = plpy.prepare("delete from r_sp_vertical_sp where project_id = $1 and sign = 2", ["text"])
+#     del_plan.execute([project_id])
+#     for single_result in result_arr:
+#         del_manual_plan = plpy.prepare(
+#             "delete from r_sp_vertical_sp where (space_id = $1 and space_other_id = $2) or (space_other_id = $1 and space_id = $2)",
+#             ["text", "text"])
+#         del_manual_plan.execute([single_result[0], single_result[1]])
+#         insert_plan = plpy.prepare(
+#             "insert into r_sp_vertical_sp(space_id, space_other_id, project_id, sign, object_type) values($1, $2, $3, 2, $4)",
+#             ["text", "text", "text", "text"])
+#         insert_plan.execute([single_result[0], single_result[1], project_id, single_result[2]])
+#
+#
+#
+#
+#
+#
+#
+#
+#
+#
+# # 获取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_vertically_overlap(polygon1, polygon2):
+#     length1 = len(polygon1)
+#     length2 = len(polygon2)
+#     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], polygon2[j]):
+#                 return True
+#     return False
+#
+# # building -> floor -> object_type -> [space_id]
+# def compose_dict(zone_data):
+#     building_map = dict()
+#     for row in zone_data:
+#         building_id = row['building_id']
+#         floor_id = row['floor_id']
+#         object_type = row['object_type']
+#         if building_id not in building_map:
+#             building_map[building_id] = dict()
+#         floor_map = building_map[building_id]
+#         if floor_id not in floor_map:
+#             floor_map[floor_id] = dict()
+#         type_map = floor_map[floor_id]
+#         if object_type not in type_map:
+#             type_map[object_type] = []
+#         arr = type_map[object_type]
+#         arr.append(row)
+#     return building_map

+ 75 - 34
src/affected_space/test.py

@@ -6,35 +6,22 @@ import psycopg2
 from shapely.geometry import Polygon
 import sys
 
+from src.affected_space.affected_space import get_affected_spaced
 from src.grid.check_grid import check_grid_upright
 
-involved_space = [
-    'id',
-    'floor_name',
-    'project_id',
-    'folder_id',
-    'fid',
-    'accept_time',
-    'version',
-    'note',
-    'user_id',
-    'user_name',
-    'log',
-    'url',
-    'md5',
-    'status'
+space_keys = [
+    'floor_id',
+    'space_id',
+    'outline'
 ]
 
-grid_keys = [
-    'id',
-    'model_id',
-    'name',
-    'type',
-    'last_update',
-    'create_time',
-    'revit_id',
+model_keys = [
+    'id'
+]
+
+ispace_keys = [
     'source_id',
-    'location',
+    'outline'
 ]
 
 
@@ -71,21 +58,75 @@ def loads_curve(x):
     x['curve'] = json.loads(x['curve'])
     return x
 
+def transform_outline(obj):
+    column_outline = 'outline'
+    for space in obj:
+        outline = space.get(column_outline)
+        print(type(outline))
+        outline_str = str(outline).replace('\'', '"')
+        space[column_outline] = outline_str
+
 
 if __name__ == '__main__':
-    points1 = [(0, 0), (0, 1), (1, 1), (1, 0)]
-    points2 = [(0, 0), (0.00, 0.5), (0, 1), (1, 1), (1, 0)]
-    poly1 = Polygon(points1)
-    poly2 = Polygon(points2)
+    # points1 = [(0, 0), (0, 1), (1, 1), (1, 0)]
+    # points2 = [(0, 0), (0.00, 0.5), (0, 1), (1, 1), (1, 0)]
+    # poly1 = Polygon(points1)
+    # poly2 = Polygon(points2)
+    #
+    # print(poly1.equals(poly2))
+    # print(poly1.almost_equals(poly2, 0.99))
+    # print(poly1.almost_equals(poly2, 0))
+    # print(poly1.almost_equals(poly2, -10))
+    # print(poly1.almost_equals(poly2, 2))
+    # print(poly1.almost_equals(poly2, 0.0001))
+    floor_id = '7893fe0c6cd511ea83548fd73aa29e85'
+    floor_str = "SELECT id FROM public.floor where model_id = '{0}'".format(floor_id)
+
+    floor_data = get_data(floor_str)
+
+    floor_list = [dict(zip(model_keys, item)) for item in floor_data]
+
+    if len(floor_list) == 0:
+        print("no binding floor")
+        sys.exit(0)
+    floor_str = ""
+    for fl in floor_list:
+        floor_str = (floor_str + "'" + fl.get('id') + "',")
+    floor_str = floor_str.strip(',')
+    model_str = "select id from revit.model_file where model_floor_id = '{0}' and removed = false and status = 4 and version is not null order by version desc limit 2".format(floor_id)
+    model_data = get_data(model_str)
+    model_list = [dict(zip(model_keys, item)) for item in model_data]
+
+    if len(model_list) != 2 :
+        print("no prev model")
+        sys.exit(0)
+
+    space_str = "select rel.floor_id, rel.space_id, sp.outline from r_sp_in_fl rel left join zone_space_base sp on rel.space_id = sp.id where rel.floor_id in (" + floor_str + ")"
+    space_data = get_data(space_str)
+    space_list = [dict(zip(space_keys, item)) for item in space_data]
+
+    if len(space_list) == 0:
+        print("no space")
+        sys.exit(0)
+
+    new_ispace_str = "select source_id, outline from revit.space where model_id = '{0}'".format(model_list[0]['id'])
+    prev_ispace_str = "select source_id, outline from revit.space where model_id = '" + model_list[1]['id'] + "'"
+
+    new_ispace_data = get_data(new_ispace_str)
+    prev_ispace_data = get_data(prev_ispace_str)
+
+    new_ispace_list = [dict(zip(ispace_keys, item)) for item in new_ispace_data]
+    prev_ispace_list = [dict(zip(ispace_keys, item)) for item in prev_ispace_data]
+
+
+    transform_outline(space_list)
+    transform_outline(new_ispace_list)
+    transform_outline(prev_ispace_list)
 
-    print(poly1.equals(poly2))
-    print(poly1.almost_equals(poly2, 0.99))
-    print(poly1.almost_equals(poly2, 0))
-    print(poly1.almost_equals(poly2, -10))
-    print(poly1.almost_equals(poly2, 2))
-    print(poly1.almost_equals(poly2, 0.0001))
 
+    affected_space_ids = get_affected_spaced(space_list, new_ispace_list, prev_ispace_list)
 
+    print(affected_space_ids)
 
     # involved_space = "select * from  where folder_id = " \
     #                      "'bbe510dbe26011e999b69b669ea08505' and status in (3, 31, 4) "