![](/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.