![](/img/trans.png)
[英]How to get the intersection length of touching geometries with ST_Touches
[英]Applying ST_Intersection on a list of geometries
我是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的文档,它们确实具有不同的签名,这表明取消链接ST_Union,ST_Intersection只能应用于两个几何。
有解决方案吗?
提前致谢
您可以使用WITH RECURSIVE
公共表表达式来处理带有运行结果的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;
“递归”将在最后一个数组索引处停止,或者结果为空。 另外,您可以通过注释掉最后一行来查看每个相交步骤。
您需要自我加入 。 例如:
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
我发现此解决方案似乎最适合我的情况。
创建函数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
区别很重要。 如果存在相同的多边形,则可能会出错。
这是最适合我的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.