我是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_Union与ST_Intersection的文档,它们确实有不同的签名,这表明unlinke ST_Union,ST_Intersection只能应用于2个几何。
有解决方法吗?
提前致谢
答案 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;停在最后一个数组索引上,或者如果结果为空。此外,您可以通过注释掉最后一行来查看每个交叉步骤。
答案 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);
通过这种方式,您可以将表格与自身进行比较。这两个条件保证:
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
独特是重要的。如果有相同的多边形,可能会出错。
这对我来说最有效。