PostGIS를 사용하여 교차점을 기준으로 다각형 분리


36

일부는 서로 교차하는 다각형의 PostGIS 테이블이 있습니다. 이것이 내가하려고하는 일입니다.

  • id로 선택한 주어진 다각형에 대해 교차하는 모든 다각형을 알려주십시오. 원래,select the_geom from the_table where ST_Intersects(the_geom, (select the_geom from the_table where source_id = '123'))
  • 이 다각형에서 교차점이 새로운 다각형이되도록 새 다각형을 만들어야합니다. 따라서 다각형 A가 다각형 B와 교차하면 A-AB, AB 및 B-AB의 세 가지 새로운 다각형이 생깁니다.

어떤 아이디어?


1
흠, 나는 당신이 무엇을 얻고 있는지 알지만 간단한 그래픽은 나 (그리고 다른 사람들)가 당신이 원하는 것을 정확하게 볼 수 있도록 도움을 줄 수 있습니다.
Jason

내 답변에 일부를 추가했습니다.
Adam Matan

답변:


29

관심있는 각 다각형에 대해 교차 다각형 그룹이 있다고 말 했으므로 "다각형 오버레이"라고하는 것을 만들 수 있습니다.

이것은 정확히 Adam의 솔루션이하는 일이 아닙니다. 차이점을 보려면 ABC 교차점의이 그림을보십시오.

ABC 교차로

Adam의 솔루션이 "AB! C"및 "ABC"영역을 모두 포함하는 "AB"다각형과 "AC! B"및 "ABC"를 포함하는 "AC"다각형 및 " "BC! A"및 "ABC"인 BC "다각형. 따라서 "AB", "AC"및 "BC"출력 다각형은 모두 "ABC"영역과 겹칩니다.

다각형 오버레이는 겹치지 않는 다각형을 생성하므로 AB! C는 하나의 다각형이고 ABC는 하나의 다각형입니다.

PostGIS에서 다각형 오버레이를 만드는 것은 실제로 매우 간단합니다.

기본적으로 세 단계가 있습니다.

1 단계는 선 작업을 추출합니다. [ 다각형 의 외부 링 을 사용하고 있습니다. 구멍을 올바르게 처리하려면 조금 더 복잡해집니다] :

SELECT ST_ExteriorRing(polygon_col) AS the_geom FROM my_table) AS lines

2 단계는 선 작업을 "노드"하는 것입니다 (모든 교차점에서 노드 생성). JTS 와 같은 일부 라이브러리 에는이를 수행하는 데 사용할 수있는 "Noder"클래스가 있지만 PostGIS에서는 ST_Union 함수가이를 수행합니다.

SELECT ST_Union(the_geom) AS the_geom FROM (...your lines...) AS noded_lines

3 단계는 ST_Polygonize 함수 를 사용하여 모든 선에서 나올 수있는 겹치지 않는 다각형을 모두 만드는 것입니다 .

SELECT ST_Polygonize(the_geom) AS the_geom FROM (...your noded lines...)

각 단계의 출력을 임시 테이블에 저장하거나 모두 단일 명령문으로 결합 할 수 있습니다.

CREATE TABLE my_poly_overlay AS
SELECT geom FROM ST_Dump((
    SELECT ST_Polygonize(the_geom) AS the_geom FROM (
        SELECT ST_Union(the_geom) AS the_geom FROM (
            SELECT ST_ExteriorRing(polygon_col) AS the_geom FROM my_table) AS lines
        ) AS noded_lines
    )
)

내가 사용하고 ST_Dump를 각 행은 다각형 오버레이를 구성하는 다각형 중 하나입니다 테이블이 더 편리 ST_Polygonize의 출력이 형상 모음입니다 때문에, 그것은 (보통)입니다.


ST_ExteriorRing구멍 을 떨어 뜨립니다. ST_Boundary내부 링을 유지하지만 내부 링도 다각형을 만듭니다.
jpmc26

다각형이 너무 많으면 외부 링의 결합이 충돌합니다. 불행히도이 "직접적인"솔루션은 작은 범위에만 적용됩니다.
Pierre Racine

13

내가 올바르게 이해한다면, 당신은 취하고 싶습니다 (A는 왼쪽 형상, B는 오른쪽입니다) :

A∪B 이미지 http://img838.imageshack.us/img838/3996/intersectab1.png

그리고 추출 :

아 ∖ AB

A ∖ AB 이미지 http://img830.imageshack.us/img830/273/intersectab2.png

AB

AB의 이미지 http://img828.imageshack.us/img828/7413/intersectab3.png

그리고 B ∖ AB

B ∖ AB 이미지 http://img839.imageshack.us/img839/5458/intersectab4.png

즉, 모든 교차 쌍에 대해 세 가지 다른 형상이 있습니다.

먼저, 모든 교차 지오메트리의 뷰를 작성해 봅시다. 테이블 이름이이라고 가정하면 다음 polygons_table을 사용합니다.

CREATE OR REPLACE VIEW p_intersections AS    -- Create a view with the 
SELECT t1.the_geom as t1_geom,               -- intersecting geoms. Each pair
       t2.the_geom as t2_geom                -- appears once (t2.id<t2.id)
    FROM polygons_table t1, polygons_table t2  
         WHERE t1.id<t2.id AND t1.the_geom && t2.the_geom 
                           AND intersects t1.the_geom, t2.the_geom;

이제 교차 지오메트리 쌍을 저장하는 뷰 (실제로 읽기 전용 테이블)가 생겼습니다. 여기서 각 쌍은 t1.id<t2.id조건 으로 인해 한 번만 나타납니다 .

- 이제하자는 교차로를 수집 A∖AB, ABB∖ABSQL의를 사용하여, UNION모든 세 개의 쿼리에

--AB:
SELECT ST_intersection(t1.the_geom, t2.the_geom) 
    AS geom 
    FROM p_intersections

UNION 

--AAB:
SELECT ST_Difference(t1.the_geom, t2.the_geom) 
    AS geom 
    FROM p_intersections

UNION

--BAB:
SELECT ST_Difference(t2.the_geom, t1.the_geom) 
    AS geom 
    FROM p_intersections;

노트:

  1. &&오퍼레이터는 이전 필터로서 사용하는 intersects성능을 향상시키기 위해, 작업자.
  2. VIEW하나의 거대한 쿼리 대신에 생성하도록 선택했습니다 . 이것은 단지 편의를위한 것입니다.
  3. 당신이 의미하다면 AB노조가 아닌 교차로의입니다 AB상기 사용 ST_Union은 대신 ST_Intersection에 - UNION적절한 장소에서 쿼리.
  4. 기호 설정 차이에 대한 유니 코드 기호입니다; 데이터베이스를 혼동하는 경우 코드에서 제거하십시오.
  5. Wikimedia Commons의 멋진 세트 이론 범주 의 사진 제공 .

메타에 관한 나의 버그 티켓 : meta.gis.stackexchange.com/questions/79/…
Adam Matan

좋은 설명입니다! 결과는 scw 솔루션과 동일하지만 그의 방법은 더 빨라야합니다 (A와 B의 추가 교차점을 계산 / 저장 / 추가하지 않음)
stachu

감사! 테이블이 아닌 SQL VIEW 만 생성하므로 추가 정보를 저장하지 않는다고 생각합니다.
Adam Matan

예, 맞습니다. 그러나 A와 B의 추가 교차로를 계산하면 필요하지 않습니다
stachu

5
이 답변의 이미지는 더 이상 작동하지 않습니다.
Fezter

8

당신이 설명하는 것은 Union 연산자 가 ArcGIS에서 작동 하는 방식 이지만 GEOS 세계의 Union 또는 Intersection과 약간 다릅니다. Shapely 매뉴얼에는 GEOS에서 세트가 작동하는 방법에 대한 예제가 있습니다. 그러나 PostGIS 위키에는 선 작업을 사용 하는 좋은 예가 있습니다.

또는 세 가지를 계산할 수 있습니다.

  1. ST_Intersection (geom_a, geom_b)
  2. ST_ 차이 (geom_a, geom_b)
  3. ST_ 차이 (geom_b, geom_a)

두 번째 글 머리표에서 언급 한 3 개의 다각형이어야합니다.


2
PostGIS 위키 예제는 훌륭합니다
fmark

ST_Intersects가 교차하는지 여부를 부울 값으로 리턴하지 않습니까? ST_Intersection이 작동한다고 생각합니다.
Jason

그래, 내 부분의 오타-이제 원래 수정되었습니다. Jason!
scw

-2

다음과 같은 것 :

new_table VALUES에 삽입 ((st_intersects (the_geom, (id = '123'에서 id_'123 ')에서 old_table에서 id 선택, id ='123 '))) = true

편집 : 다각형의 실제 교차가 필요합니다.

new_table 값에 INSERT IN ((ID 선택, ST_Intersection (the_geom, (ID = 123에서 이전에서 the_geom 선택)))

그것이 작동하는지 확인하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.