PostGIS 爆管分析之根据爆点找出所有影响阀门
环境:
Win10
ArcMap10.4(用于数据处理)
postgresql9.4
postgis2.2.3
pgRouting2.3(postgresql插件)
说明:
做爆管分析的第一步,需要先将数据做拓扑处理(方法见博文《PostGIS 结合Openlayers以及Geoserver实现最短路径分析》,共三篇:https://www.cnblogs.com/giser-s/p/11599562.html)
以下在构建拓扑数据成功的基础上继续(保证gid、source、target字段)
步骤:
1、用户设定的爆管点(startx,starty),会与真实管网位置有差距,这里设置15米容差:假设爆管点距离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;
2、开始查找,从爆管开始
--循环第一次,将爆管放入查询条件,查询爆管上是否有阀门
IF(v_up_idx = 0) THEN
SELECT array_append(v_up_where, v_startSource) into v_up_where;
ELSE
--v_up_where = null;
END IF; --循环开始
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)
LOOP --查询管网上的点
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;
3、如爆管没有阀门,则继续循环下一层级,往下找与爆管相接的管段;如果有阀门,则返回阀门,从下一次循环中剔除(不再找与他相接的管段)
--如果没查找到阀门,则继续往下查
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
4、如果有阀门,则返回阀门gid和geom
--执行返回结果
return query
select v_uptap_gid as res_uptap_gid,v_uptap_geom as res_uptap_geom ;
5、附上全部存储过程
-- Function: test_getpoint5(character varying, double precision, double precision)
-- DROP FUNCTION test_getpoint5(character varying, double precision, double precision);
CREATE OR REPLACE FUNCTION test_getpoint5(
IN tbl character varying,
IN startx double precision,
IN starty double precision)
RETURNS TABLE(v_gid integer, v_res geometry) 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排除
up_temprow record ;
test 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;
test = 0;
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;
--IF(v_up_idx = 0) THEN
--SELECT array_append(v_up_where, v_startSource) into v_up_where;
--SELECT array_append(v_up_where, v_startTarget) into v_up_where;
--ELSE
--v_up_where = null;
--END IF;
--记录层级
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)
LOOP
test = test +1;
--清空需要查的点
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; --如果没查找到阀门,则继续往下查
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 '%' , v_uptap_gid ||'---'||cast(test as text);
--执行返回结果
return query
select v_uptap_gid as res_uptap_gid,v_uptap_geom as res_uptap_geom ;
END IF;
--return next;
END LOOP;
END LOOP;
END IF;
end; $BODY$
LANGUAGE plpgsql VOLATILE STRICT
COST 100
ROWS 1000;
ALTER FUNCTION test_getpoint5(character varying, double precision, double precision)
OWNER TO postgres;
结尾:
这里本想将上游阀门和下游阀门分开,但是我们建立的拓扑中并没有方向,所以改成了查询出所有的影响阀门。
后续将继续研究,把方向数据放进去,实现上游阀门、下游阀门、精确找出总阀门的功能
PostGIS 爆管分析之根据爆点找出所有影响阀门的更多相关文章
- 记录一下通过分析Tomcat内部jar包找出request.getReader()所用的字符编码在哪里设置和起效的完整分析流程
前言: 之前写Java服务端处理POST请求时遇到了请求体转换成字符流所用编码来源的疑惑,在doPost方法里通过request.getReader()获取的BufferedReader对象内部的 R ...
- PostGIS 爆管分析之找出上游阀门
环境: Win10 ArcMap10.4(用于数据处理) postgresql9.4 postgis2.2.3 pgRouting2.3(postgresql插件) 说明: 继上一篇文章做了爆管分析找 ...
- PostGIS 爆管分析之找出总阀门
这个算法算是被摒弃了,但是很多自己思考过后留下的成果,虽然不用了,留着做记录. 算法目的是为了发生爆管后找到总阀门,这里分了几个步骤: 1.找到爆管点所在管段 2.通过遍历找到爆管点所有影响的阀门 3 ...
- PostGIS管网连通性分析
GIS在管网数据中的很重要的一个应用方向就是"管网空间分析",其中包括连通性分析.上下游分析.爆管分析等等.下面是我使用postgis来实现该"管网连通性分析" ...
- [转帖]预警 | Linux 爆“SACK Panic”远程DoS漏洞,大量主机受影响
预警 | Linux 爆“SACK Panic”远程DoS漏洞,大量主机受影响 https://cloud.tencent.com/developer/article/1447879 所有的 版本 ...
- 从分析SQLSERVER ERRORLOG查找错误折射出的工作效率问题
从分析SQLSERVER ERRORLOG查找错误折射出的工作效率问题 前几天,在备份某一台服务器上的某一个库的时候遇到问题,数据库80G+,在完整备份的时候,SQLSERVER报错 消息 ,级别 , ...
- Python练习六十:网页分析,找出里面的正文与链接
网页分析,找出里面的正文与链接 代码如下: from urllib import request from bs4 import BeautifulSoup request = request.url ...
- 网络游戏逆向分析-3-通过发包函数找功能call
网络游戏逆向分析-3-通过发包函数找功能call 网络游戏和单机游戏的分析有相似点,但是区别还是很大的. 网络游戏和单机游戏的区别: 网络游戏是需要和服务器进行交互的,网游中的所有功能几乎都会先发送封 ...
- PostGIS 爆管分析之找出上游阀门(优化版)
说明 前面描述过利用postgis查找上游阀门的原理,以及代码,其实当初写完就发现又很大的优化空间,但一直没有时间去做. 最近遇到一个情况,处理60w+条管网数据时,效率太慢了,于是腾时间优化了一版. ...
随机推荐
- Java网络编程(二)IP、URL和HTTP
一.IP InetAddress类有一些静态工厂方法,可以连接到DNS服务器来解析主机名. 示例1:InetAddress address = InetAddress.getByName(" ...
- Java多线程编程(六)单例模式与多线程
在使用多线程技术的单例模式时会出现一些意想不到的情况,这样的代码如果在生产环境中出现异常,有可能造成灾难性的后果. 一.立即加载/“饿汉模式” 立即加载就是使用类的时候已经将对象创建完毕,常见的实现方 ...
- django-模型之(ORM)对象关系映射(一)
所谓对象关系映射,就是将数据库的一些名字与python中的一些名字相对应,表名-->类名,字段-->属性,操作(增删改查)-->方法.这样,我们就可以通过对Python代码的编辑来对 ...
- 数据后台管理(五)AOP日志
为了增加数据的安全性,在数据管理的过程中,我们需要将操作者访问时间,操作者的名称,访问的IP,访问资源的URL,执行时长,访问方法记录下来存储到数据库中,并可以通过页面查看. 1.将日志信息存储到数据 ...
- Https 与 iOS 信息安全
转载自:swift-cafe 什么是 Https 咱们从最直观的说起. 我们平时在用电脑访问网页的时候,有时候会在地址栏的左边多出一个小锁的图标,就像这样: 这是大多数主流浏览器的一个通用做法,当我们 ...
- Java HashSet对txt文本内容去重(统计小说用过的字或字数)
Java HashSet对txt文本内容去重(统计小说用过的字或字数) 基本思路: 1.字节流读需要去重的txt文本.(展示demo为当前workspace下名为utf-8.txt的文本) 2.对读取 ...
- 浅谈Retinex
Retinex是上个世纪七十年代由Land提出的色彩理论.我认为其核心思想基于俩点 (1)在颜色感知时,人眼对局部相对光强敏感程度要优于绝对光强. (2)反射分量R(x,y)储存有无光源物体的真实模样 ...
- NOIP提高组/CSP-S复赛需掌握的算法
1.排序算法(快排.选择.冒泡.堆排序.二叉排序树.桶排序) 2.DFS/BFS 也就是搜索算法,剪枝务必要学! 学宽搜的时候学一下哈希表! 3.树 ①遍历 ②二叉树 ③二叉排序树(查找.生成.删除) ...
- JAVA程序打包方法-挺好
https://blog.csdn.net/dj0721/article/details/72462688/
- 通俗易懂了解Vuex
1.前言 在使用Vue进行开发的时候,关于vue组件通信的方式,除了通俗易懂了解Vue组件的通信方式这篇博文谈到三种通信方式,其实vue更提倡我们使用vuex来进行组件间的状态管理以及通信问题.Vue ...