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

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

1、找到爆管点所在管段

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

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

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

5、找出阀门中的总阀门

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

-- Function: test_getpoint7(character varying, double precision, double precision)
-- DROP FUNCTION test_getpoint7(character varying, double precision, double precision);
CREATE OR REPLACE FUNCTION test_getpoint7(
IN tbl character varying,
IN startx double precision,
IN starty double precision)
RETURNS TABLE(v_gid integer, v_res geometry, v_type integer) AS
$BODY$ declare
v_startLine geometry;--离起点最近的线
v_startTarget integer;--距离起点最近线的终点
v_startSource integer;
v_statpoint geometry;--在v_startLine上距离起点最近的点
v_endpoint geometry;--在v_endLine上距离终点最近的点
v_up_source integer;--游标,记录是否有记录
v_up_idx integer;--记录遍历到多少层级
v_uptap_gid integer;--上游阀门gid
v_uptap_geom geometry;--上游阀门要素
v_all_where integer[];--记录所有查询过的管段
v_up_where integer[];--where条件,将遍历到阀门的管段gid排除
v_down_where integer[];--where条件,将遍历到阀门的管段gid排除
up_temprow record ;
--v_cost record;--记录阀门管段source(用于计算消耗,判断方向)
m_cost integer;
m_cost_value integer;
temprow record;
v_cost integer[];
res_source integer;
res_tap_pipe text[];
m_tap_pipe text;
idx_tap_pipe integer; --遍历结果游标
m_up_cost integer;--上游阀门
v_up_cost integer[];--上游阀门集合
res_main_pipe integer[];--总阀门集合
m_main_pipe integer;--总阀门
begin
--查询离起点最近的线
--3857坐标系
--找起点15米范围内的最近线
execute 'select geom, source, target, ST_StartPoint(geom) as startpoint,ST_EndPoint(geom) as endpoint from ' ||tbl||
' where ST_DWithin(geom,ST_Geometryfromtext(''point('|| startx ||' ' || starty ||')'',3857),15)
order by ST_Distance(geom,ST_GeometryFromText(''point('|| startx ||' '|| starty ||')'',3857)) limit 1'
into v_startLine, v_startSource ,v_startTarget, v_statpoint ,v_endpoint;
IF(v_startLine is not null) THEN
--查找上游阀门
v_up_idx = 0;
v_up_source = 1;
--寻找上游阀门
SELECT array_append(v_up_where, v_startSource) into v_up_where;
--如果没有下级节点需要遍历
WHILE array_length(v_up_where,1) > 0
LOOP
--游标归零
v_up_source = 0;
--记录层级
v_up_idx = v_up_idx + 1;
--获取当前层级节点
FOR up_temprow IN
select zy1.gid,zy1.source,zy1.target from zy zy1 where source = any(v_up_where) or target = any(v_up_where)
--select zy1.gid,zy1.source,zy1.target from zy zy1 where target = any(v_up_where)--找上游
LOOP
--清空需要查的点
IF(v_up_source = 0) THEN
v_up_where = null;
END IF;
--清空初始执行节点
v_startSource = 0;
--标志执行有数据
v_up_source = 1;
--查询管网上的点
select t.gid,t.geom from fm t where t.gid in (
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)
) into v_uptap_gid, v_uptap_geom;
raise notice '%' , 'UP---'||up_temprow.gid;
--如果没查找到阀门,则继续往下查
IF(v_uptap_gid is null) then
--source去重,判断如果数组中已有,则不添加
IF (v_up_where @> ARRAY[up_temprow.source::integer] OR v_all_where @> ARRAY[up_temprow.source::integer]) THEN
ELSE
SELECT array_append(v_up_where,up_temprow.source) into v_up_where;
SELECT array_append(v_all_where,up_temprow.source) into v_all_where;
END IF;
--target去重,判断如果数组中已有,则不添加
IF (v_up_where @> ARRAY[up_temprow.target::integer] OR v_all_where @> ARRAY[up_temprow.target::integer]) THEN
ELSE
SELECT array_append(v_up_where,up_temprow.target) into v_up_where;
SELECT array_append(v_all_where,up_temprow.target) into v_all_where;
END IF;
ELSE
raise notice '%' , up_temprow.source;
--记录阀门所在管段source
IF (v_cost @> ARRAY[up_temprow.source::integer]) THEN
ELSE
SELECT array_append(v_cost,up_temprow.source) into v_cost;
SELECT array_append(v_cost,up_temprow.target) into v_cost;
END IF;
--insert into v_cost values (up_temprow.gid,up_temprow.source,v_uptap_gid,v_uptap_geom );
--insert into v_cost values (up_temprow.gid,up_temprow.target,v_uptap_gid,v_uptap_geom );
--insert into v_cost values (up_temprow.gid,v_uptap_geom ,v_uptap_gid);
--return next v_cost;
--insert into v_taps values (v_uptap_gid, v_uptap_geom, up_temprow.source);
--v_cost = up_temprow;
--执行返回结果
--阀门id,阀门图形要素,阀门类型(上游/下游)
--return query
--select v_uptap_gid as res_uptap_gid,v_uptap_geom as res_uptap_geom ,up_temprow.source as res_source;
--raise notice '%' , 'res_tap_pipe---'||cast(res_tap_pipe as text);
IF (res_tap_pipe is not null) THEN
--SELECT array_append(res_tap_pipe,ARRAY[v_uptap_gid,up_temprow.source]) into res_tap_pipe;
--select cast(res_tap_pipe as text);
select res_tap_pipe || ARRAY[v_uptap_gid||','||cast(v_uptap_geom as text)||','||up_temprow.source] into res_tap_pipe;
ELSE
select ARRAY[v_uptap_gid||','||cast(v_uptap_geom as text)||','||up_temprow.source] into res_tap_pipe;
END IF;
END IF;
--return next;
END LOOP;
END LOOP;
--raise notice '%' , v_cost;
raise notice '%' , 'res_tap_pipe---'||cast(res_tap_pipe as text);
--return query select * from v_cost;
raise notice '%' , 'v_cost---'||cast(v_cost as text); --查找上游阀门
FOREACH m_cost IN ARRAY v_cost
LOOP
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;
raise notice '%' , 'm_cost_value---'||cast(m_cost_value as text);
--如果没有消耗大于9999999的(阈值),则认为是上游阀门
IF(m_cost_value = 0) THEN
--判断上游阀门间是否有上下游关系
SELECT array_append(v_up_cost,m_cost) into v_up_cost;
END IF;
--IF(m_cost_value = array_length(v_cost,1)/2 - 1) THEN
----return query
---- select * from v_taps where source = m_cost;
----raise notice '%' , 'res_tap_pipe---'||cast(unnest(res_tap_pipe) as text);
--FOREACH m_tap_pipe IN ARRAY res_tap_pipe
--LOOP
--raise notice '%' , 'm_cost---'||cast(m_cost as text) ;
--IF (split_part(m_tap_pipe, ',', 3)::integer = m_cost) THEN
----阀门id,阀门图形要素,阀门类型(上游/下游)
--return query
--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;
--END IF;
--idx_tap_pipe = idx_tap_pipe+1;
--END LOOP;
--END IF;
END LOOP; raise notice '%' , '上游阀门---'||cast(v_up_cost as text); --循环遍历找主阀门
FOREACH m_up_cost IN ARRAY v_up_cost
LOOP
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;
IF(m_cost_value = 0) THEN
SELECT array_append(res_main_pipe,m_up_cost) into res_main_pipe;
END IF;
END LOOP; raise notice '%' , 'res_main_pipe---'||cast(res_main_pipe as text); IF(res_main_pipe IS NULL OR array_length(res_main_pipe,1)=0) THEN
res_main_pipe = v_up_cost;
END IF; FOREACH m_main_pipe IN ARRAY res_main_pipe
LOOP
FOREACH m_tap_pipe IN ARRAY res_tap_pipe
LOOP
raise notice '%' , 'm_cost---'||cast(m_cost as text) ;
IF (split_part(m_tap_pipe, ',', 3)::integer = m_main_pipe) THEN
--阀门id,阀门图形要素,阀门类型(上游/下游)
return query
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;
END IF;
END LOOP;
END LOOP;
  END IF;
--查找总阀门 --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;

end;  

$BODY$
LANGUAGE plpgsql VOLATILE STRICT
COST 100
ROWS 1000;
ALTER FUNCTION test_getpoint7(character varying, double precision, double precision)
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. 5G:今天不谈技术,谈谈需求和应用

    4G改变生活,5G改变社会.随着2019年5G手机的发布,5G时代已经拉开帷幕,无数嗅觉灵敏的投资人和创业者在研究5G行业的投资机会. 但是,市场研究侧重于技术细节与上游产业链设备投资居多,对于贴近消 ...

  2. centos 7.6修改ssh端口,设置防火墙规则

    一.修改ssh端口 1 使用 root 用户进入 /etc/ssh目录 2 备份ssh配置文件 cp sshd_config sshd_config-bak 3 使用 vim 打开 sshd_conf ...

  3. SpringBoot整合Logback

    本文主要讲与Boot整合,后面会详细讲解Logback 官方文档 ConsoleAppender 如 name 所示,附加在 console 上,或者更准确地说是 System.out 或 Syste ...

  4. 七牛云图片存储---Java

    一.新建存储空间 到七牛云官网注册一个账号 新建一个存储空间 到个人中心获取秘钥 二.新建Java项目 1.pom.xml配置 <dependency> <groupId>co ...

  5. javase实现记事本

    java编程就是分布式.微服务?离开Spring...我还能写点什么 不知从何时起,自己喜欢上也习惯了用java写点界面程序.app.也许这就是程序员仅剩的一点乐趣.但对我而言.我却很享受这个过程.程 ...

  6. 【C#多线程】2.线程池简述+两种传统的异步模式

    线程池简述+两种传统的异步编程模式 1.线程池简述 首先我们要明确一点,编程中讲的线程与平时我们形容CPU几核几线程中的线程是不一样的,CPU线程是指逻辑处理器,比如4核8线程,讲的是这个cpu有8个 ...

  7. 第三十四章 POSIX消息队列

    POSIX消息队列相关函数 mq_open 功能: 用来创建和访问一个消息队列 原型: mqd_t mq_open(const char *name, int oflag); //只能用来打开消息队列 ...

  8. MIT线性代数:4.A的LU分解

  9. Appium的加载过程

    appium运行流程 Appium的加载过程如上图. 1)调用Android adb完成基本的系统操作: 2)向Android上部署bootstrap.jar: 3)Bootstrap.jar For ...

  10. NOIP模拟 32

    我在31反思中膜拜过了B哥 没想到这次又... 我给老姚家丢脸了...STO 首先T1暴力就写挂了... 贪图从$n^3$*$2^n$优化成$n^2$*$2^n$然后打错了 哗哗的扔分 而且正解都想不 ...