2013-03-25 10 views
7

私は空間テーブル内のすべてのポリゴン間の再帰的交差を実行し、結果の(多)ポリゴンとそれぞれの交差点に関する情報を取得しようとしています。PostGISポリゴン間の再帰的交差

画像(ない本当にスケールで)それを説明する: Example

のはA, B, C四角がテーブルにあるとしましょう。 A, B, C, A+B, A+C, B+C, A+B+Cポリゴンを出力したいと思います。A+BABのように交差することを知る必要があります。

これまでのところ、交差点を実行するクエリがありますが、元のポリゴンの交差部分を「切断」しません。例えば:

Polygon A should be  A - (A+B) - (A+C) - (A+B+C) 
Polygon A+C should be A+C - (A+B+C) 

IはAA+Cポリゴンのために今取得結果の画像:

Current WRONG result

ここでは、データとして、画像内の四角形を使用して、テストスクリプトです。 areaの列を見ると、いくつかの再帰的なST_Differenceが欠落していることが明らかです。私は方法を理解できません。どんなアイデアも歓迎されます。

-- Create a test table 
CREATE TABLE test (
    name text PRIMARY KEY, 
    geom geometry(POLYGON) 
); 

-- Insert test data 
INSERT INTO test (name, geom) VALUES 
    ('A', ST_GeomFromText('POLYGON((1 2, 1 6, 5 6, 5 2, 1 2))')), 
    ('B', ST_GeomFromText('POLYGON((0 0, 0 4, 4 4, 4 0, 0 0))')), 
    ('C', ST_GeomFromText('POLYGON((2 0, 2 4, 6 4, 6 0, 2 0))')); 


-- Query  
WITH RECURSIVE 
source (rownum, geom, ret) AS (
    SELECT row_number() OVER (ORDER BY name ASC), ST_Multi(geom), ARRAY[name] FROM test 
), 
r (rownum, geom, ret, incroci) AS (
    SELECT rownum, geom, ret, 0 FROM source 
    UNION ALL 
    SELECT s.rownum, ST_CollectionExtract(ST_Intersection(s.geom, r.geom), 3), (r.ret || s.ret), (r.incroci + 1) 
     FROM source AS s INNER JOIN r ON s.rownum > r.rownum AND ST_Intersects(s.geom, r.geom) AND ST_Area(ST_Intersection(s.geom, r.geom)) > 0.5 
), 
result (geom, ret) AS (
    SELECT ST_Union(geom) AS geom, ret FROM r GROUP BY ret 
) 
SELECT geom, ST_Area(geom) AS area, ret FROM result ORDER BY ret 

ウィンドウ関数はもちろん、この特定の例では厳密には必要ありませんが、このコードは、側にいくつかのより多くの事をして、私の本当の場合、の簡易版です。

私はあなたがすべてのあなたがRETことを含む他のgeomの労働組合を減算する必要がありGEOMからのように、すべてのポリゴンを持っているすでに、2.0

答えて

4

ST_DIFFRENCEは再帰的である必要はありません。PostgreSQLの9.2とのPostGISを使用していますが、それと同じではありません。これはうまくいくように機能します。

WITH RECURSIVE 
source (rownum, geom, ret) AS (
    SELECT row_number() OVER (ORDER BY name ASC), ST_Multi(geom), ARRAY[name] FROM test 
), 
r (rownum, geom, ret, incroci) AS (
    SELECT rownum, geom, ret, 0 FROM source 
    UNION ALL 
    SELECT s.rownum, ST_CollectionExtract(ST_Intersection(s.geom, r.geom), 3), (r.ret || s.ret), (r.incroci + 1) 
     FROM source AS s INNER JOIN r ON s.rownum > r.rownum AND ST_Intersects(s.geom, r.geom) AND ST_Area(ST_Intersection(s.geom, r.geom)) > 0.5 
), 
result (geom, ret) AS (
    SELECT ST_Difference(ST_Union(r.geom),q.geom) AS geom, r.ret FROM r JOIN (SELECT r.ret,ST_UNION(COALESCE(r2.geom,ST_GeomFromText('POLYGON EMPTY'))) as geom FROM r LEFT JOIN r AS r2 ON r.ret<@r2.ret AND r.ret!=r2.ret GROUP BY r.ret) AS q on r.ret=q.ret GROUP BY r.ret,q.geom 
) 
SELECT geom, ST_Area(geom) AS area, ret FROM result ORDER BY ret 
+0

本当にこのような自己結合を使用していただきありがとうございます! – Eggplant

関連する問題