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+条管网数据时,效率太慢了,于是腾时间优化了一版. ...
随机推荐
- js检测页面上一个元素是否已经滚动到了屏幕的可视区域内
应用场景:只要页面加载了,其中在页面中出现的li就向控制台输出第几个发送请求:在本次加载的页面中,再将滚动条滚回前边的li,不再向控制台输出东西,也就是说已经显示过的li,不再向控制台输出东西. &l ...
- redis集群之Codis
在大数据高并发场景下,单个 Redis 实例往往会显得捉襟见肘.首先体现在内存上,单个 Redis 的内存不宜过大,内存太大会导致 rdb 文件过大,进一步导致主从同步时全量同步时间过长,在实例重启恢 ...
- Redux的核心概念,实现代码与应用示例
Redux是一种JavaScript的状态管理容器,是一个独立的状态管理库,可配合其它框架使用,比如React.引入Redux主要为了使JavaScript中数据管理的方便,易追踪,避免在大型的Jav ...
- vue-route动态路由
配置子路由: 路由的视图都需要使用view-router 子路由也可以嵌套路由使用: children来做嵌套如上图 使用location.页面name就可以做页面跳转 mounted:挂载,延迟跳转 ...
- SpringBoot与MybatisPlus3.X整合示例(十六)
包含 分页.逻辑删除.自定义全局操作 等绝大部分常用功能的使用示例,相当于大整合的完整示例 pom.xml <dependencies> <dependency> <gr ...
- activeMQ 安装及启动异常处理
一.环境: [root@centos_6 ~]# cat /etc/system-release CentOS release 6.5 (Final) [root@centos_6 ~]# uname ...
- 暑期集训20190727 水(water)
[题目描述] 有一块矩形土地被划分成n×m个正方形小块.这些小块高低不平,每一小 块都有自己的高度.水流可以由任意一块地流向周围四个方向的四块地中,但 是不能直接流入对角相连的小块中. 一场大雨后,由 ...
- [考试反思]0819NOIP模拟测试26:荒芜
这么正式的考试,明天应该就是最后一次了吧 然而..今天,我仍然没能抓住机会 RNBrank1:.skyh还是稳.外校gmk拿走第三. 四五六名都是63-64.第七50.第八39.我和三个并列的是第九. ...
- 使用Typescript重构axios(十九)——请求取消功能:实现第二种使用方式
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- 2018年7月份前端开源软件TOP3
基于 ThinkPHP5 + Bootstrap 的后台开发框架 FastAdmin FastAdmin 详细介绍 FastAdmin是一款基于 ThinkPHP5 + Bootstrap 的极速后台 ...