12

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

それを説明するための画像(実際には縮尺は合っていません): 例

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)

AA+Cポリゴンについて今得た結果の画像:

現在の間違った結果

これは、画像内の正方形をデータとして使用するテストスクリプトです。列を見ると、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

もちろん、この特定の例ではウィンドウ関数は厳密には必要ありませんが、このコードは私の実際のケースの単純化されたバージョンであり、側面でさらにいくつかのことを行います。

PostgreSQL9.2とPostGIS2.0を使用しています

4

1 に答える 1

7

ST_DIFFRENCEは再帰的である必要はありません。すでにすべてのポリゴンがあるので、すべてのジオメトリから、そのretを含むがそれに等しくない他のジオメトリの和集合を差し引く必要があります。これは機能するので、次のようにする必要があります。

    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
于 2013-03-25T23:32:01.453 に答える