在PostGIS中一个面要素表中的缝隙(Find gaps among polygons in PostGIS)

2024-06-01 06:04

本文主要是介绍在PostGIS中一个面要素表中的缝隙(Find gaps among polygons in PostGIS),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

场景

在PostGIS中有一张面要素表,需要检查该表中的哪些地方有缝隙。
其中缝隙定义为这些多边形的并集中的环。
There is a surface feature table in PostGIS, and it is necessary to check which areas in the table have gaps.
The gaps are defined as the rings in the union of these polygons.
数据分布如下:
在这里插入图片描述
我们可以看出其中的缝隙,用红色框选一下:
在这里插入图片描述

第一步:计算全部要素的外包矩形

			WITH all_box AS (SELECT ST_Envelope(ST_Union(geom)) AS boxFROM TARGET_TABLE), unionB as (SELECT ST_Simplify(ST_Union(st_buffer(GEOM_COLUMN,TOLERANCE_VALUE)),TOLERANCE_VALUE) AS BGEOM FROM TARGET_TABLE) 

第二步:从外包矩形中依次去掉面要素

removed_box AS (SELECT ST_Difference(a.box, B.BGEOM) AS xFROM all_box aJOIN unionB b ON TRUE)

第三步:去掉与边界接触的子要素

			, filtered_x AS (SELECT ST_Difference(r.x, ST_Boundary(r.x)) AS yFROM removed_box r)

第四步:如果是几何集合则分解为简单对象

			, otherpolygons as (SELECT (ST_Dump(f.y)).* FROM filtered_x f), otherPolygons_sub as (select geom from otherpolygons where ST_NumInteriorRings(geom) > 0), interior_rings AS (SELECT ST_InteriorRingN(geom, generate_series(1, ST_NumInteriorRings(geom))) AS geomFROM otherPolygons_sub t)select op.geomfrom otherpolygons op, all_box ab where (st_touches(ST_ExteriorRing(ab.box),op.geom) = false)or(st_geometrytype(st_intersection(ST_ExteriorRing(ab.box),op.geom)) = ''ST_Point'')';

完整函数

create or replace function public.sp_check_gap(targetTb varchar,resultTb varchar,geomColumnName varchar default 'geom', curUserName varchar default '')
RETURNS character varying
LANGUAGE 'plpgsql'
AS $BODY$--DECLARE _RESULT VARCHAR;--DECLARE row record;declare _TOLERANCE FLOAT8 default 0.0000000000001;declare _SQLTMP text;declare _ISPOINTTYPE BOOLEAN;
beginexecute 'SELECT EXISTS (SELECT POSITION(''Polygon'' in ST_GEOMETRYTYPE(GEOM)) FROM ' ||targetTb|| ' LIMIT 1)' into _ISPOINTTYPE;-- 如果类型不是面,则不检查if _ISPOINTTYPE = false then return -1;end if;--ID、要素ID、是否已修正EXECUTE 'CREATE TABLE IF NOT EXISTS ' || resultTb ||' (id varchar DEFAULT (((''ID_''::text || to_char(now(), ''YYYYMMDDHH24MISS''::text)) || ''_''::text) || "substring"(md5(random()::text), 1, 10)) NOT NULL,geom Geometry,corrected Boolean)';execute 'DELETE FROM ' || resultTb;_SQLTMP :='-- 第一步:计算全部要素的外包矩形WITH all_box AS (SELECT ST_Envelope(ST_Union(geom)) AS boxFROM TARGET_TABLE), unionB as (SELECT ST_Simplify(ST_Union(st_buffer(GEOM_COLUMN,TOLERANCE_VALUE)),TOLERANCE_VALUE) AS BGEOM FROM TARGET_TABLE) -- 第二步:从外包矩形中依次去掉面要素, removed_box AS (SELECT ST_Difference(a.box, B.BGEOM) AS xFROM all_box aJOIN unionB b ON TRUE)-- 第三步:去掉与边界接触的子要素, filtered_x AS (SELECT ST_Difference(r.x, ST_Boundary(r.x)) AS yFROM removed_box r)-- 第四步:如果是几何集合则分解为简单对象, otherpolygons as (SELECT (ST_Dump(f.y)).* FROM filtered_x f), otherPolygons_sub as (select geom from otherpolygons where ST_NumInteriorRings(geom) > 0), interior_rings AS (SELECT ST_InteriorRingN(geom, generate_series(1, ST_NumInteriorRings(geom))) AS geomFROM otherPolygons_sub t)insert into RESULT_TABLE (geom)select op.geomfrom otherpolygons op, all_box ab where (st_touches(ST_ExteriorRing(ab.box),op.geom) = false)or(st_geometrytype(st_intersection(ST_ExteriorRing(ab.box),op.geom)) = ''ST_Point'')';_SQLTMP:= REPLACE(_SQLTMP,'RESULT_TABLE',resultTb);_SQLTMP:= REPLACE(_SQLTMP,'TARGET_TABLE',targetTb);_SQLTMP:= REPLACE(_SQLTMP,'GEOM_COLUMN',geomColumnName);_SQLTMP:= REPLACE(_SQLTMP,'TOLERANCE_VALUE',_TOLERANCE::VARCHAR);raise notice '_SQLTMP : %',_SQLTMP;execute _SQLTMP;RETURN resultTb;
end;
$BODY$;

测试调用

select public.sp_check_gap('TARGET_TABLE','RESULT_TABLE');

查询结果

select * from YOUR_RESULT_TABLENAME;

在这里插入图片描述

分析结果

在这里插入图片描述

这篇关于在PostGIS中一个面要素表中的缝隙(Find gaps among polygons in PostGIS)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1020178

相关文章

读软件设计的要素04概念的关系

1. 概念的关系 1.1. 概念是独立的,彼此间无须相互依赖 1.1.1. 一个概念是应该独立地被理解、设计和实现的 1.1.2. 独立性是概念的简单性和可重用性的关键 1.2. 软件存在依赖性 1.2.1. 不是说一个概念需要依赖另一个概念才能正确运行 1.2.2. 只有当一个概念存在时,包含另一个概念才有意义 1.3. 概念依赖关系图简要概括了软件的概念和概念存在的理

MongoDB学习—(6)MongoDB的find查询比较符

首先,先通过以下函数向BookList集合中插入10000条数据 function insertN(obj,n){var i=0;while(i<n){obj.insert({id:i,name:"bookNumber"+i,publishTime:i+2000})i++;}}var BookList=db.getCollection("BookList")调用函数,这样,BookList

Oracle把一个表的某个字段更新到另一张表中

第一种方法: update tablea set column_name1=(select name2 from tableb where tableb.name3=tablea.name1) 只修改一个 update tablea set column_name1=(select name2 from tableb where tableb.name3='a') where tablea.na

【NodeJS】Error: Cannot find module 'ms'

转载自:http://blog.csdn.net/echo_ae/article/details/75097004 问题: Error: Cannot find module 'ms'at Function.Module._resolveFilename (module.js:469:15)at Function.Module._load (module.js:417:25)at Module

leetCode#448. Find All Numbers Disappeared in an Array

Description Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. Find all the elements of [1, n] inclusive that do not appear in this

访问controller404:The origin server did not find a current representation for the target resource

ider build->rebuild project。Rebuild:对选定的目标(Project),进行强制性编译,不管目标是否是被修改过。由于 Rebuild 的目标只有 Project,所以 Rebuild 每次花的时间会比较长。 参考:资料

mybatis错误——java.io.IOException Could not find resource comxxxxxxMapper.xml

在学习Mybatis的时候,参考网上的教程进行简单demo的搭建,配置的没有问题,然后出现了下面的错误! Exception in thread "main" java.lang.RuntimeException: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause:

读软件设计的要素03概念的组合

1. 概念的组合 1.1. 概念不像程序那样,可以用较大的包含较小的 1.1.1. 每个概念对用户来说都是平等的,软件或系统就是一组串联运行的概念组合 1.2. 概念是通过操作来同步组合的 1.2.1. 同步并不增加新的概念操作,但会限制已有的操作,从而消除一些独立概念可能会出现的操作序列 1.3. 在自由组合中,概念彼此独立,仅受一些记录的约束,这些约束是为了确保概念对事物观点的一

Linux 中的 find 命令介绍以及使用

文章目录 Linux 中的 `find` 命令详解及使用示例`find` 命令的基本语法常用的 `find` 命令选项按文件名搜索:`-name`按文件类型搜索:`-type`按文件大小搜索:`-size`按修改时间搜索:`-mtime`按权限搜索:`-perm`按所有者搜索:`-user` 和 `-group` `find` 命令的常见操作删除找到的文件:`-exec` 和 `rm`查找并

mysql中find_in_set()函数

1.场景 假设有一个user用户表,表字段分别为:id(主键),name(姓名),age(年龄),hobby(爱好)。而一个人可能有好几个爱好,游泳啊篮球啊乒乓球啊等等。数据库里hobby字段存的是:游泳,篮球,乒乓球 而要想查所有喜欢游泳的人,就可以用find_in_set函数了 todo:贴图 2.使用 select *from user where find_in_set("游泳"