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, AB및 B∖ABSQL의를 사용하여, UNION모든 세 개의 쿼리에

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

UNION 

--A∖AB:
SELECT ST_Difference(t1.the_geom, t2.the_geom) 
    AS geom 
    FROM p_intersections

UNION

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

노트:

  1. &&오퍼레이터는 이전 필터로서 사용하는 intersects성능을 향상시키기 위해, 작업자.
  2. VIEW하나의 거대한 쿼리 대신에 생성하도록 선택했습니다 . 이것은 단지 편의를위한 것입니다.
  3. 당신이 의미하다면 AB노조가 아닌 교차로의입니다 A및 B상기 사용 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.