|
@@ -1,6 +1,6 @@
|
|
|
# 竖井贯通关系
|
|
|
## 前置条件
|
|
|
- 1. 竖井包含的有元空间(竖井在r_sh_contain_si表中有数据)
|
|
|
+ 1. 竖井包含的有业务空间
|
|
|
## 处理逻辑
|
|
|
1. 两两竖井对比, 前提条件: 对比的两竖井不能包含有相同的业务空间, 否则不能对比. (竖井包含元空间的数据是前端做划分)
|
|
|
2. 满足1之后, 如果其中一个竖井包含的业务空间与另一个竖井包含的业务空间在垂直方向上有重叠, 则认为这两个竖井有贯通关系
|
|
@@ -12,46 +12,124 @@
|
|
|
|
|
|
```
|
|
|
-- 竖井贯通关系
|
|
|
-create or replace function public.rel_sh2sh(project_id character varying) returns boolean
|
|
|
-as
|
|
|
-$$
|
|
|
-def is_exist(shaft1, shaft2, rel_dict):
|
|
|
- if shaft1 in rel_dict:
|
|
|
- if shaft2 in rel_dict[shaft1]:
|
|
|
- return True
|
|
|
- if shaft2 in rel_dict:
|
|
|
- if shaft1 in rel_dict[shaft2]:
|
|
|
+CREATE OR REPLACE FUNCTION "public"."rel_sh2sh"("project_id" varchar)
|
|
|
+ RETURNS "pg_catalog"."bool" AS $BODY$
|
|
|
+
|
|
|
+from shapely.geometry import Polygon
|
|
|
+import json
|
|
|
+
|
|
|
+# 获取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])
|
|
|
+ try:
|
|
|
+ if poly1.overlaps(poly2):
|
|
|
+ return True
|
|
|
+ except Exception as e:
|
|
|
+ plpy.warning('fff + {}'.format(e))
|
|
|
+ return False
|
|
|
+ if poly1.equals(poly2) or poly1.contains(poly2):
|
|
|
+ return False
|
|
|
+ return True
|
|
|
+
|
|
|
+def is_sub_outline_overlap(polygon1, polygon2):
|
|
|
+ try:
|
|
|
+ poly1 = get_polygon(polygon1[0])
|
|
|
+ poly2 = get_polygon(polygon2[0])
|
|
|
+ if poly1.overlaps(poly2) or poly1.equals(poly2):
|
|
|
return True
|
|
|
+ if poly1.contains(poly2):
|
|
|
+ return is_include(polygon1, poly2)
|
|
|
+ if poly2.contains(poly1):
|
|
|
+ return is_include(polygon2, poly1)
|
|
|
+ except Exception as e:
|
|
|
+ plpy.warning('dddd + {}'.format(e))
|
|
|
+ return False
|
|
|
return False
|
|
|
|
|
|
+# 是否垂直方向上面积有重叠
|
|
|
+def is_sp_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
|
|
|
+
|
|
|
+def is_vertically_overlap(sp_set_i, sp_set_j, sp_outline_dict):
|
|
|
+ for sp_i in sp_set_i:
|
|
|
+ for sp_j in sp_set_j:
|
|
|
+ outline_i = sp_outline_dict[sp_i]
|
|
|
+ outline_j = sp_outline_dict[sp_j]
|
|
|
+ if is_sp_vertically_overlap(outline_i, outline_j):
|
|
|
+ return True
|
|
|
+ return False
|
|
|
+
|
|
|
+
|
|
|
+# 计算竖井的贯通关系
|
|
|
+def calc_sh2sh(rel_dict, sp_outline_dict):
|
|
|
+ result = []
|
|
|
+ key_list = list(rel_dict.keys())
|
|
|
+ for i in range(len(key_list)):
|
|
|
+ for j in range(i + 1, len(key_list)):
|
|
|
+ sh_i = key_list[i]
|
|
|
+ sh_j = key_list[j]
|
|
|
+ sp_i = rel_dict[sh_i]
|
|
|
+ sp_j = rel_dict[sh_j]
|
|
|
+ intersection = sp_i.intersection(sp_j)
|
|
|
+ if len(intersection) > 0:
|
|
|
+ continue
|
|
|
+ is_overlap = is_vertically_overlap(sp_i, sp_j, sp_outline_dict)
|
|
|
+ if is_overlap:
|
|
|
+ result.append((sh_i, sh_j))
|
|
|
+ return result
|
|
|
+
|
|
|
try:
|
|
|
# 将下面对数据库的操作作为一个事务, 出异常则自动rollback
|
|
|
with plpy.subtransaction():
|
|
|
delete_plan = plpy.prepare("delete from r_sh_through_sh where project_id = $1 and sign = 2", ["text"])
|
|
|
delete_plan.execute([project_id])
|
|
|
- sh_plan = plpy.prepare("select s1.shaft_id s1, s2.shaft_id s2 from r_sh_contain_si s1 inner join r_sh_contain_si s2 on s1.ispace_id = s2.ispace_id where s1.project_id = $1 and s2.project_id = $1 and s1.shaft_id != s2.shaft_id", ["text"])
|
|
|
+ sh_plan = plpy.prepare("select sh_id, sp_id, sp.outline from relationship.r_sh2sp rel inner join zone_space_base sp on sp.id = rel.sp_id where rel.project_id = $1", ["text"])
|
|
|
rel = sh_plan.execute([project_id])
|
|
|
rel_dict = dict()
|
|
|
+ sp_outline_dict = dict()
|
|
|
for row in rel:
|
|
|
- shaft1 = row['s1']
|
|
|
- shaft2 = row['s2']
|
|
|
- if shaft1 == None or shaft2 == None:
|
|
|
- continue
|
|
|
- if not is_exist(shaft1, shaft2, rel_dict):
|
|
|
- if shaft1 not in rel_dict:
|
|
|
- rel_dict[shaft1] = set()
|
|
|
- rel_dict[shaft1].add(shaft2)
|
|
|
- for shaft1, sub_set in rel_dict.items():
|
|
|
- for shaft2 in sub_set:
|
|
|
- plan = plpy.prepare("insert into r_sh_through_sh(shaft_id, shaft_other_id, project_id, sign) values($1, $2, $3, 2)", ["text", "text", "text"])
|
|
|
- plan.execute([shaft1, shaft2, project_id])
|
|
|
+ shaft_id = row['sh_id']
|
|
|
+ sp_id = row['sp_id']
|
|
|
+ sp_outline = row['outline']
|
|
|
+ if shaft_id not in rel_dict:
|
|
|
+ rel_dict[shaft_id] = set()
|
|
|
+ rel_dict[shaft_id].add(sp_id)
|
|
|
+ if sp_id not in sp_outline_dict:
|
|
|
+ sp_outline_dict[sp_id] = json.loads(sp_outline)
|
|
|
+ sh2sh_arr = calc_sh2sh(rel_dict, sp_outline_dict)
|
|
|
+ for (shaft1, shaft2) in sh2sh_arr:
|
|
|
+ delete_duplicate_plan = plpy.prepare("delete from r_sh_through_sh where (shaft_id = $1 and shaft_other_id = $2) or (shaft_id = $2 and shaft_other_id = $1)", ["text", "text"])
|
|
|
+ delete_duplicate_plan.execute([shaft1, shaft2])
|
|
|
+ plan = plpy.prepare("insert into r_sh_through_sh(shaft_id, shaft_other_id, project_id, sign) values($1, $2, $3, 2)", ["text", "text", "text"])
|
|
|
+ plan.execute([shaft1, shaft2, project_id])
|
|
|
except Exception as e:
|
|
|
plpy.warning(e)
|
|
|
return False
|
|
|
else:
|
|
|
return True
|
|
|
-$$
|
|
|
-LANGUAGE 'plpython3u' VOLATILE;
|
|
|
+$BODY$
|
|
|
+ LANGUAGE plpython3u VOLATILE
|
|
|
+ COST 100
|
|
|
|
|
|
|
|
|
select public.rel_sh2sh('Pj1102290002')
|