2013-03-25 2 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) 

나는 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 것을 포함 된 다른 기하 구조의 결합을 빼줄 필요가 기하 구조에서, 그래서 모든 다각형이 이미 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

관련 문제