在几何列表

时间:2016-09-14 18:27:48

标签: sql postgresql postgis

我是postgis的新手,所以,对不起,如果这是一个愚蠢的问题。

我在表格中有一个多边形列表,我想找到它们之间的交叉点。 我可以做一个没有问题的ST_Union:

select ST_Union(t.geom) from mytable t

但同样不适用于ST_Intersection

select ST_Intersection(t.geom) from mytable t` ERROR: function st_intersection(geometry) does not exist

查看ST_UnionST_Intersection的文档,它们确实有不同的签名,这表明unlinke ST_Union,ST_Intersection只能应用于2个几何。

有解决方法吗?

提前致谢

3 个答案:

答案 0 :(得分:1)

您可以使用WITH RECURSIVE common table expression来处理具有正在运行结果的geometry[]的每个元素。

以下是基于重叠缓冲随机位置(图中的蓝色多边形)的一些示例数据:

DROP TABLE IF EXISTS ar;
SELECT array_agg(ST_Buffer(ST_MakePoint(random(), random()), 0.5, 3)) AS geoms
INTO TEMP ar
FROM generate_series(1, 6) AS id;
SELECT ST_Collect(geoms) FROM ar;

这就是魔术:

WITH RECURSIVE inter AS (
   -- First geometry
   SELECT 1 AS idx, geoms[1] AS geom FROM ar a
   UNION ALL
   -- Remaining geometries with the previous result
   SELECT a.idx + 1, ST_Intersection(a.geom, b.geoms[a.idx + 1])
   FROM inter a, ar b
   WHERE a.idx + 1 <= array_length(geoms, 1) AND NOT ST_IsEmpty(a.geom)
)
SELECT * FROM inter
ORDER BY idx DESC LIMIT 1;

&#34;递归&#34;停在最后一个数组索引上,或者如果结果为空。此外,您可以通过注释掉最后一行来查看每个交叉步骤。

img

答案 1 :(得分:0)

您需要self join。 例如:

SELECT ST_intersection(a.geom,b.geom) 
FROM mytable AS a, mytable AS b 
WHERE st_equals(a.geom, b.geom) IS FALSE AND ST_intersects(a.geom, b.geom);

通过这种方式,您可以将表格与自身进行比较。这两个条件保证:

  • 两个几何形状不一样
  • 两个几何相交(否则ST_Intersections将返回GEOMETRYCOLLECTION EMPTY

如果您的表有ID列,则可以使用

WHERE a.id != b.id

而不是

WHERE st_equals(a.geom, b.geom) IS FALSE 

答案 2 :(得分:0)

我发现this solution似乎对我的情况最有效。

创建函数ST_IntersectionArray后建议

create or replace function ST_IntersectionArray(geoms geometry[]) returns geometry as $$ declare i integer; tmpGeom geometry; begin tmpGeom := geoms[1]; FOR i IN 1..array_length(geoms,1) LOOP tmpGeom:= ST_Intersection(tmpGeom,geoms[i]); END LOOP; return tmpGeom; end; $$ LANGUAGE plpgsql;

你可以做到

select ST_Intersection(array_agg(distinct t.geom)) from mytable t

独特是重要的。如果有相同的多边形,可能会出错。

这对我来说最有效。