这个算法算是被摒弃了,但是很多自己思考过后留下的成果,虽然不用了,留着做记录。

算法目的是为了发生爆管后找到总阀门,这里分了几个步骤:

1、找到爆管点所在管段

2、通过遍历找到爆管点所有影响的阀门

3、找到影响阀门中的上游阀门

4、在上游阀门中进行遍历,看相互关系,与其他阀门都联通的则视为总阀门

5、找出阀门中的总阀门

#考虑了一下,所有与爆点相连的上游阀门其实在爆管发生后都需要关闭。所以算法中4、5步,不需要了。

  1. -- Function: test_getpoint7(character varying, double precision, double precision)
  2. -- DROP FUNCTION test_getpoint7(character varying, double precision, double precision);
  3. CREATE OR REPLACE FUNCTION test_getpoint7(
  4. IN tbl character varying,
  5. IN startx double precision,
  6. IN starty double precision)
  7. RETURNS TABLE(v_gid integer, v_res geometry, v_type integer) AS
  8. $BODY$
  9.  
  10. declare
  11. v_startLine geometry;--离起点最近的线
  12. v_startTarget integer;--距离起点最近线的终点
  13. v_startSource integer;
  14. v_statpoint geometry;--在v_startLine上距离起点最近的点
  15. v_endpoint geometry;--在v_endLine上距离终点最近的点
  16. v_up_source integer;--游标,记录是否有记录
  17. v_up_idx integer;--记录遍历到多少层级
  18. v_uptap_gid integer;--上游阀门gid
  19. v_uptap_geom geometry;--上游阀门要素
  20. v_all_where integer[];--记录所有查询过的管段
  21. v_up_where integer[];--where条件,将遍历到阀门的管段gid排除
  22. v_down_where integer[];--where条件,将遍历到阀门的管段gid排除
  23. up_temprow record ;
  24. --v_cost record;--记录阀门管段source(用于计算消耗,判断方向)
  25. m_cost integer;
  26. m_cost_value integer;
  27. temprow record;
  28. v_cost integer[];
  29. res_source integer;
  30. res_tap_pipe text[];
  31. m_tap_pipe text;
  32. idx_tap_pipe integer; --遍历结果游标
  33. m_up_cost integer;--上游阀门
  34. v_up_cost integer[];--上游阀门集合
  35. res_main_pipe integer[];--总阀门集合
  36. m_main_pipe integer;--总阀门
  37. begin
  38. --查询离起点最近的线
  39. --3857坐标系
  40. --找起点15米范围内的最近线
  41. execute 'select geom, source, target, ST_StartPoint(geom) as startpoint,ST_EndPoint(geom) as endpoint from ' ||tbl||
  42. ' where ST_DWithin(geom,ST_Geometryfromtext(''point('|| startx ||' ' || starty ||')'',3857),15)
  43. order by ST_Distance(geom,ST_GeometryFromText(''point('|| startx ||' '|| starty ||')'',3857)) limit 1'
  44. into v_startLine, v_startSource ,v_startTarget, v_statpoint ,v_endpoint;
  45. IF(v_startLine is not null) THEN
  46. --查找上游阀门
  47. v_up_idx = 0;
  48. v_up_source = 1;
  49. --寻找上游阀门
  50. SELECT array_append(v_up_where, v_startSource) into v_up_where;
  51. --如果没有下级节点需要遍历
  52. WHILE array_length(v_up_where,1) > 0
  53. LOOP
  54. --游标归零
  55. v_up_source = 0;
  56. --记录层级
  57. v_up_idx = v_up_idx + 1;
  58. --获取当前层级节点
  59. FOR up_temprow IN
  60. select zy1.gid,zy1.source,zy1.target from zy zy1 where source = any(v_up_where) or target = any(v_up_where)
  61. --select zy1.gid,zy1.source,zy1.target from zy zy1 where target = any(v_up_where)--找上游
  62. LOOP
  63. --清空需要查的点
  64. IF(v_up_source = 0) THEN
  65. v_up_where = null;
  66. END IF;
  67. --清空初始执行节点
  68. v_startSource = 0;
  69. --标志执行有数据
  70. v_up_source = 1;
  71. --查询管网上的点
  72. select t.gid,t.geom from fm t where t.gid in (
  73. select a.gid from fm a,(select c.* from zy c where c.gid = up_temprow.gid) b where ST_intersects(a.geom,b.geom)
  74. ) into v_uptap_gid, v_uptap_geom;
  75. raise notice '%' , 'UP---'||up_temprow.gid;
  76. --如果没查找到阀门,则继续往下查
  77. IF(v_uptap_gid is null) then
  78. --source去重,判断如果数组中已有,则不添加
  79. IF (v_up_where @> ARRAY[up_temprow.source::integer] OR v_all_where @> ARRAY[up_temprow.source::integer]) THEN
  80. ELSE
  81. SELECT array_append(v_up_where,up_temprow.source) into v_up_where;
  82. SELECT array_append(v_all_where,up_temprow.source) into v_all_where;
  83. END IF;
  84. --target去重,判断如果数组中已有,则不添加
  85. IF (v_up_where @> ARRAY[up_temprow.target::integer] OR v_all_where @> ARRAY[up_temprow.target::integer]) THEN
  86. ELSE
  87. SELECT array_append(v_up_where,up_temprow.target) into v_up_where;
  88. SELECT array_append(v_all_where,up_temprow.target) into v_all_where;
  89. END IF;
  90. ELSE
  91. raise notice '%' , up_temprow.source;
  92. --记录阀门所在管段source
  93. IF (v_cost @> ARRAY[up_temprow.source::integer]) THEN
  94. ELSE
  95. SELECT array_append(v_cost,up_temprow.source) into v_cost;
  96. SELECT array_append(v_cost,up_temprow.target) into v_cost;
  97. END IF;
  98. --insert into v_cost values (up_temprow.gid,up_temprow.source,v_uptap_gid,v_uptap_geom );
  99. --insert into v_cost values (up_temprow.gid,up_temprow.target,v_uptap_gid,v_uptap_geom );
  100. --insert into v_cost values (up_temprow.gid,v_uptap_geom ,v_uptap_gid);
  101. --return next v_cost;
  102. --insert into v_taps values (v_uptap_gid, v_uptap_geom, up_temprow.source);
  103. --v_cost = up_temprow;
  104. --执行返回结果
  105. --阀门id,阀门图形要素,阀门类型(上游/下游)
  106. --return query
  107. --select v_uptap_gid as res_uptap_gid,v_uptap_geom as res_uptap_geom ,up_temprow.source as res_source;
  108. --raise notice '%' , 'res_tap_pipe---'||cast(res_tap_pipe as text);
  109. IF (res_tap_pipe is not null) THEN
  110. --SELECT array_append(res_tap_pipe,ARRAY[v_uptap_gid,up_temprow.source]) into res_tap_pipe;
  111. --select cast(res_tap_pipe as text);
  112. select res_tap_pipe || ARRAY[v_uptap_gid||','||cast(v_uptap_geom as text)||','||up_temprow.source] into res_tap_pipe;
  113. ELSE
  114. select ARRAY[v_uptap_gid||','||cast(v_uptap_geom as text)||','||up_temprow.source] into res_tap_pipe;
  115. END IF;
  116. END IF;
  117. --return next;
  118. END LOOP;
  119. END LOOP;
  120. --raise notice '%' , v_cost;
  121. raise notice '%' , 'res_tap_pipe---'||cast(res_tap_pipe as text);
  122. --return query select * from v_cost;
  123. raise notice '%' , 'v_cost---'||cast(v_cost as text);
  124.  
  125. --查找上游阀门
  126. FOREACH m_cost IN ARRAY v_cost
  127. LOOP
  128. SELECT count(*) FROM pgr_dijkstraCost('select gid as id, source, target, length as cost, reverse_cost from zy',m_cost, ARRAY[v_startSource,v_startTarget], true) where agg_cost >= 9999999 into m_cost_value;
  129. raise notice '%' , 'm_cost_value---'||cast(m_cost_value as text);
  130. --如果没有消耗大于9999999的(阈值),则认为是上游阀门
  131. IF(m_cost_value = 0) THEN
  132. --判断上游阀门间是否有上下游关系
  133. SELECT array_append(v_up_cost,m_cost) into v_up_cost;
  134. END IF;
  135. --IF(m_cost_value = array_length(v_cost,1)/2 - 1) THEN
  136. ----return query
  137. ---- select * from v_taps where source = m_cost;
  138. ----raise notice '%' , 'res_tap_pipe---'||cast(unnest(res_tap_pipe) as text);
  139. --FOREACH m_tap_pipe IN ARRAY res_tap_pipe
  140. --LOOP
  141. --raise notice '%' , 'm_cost---'||cast(m_cost as text) ;
  142. --IF (split_part(m_tap_pipe, ',', 3)::integer = m_cost) THEN
  143. ----阀门id,阀门图形要素,阀门类型(上游/下游)
  144. --return query
  145. --select split_part(m_tap_pipe, ',', 1)::integer as res_uptap_gid,split_part(m_tap_pipe, ',', 2)::geometry as res_uptap_geom ,split_part(m_tap_pipe, ',', 3)::integer as res_source;
  146. --END IF;
  147. --idx_tap_pipe = idx_tap_pipe+1;
  148. --END LOOP;
  149. --END IF;
  150. END LOOP;
  151.  
  152. raise notice '%' , '上游阀门---'||cast(v_up_cost as text);
  153.  
  154. --循环遍历找主阀门
  155. FOREACH m_up_cost IN ARRAY v_up_cost
  156. LOOP
  157. SELECT count(*) FROM pgr_dijkstraCost('select gid as id, source, target, length as cost, reverse_cost from zy',m_up_cost, v_up_cost, true) where agg_cost >= 9999999 into m_cost_value;
  158. IF(m_cost_value = 0) THEN
  159. SELECT array_append(res_main_pipe,m_up_cost) into res_main_pipe;
  160. END IF;
  161. END LOOP;
  162.  
  163. raise notice '%' , 'res_main_pipe---'||cast(res_main_pipe as text);
  164.  
  165. IF(res_main_pipe IS NULL OR array_length(res_main_pipe,1)=0) THEN
  166. res_main_pipe = v_up_cost;
  167. END IF;
  168.  
  169. FOREACH m_main_pipe IN ARRAY res_main_pipe
  170. LOOP
  171. FOREACH m_tap_pipe IN ARRAY res_tap_pipe
  172. LOOP
  173. raise notice '%' , 'm_cost---'||cast(m_cost as text) ;
  174. IF (split_part(m_tap_pipe, ',', 3)::integer = m_main_pipe) THEN
  175. --阀门id,阀门图形要素,阀门类型(上游/下游)
  176. return query
  177. select split_part(m_tap_pipe, ',', 1)::integer as res_uptap_gid,split_part(m_tap_pipe, ',', 2)::geometry as res_uptap_geom ,split_part(m_tap_pipe, ',', 3)::integer as res_source;
  178. END IF;
  179. END LOOP;
  180. END LOOP;
  1. END IF;
  1. --查找总阀门 --FOR temprow IN -- select * from v_cost --LOOP -- SELECT count(*) FROM pgr_dijkstraCost('select gid as id, source, target, length as cost, reverse_cost from zy',m_cost, v_cost, true) where agg_cost <9999999 into m_cost_value; -- if(m_cost_value == ) --END LOOP;
  2.  
  3. end;
  4.  
  5. $BODY$
  6. LANGUAGE plpgsql VOLATILE STRICT
  7. COST 100
  8. ROWS 1000;
  9. ALTER FUNCTION test_getpoint7(character varying, double precision, double precision)
  10. OWNER TO postgres;

PostGIS 爆管分析之找出总阀门的更多相关文章

  1. PostGIS 爆管分析之找出上游阀门

    环境: Win10 ArcMap10.4(用于数据处理) postgresql9.4 postgis2.2.3 pgRouting2.3(postgresql插件) 说明: 继上一篇文章做了爆管分析找 ...

  2. PostGIS 爆管分析之找出上游阀门(优化版)

    说明 前面描述过利用postgis查找上游阀门的原理,以及代码,其实当初写完就发现又很大的优化空间,但一直没有时间去做. 最近遇到一个情况,处理60w+条管网数据时,效率太慢了,于是腾时间优化了一版. ...

  3. PostGIS 爆管分析之根据爆点找出所有影响阀门

    环境: Win10 ArcMap10.4(用于数据处理) postgresql9.4 postgis2.2.3 pgRouting2.3(postgresql插件) 说明: 做爆管分析的第一步,需要先 ...

  4. Python练习六十:网页分析,找出里面的正文与链接

    网页分析,找出里面的正文与链接 代码如下: from urllib import request from bs4 import BeautifulSoup request = request.url ...

  5. 如何找出你性能最差的SQL Server查询

    我经常会被反复问到这样的问题:”我有一个性能很差的SQL Server.我如何找出最差性能的查询?“.因此在今天的文章里会给你一些让你很容易找到问题答案的信息向导. 问SQL Server! SQL ...

  6. 《BI那点儿事》Microsoft 决策树算法——找出三国武将特性分布,献给广大的三国爱好者们

    根据游戏<三国志11>武将数据,利用决策树分析,找出三国武将特性分布.其中变量包括统率.武力.智力.政治.魅力.身分.变量说明:统率:武将带兵出征时的部队防御力.统帅越高受到普通攻击与兵法 ...

  7. 记录一下通过分析Tomcat内部jar包找出request.getReader()所用的字符编码在哪里设置和起效的完整分析流程

    前言: 之前写Java服务端处理POST请求时遇到了请求体转换成字符流所用编码来源的疑惑,在doPost方法里通过request.getReader()获取的BufferedReader对象内部的 R ...

  8. Bugku-CTF分析篇-weblogic(黑客攻击了Weblogic应用,请分析攻击过程,找出Weblogic的主机名。)

    weblogic 黑客攻击了Weblogic应用,请分析攻击过程,找出Weblogic的主机名. flag格式:flag{} Tip:主机名为十六进制.  

  9. 使用 Visual Studio 分析器找出应用程序瓶颈(转)

    使用 Visual Studio 分析器找出应用程序瓶颈 Hari Pulapaka and Boris Vidolov 本文讨论: 以性能瓶颈为目标 应用程序代码分析 比较分析数据 性能报告 本文使 ...

随机推荐

  1. org.thymeleaf.exceptions.TemplateInputException: Error resolving template 报错

    org.thymeleaf.exceptions.TemplateInputException: Error resolving template报错 遇到二次,第一次是刚刚学的时候,都是一个原因,而 ...

  2. Mongodb 常见的查询语句及与 mysql 对比

    db.users.find()select * from users db.users.find({"age" : 27})select * from users where ag ...

  3. 算法<初级> - 第一章 排序相关问题

    算法 - 第一章 时间复杂度: Big O 时间/空间复杂度计算一样,都是跟输入数据源的大小有关 n->∞ O(logn) 每次只使用数据源的一半,logn同理 最优解 先满足时间复杂度的情况最 ...

  4. vue-class-component使用Mixins

    vue-class-component提供了mixinshelper函数,以类样式的方式使用mixins.通过使用mixins帮助程序,TypeScript可以推断mixin类型并在组件类型上继承它们 ...

  5. XML利用接口显示并导入到数据库

    //控制器代码 /// <summary> /// 页面 /// </summary> /// <returns></returns> public A ...

  6. Asp.net WebApi的授权安全机制 Basic认证

    1:Home/index.cshtml下面的Html代码 <div> <input value="1点击先登陆" type="button" ...

  7. Java基础(三十二)JDBC(2)连接数据库

    一.连接数据库的过程 连接数据库的过程:加载数据库驱动程序,不过只需在第一次访问数据库时加载一次,然后在每次访问数据库时创建一个Connection实例,然后执行操作数据库的SQL语句,并返回执行结果 ...

  8. LFU的基本原理与实现

    前言:之前有写过一篇关于LRU的文章链接https://www.cnblogs.com/wyq178/p/9976815.html  LRU全称:Least Recently Used:最近最少使用策 ...

  9. 务必收藏备用:.net core中通过Json或直接获取图形验证码(数字验证码、字母验证码、混合验证码),有源代码全实战demo(开源代码.net core3.0)

    很多人写的博客大家看了会一知半解,不知道怎么用,应该引用什么类库或者代码不全,这样很多小白很是头疼,尤其是尝新技术更是如此.我们这边不止告诉你步骤,而且还提供开源demo.随着时间的推移,我们的dem ...

  10. 差异:后缀数组(wzz模板理解),单调栈

    因为涉及到对模板的理解,所以就着代码看会好一些. 让那些坚决不颓代码的人受委屈了. 我是对着wzz的板子默写的,可能不完全一样啊. 还有代码注释里都是我个人的理解,不保证正确,但欢迎指正. 可以有选择 ...