使用PostGIS识别“长而窄”的多边形


10

我有一组代表大面积的多边形,例如城市社区。我想确定它们之间的大重叠区域。

但是存在一个问题:有时这些多边形会沿其周界重叠(因为它们绘制的精度很低)。这将产生我不关心的长而窄的重叠。

但其他时候,健壮多边形会出现大量重叠,这意味着邻域的多边形会与另一个多边形重叠的较大区域。我只选择这些。

请参见下面的重叠图片。想象一下,我只想选择左下角的蓝色多边形。

交叠

我可以看一下区域,但是有时狭窄的区域是如此之长,以至于最终它们会具有与蓝色多边形一样大的区域。我试图做一个面积/周长的比率,但这也产生了混合的结果。

我什至尝试使用ST_MinimumClearance,但是有时大区域会附上一个狭窄的部分,或者两个非常接近的顶点。

对其他方法有什么想法吗?


最后,最适合我的方法是使用负缓冲区,如下面的@Cyril和@FGreg所建议。

我使用了类似的东西:

ST_Area(ST_Buffer(geom, -10)) as neg_buffer_area

在我的情况下,单位为米,因此10 m负缓冲。

对于窄多边形,该区域返回零(同样,几何图形将为空)。然后,我使用此列来过滤出狭窄的多边形。


4
当然,可以使用面积/周长比。
文斯

很难说出图像中不同的多边形在哪里,但是执行类似gis.stackexchange.com/a/265233/64838的操作可能有用吗?计算最小旋转边界框,然后丢弃宽度或高度较小的边界框。
FGreg

您还可以尝试按如下所述使用负缓冲区:如何在形状文件中识别出真正的细多边形?
FGreg

Answers:


5

我会尝试创建一个负缓冲区,如果它吃了薄多边形,那很好,如果它不吃多边形,那是我的... :-)

运行此脚本,预先设置线性多边形的宽度的2/3 ...

create table name_table as
SELECT ST_Buffer(
(ST_Dump(
(ST_Union(
ST_Buffer(
(geom),-0.0001))))).geom,
0.0001)) as geom from source_table

操作系统:-)...


最后,您的建议最适合我。我最终使用了类似ST_Area(ST_Buffer(geom, -10))的东西,在我的情况下,-10为-10米。如果从该表达式返回0,则可以将其过滤掉。
bplmp

9

代替面积/周长,最好使用面积除以周长的平方(或其倒数)。

这也称为“形状指数”。周长除以面积的平方的最小值为4 * Pi()(对于磁盘,这是最紧凑的2D几何形状),因此可以通过4 * Pi()进行归一化,解释(接近1的归一化值意味着您拥有非常紧凑的对象,并且正方形的值大约为1.27)。

编辑:该区域的阈值将对消除非常小的伪像很有用,它可能很紧凑。然后,形状指数将显示出更好的对比度。编辑:除了此答案,使用ST_Snap可以帮助您在问题发生之前解决问题。


谢谢!但是我不确定在这种情况下ST_Snap有什么帮助...如果我做对了,您在建议类似的东西(o.overlap_perimeter^2 / o.overlap_area) / (4 * Pi()) as overlap_ratio?对于我来说,这不仅仅是面积/周长的结果。
bplmp

现在o.overlap_perimeter / (4 * sqrt(o.overlap_area)) as overlap_ratio根据本文使用,但结果仍然较差(尽管很难量化我所说的更糟),isprs-ann-photogramm-remote-sens-spatial-inf-sci.net/ I-7/ 135/…,第页183.
bplmp

2
谢谢您,我从未听说过“形状指数”。我一直认为使用最小边界矩形是回答此类问题的最佳方法。我发现这个,repository.asu.edu / attachments / 111230 / content /…,这很有趣。
John Powell

@JohnPowell有趣的论文,谢谢。我看到在本文中我将形状索引称为圆度索引。我的最小边界矩形问题是它不适用于非常凹的物体(例如U形)
radouxju

@bplmp ST_Snap将帮助您捕捉“近”相邻多边形的顶点,以使它们不再重叠。您的图形没有比例,但是您的伪像看起来像线条,因此我想您可以使用容差值剧院来避免伪像,但不会影响大多边形。
radouxju

5

一种选择是使用多边形面积与可以使用其末端绘制的最长线的比率。识别狭窄的长多边形。

select * from polygons where ST_Length(ST_LongestLine(geom, geom)) < ST_Area(geom) * 4

这对于条形多边形非常有效。您可以调整比例(乘以面积)以适合您的需求和投影。


1

听起来这可能与您的用例匹配:消除选定的多边形

通过擦除输入多边形的公共边界,将输入层的选定多边形与某些相邻多边形合并。相邻的多边形可以是面积最大或最小的多边形,也可以是与要消除的多边形共享最大公共边界的多边形。

消除通常用于消除条形多边形,即微小多边形,这是多边形交集过程的结果,在该过程中,输入的边界相似但不相同。

听起来您想尝试使用“最大公共边界”选项。


我知道现在您要的是Postgis解决方案,而不是qgis解决方案。抱歉,我认为postgis没有同样的功能,但我将其保留给后代。
FGreg

0

在我看来,这似乎是PostGIS拓扑扩展的理想用例。拓扑的公差参数将确定允许顶点捕捉到其他现有多边形的距离,以应对源数据的低精度并进行清理。

简而言之,策略是:

1.启用拓扑扩展

CREATE EXTENSION postgis_topology;

2.创建一个新的空拓扑

SELECT topology.CreateTopology('neighborhoods_topo', 4326, 1e-7);

第三个参数是公差,以CRS为单位;明智地选择它。理想情况下,您需要单位为米的CRS。如果CRS单位不是米,例如WGS 84 aka 4326,则用于ST_Transform重新投影多边形。

3.将“ TopoGeometry”列添加到多边形表

SELECT topology.AddTopoGeometryColumn('neighborhoods_topo', 'public', 'neighborhoods', 'topogeom', 'POLYGON');

这将返回一个新的layer_id。保存它,以后将需要它。1如果您从头开始,它将是分层的,并在每次新呼叫时增加。

4.将所有多边形添加到拓扑中

UPDATE public.neighborhoods
SET topogeom = topology.toTopoGeom(geom, 'neighborhoods_topo', 1, 1e-7);

对于大型数据集,这可能需要几个小时,请耐心等待。1是较早返回的layer_id。

5.查找出现在多个社区中的面孔

从拓扑中找到存在于2个或更多拓扑中的所有面。我将把查询保留为练习。最简单的方法可能是使用该GetTopoGeomElements函数,然后按面部ID分组,然后查看计数为2或更大的对象。或者,您可以使用拓扑表列中的清理后的几何图形创建一个新表,将其转换为标准几何图形topogeom::geometry,然后重复执行现在已有的操作,但现在使用一个干净的数据集而不会出现条重叠。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.