如何使用PostGIS从单个表中选择所有相交多边形组

问题描述 投票:0回答:1

给定如图所示的相交多边形组表。(https://i.stack.imgur.com/hlXs1.png)我们如何选择所有相交的多边形组?

以下查询使用递归,获得了一些结果,但它复制了所有组以及组内具有多个重叠重复多边形的组。

WITH RECURSIVE cte AS (

     SELECT id AS root_id,
            id, ARRAY[id] AS path,
            geom
       FROM polygons

      UNION ALL
     SELECT cte.root_id,
            t.id, path || t.id,
            t.geom
       FROM polygons AS t,
            cte
      WHERE t.id <> ALL(cte.path)
        AND ST_Intersects(t.geom, cte.geom) 
)

SELECT root_id, ARRAY_AG(id)
  FROM cte
 GROUP BY root_id
 ORDER BY root_id

最终的选择如下所示:

root_id 数组_agg
1 1,2
2 2,1
3 3,4,5,6
4 4,3,5,6
5 5,4,6,3
6 6,5,4,3
7 7,8,9,9,8
8 8,7,9,9,7
9 9,7,8,8,7
10 10

您将注意到,

root_id
1 和 2 的选择包含相同的多边形,
root_id
7、8 和 9 包含组内所有重复的多边形。

sql postgresql recursion gis postgis
1个回答
0
投票

PostGIS 3.4.0 中添加了一个函数,其名称与

ST_ClusterIntersectingWin()
完全一样。
db<>fiddle 的演示:

explain analyze verbose 
create table my_shapes_clustered2 as
select 1+ST_ClusterIntersectingWin(geom)over() as cluster_number, *
from my_shapes;
查询计划
WindowAgg(成本=0.00..15091.00行=1200宽度=391)(实际时间=5.639..5.948行=1200循环=1)
  输出:(1 + st_clusterintersectingwin(geom) OVER (?)), id, initial_seed, geom
  -> public.my_shapes 上的顺序扫描(成本=0.00..76.00 行=1200 宽度=387)(实际时间=0.006..0.215 行=1200 循环=1)
        输出:geom,id,initial_seed
规划时间:0.063毫秒
执行时间:8.455 ms
select cluster_number,st_area(st_union(geom)),count(*),array_agg(id)
from my_shapes_clustered2 
group by cluster_number 
order by cluster_number 
limit 8;
簇号 st_区域 数组_agg
1 836.248837776196 2 {798,1}
2 651.4061064388445 1 {2}
3 53.56050595625381 1 {3}
4 269.4408305746047 1 {4}
5 1596.5821681225993 4 {507,5,676,72}
6 1262.1100035153077 3 {186,296,6}
7 2008.7632476757103 4 {474,891,7,1121}
8 66.289777695502 1 {8}

在 PostGIS 2.3.0+ 中,使用@JGH建议的

ST_ClusterDBSCAN(geom,0,1) 函数,可以获得相同的结果,尽管速度稍慢:

explain analyze verbose create table my_shapes_clustered3 as select 1+ST_ClusterDBSCAN(geom,0,1)over() as cluster_number, * from my_shapes;
查询计划WindowAgg(成本=0.00..15091.00行=1200宽度=391)(实际时间=17.688..18.018行=1200循环=1)  输出:(1 + st_clusterdbscan(geom, '0'::双精度, 1) OVER (?)), id, initial_seed, geom  -> public.my_shapes 上的顺序扫描(成本=0.00..76.00 行=1200 宽度=387)(实际时间=0.005..0.218 行=1200 循环=1)        输出:geom,id,initial_seed规划时间:0.041毫秒执行时间:21.007 ms
在 2.2.0 中,有一些更笨重的

ST_ClusterIntersecting()

,即吐出集合。

© www.soinside.com 2019 - 2024. All rights reserved.