두 다각형의 서로 다른 노드 세트 (녹색 다각형 A, 빨간색 다른 폴리온 B 세그먼트) 때문에 약간 까다로운 것으로 생각됩니다. 두 다각형의 세그먼트를 비교하면 다각형 B의 세그먼트가 수정 될 단서가됩니다.
노드 다각형 A
"다른"세그먼트의 노드 다각형 B
불행히도 이것은 세그먼트 구조의 차이점 만 보여 주지만 이것이 출발점이며 다음과 같이 작동하기를 바랍니다.
다운로드 및 압축 해제 프로세스 후 데비안 리눅스 Jessie에서 PostgrSQL 9.46, PostGIS 2.1을 사용하여 데이터 세트를 가져 왔습니다.
$ createdb gis-se
$ psql gis-se < /usr/share/postgis-2.1/postgis.sql
$ psql gis-se < /usr/share/postgis-2.1/spatial_ref_sys.sql
$ shp2pgsql -S polygon_a | psql gis-se
$ shp2pgsql -S polygon_b | psql gis-se
다각형 A의 세그먼트가 B에 있지 않고 그 반대 인 경우, 두 다각형 세트의 세그먼트 사이에 차이를 만들어서 각 그룹 (A 또는 B)의 다각형에 대한 세그먼트 멤버쉽을 무시합니다. 교훈적인 이유 때문에 여러 가지 관점에서 SQL을 공식화했습니다.
이 GIS-SE 게시물 에 따라 두 다각형을 세그먼트 테이블로 분해 segments_a
하고segments_b
-- Segments of the polygon A
CREATE VIEW segments_a AS SELECT sp, ep
FROM
-- extract the endpoints for every 2-point line segment for each linestring
(SELECT
ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) as sp,
ST_PointN(geom, generate_series(2, ST_NPoints(geom) )) as ep
FROM
-- extract the individual linestrings
(SELECT (ST_Dump(ST_Boundary(geom))).geom
FROM polygon_a
) AS linestrings
-- be sure that nothing is scrambled
ORDER BY sp, ep
) AS segments;
세그먼트 테이블 다각형 A :
SELECT
st_astext(sp) AS sp,
st_astext(ep) AS ep
FROM segments_a
LIMIT 3;
sp | ep
-------------------------------------------+--------------------------------------------
POINT(-292.268907321861 95.0342877387557) | POINT(-287.118411917425 99.4165242769195)
POINT(-287.118411917425 99.4165242769195) | POINT(-264.62129248575 93.2470010145007)
POINT(-277.459563916327 -44.5629543976138) | POINT(-292.268907321861 95.03428773875
동일한 절차가 다각형 B에도 적용되었습니다.
-- Segments of the polygon B
CREATE VIEW segments_b AS SELECT sp, ep
FROM
-- extract the endpoints for every 2-point line segment for each linestring
(SELECT
ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) as sp,
ST_PointN(geom, generate_series(2, ST_NPoints(geom) )) as ep
FROM
-- extract the individual linestrings
(SELECT (ST_Dump(ST_Boundary(geom))).geom
FROM polygon_b
) AS linestrings
-- be sure that nothing is scrambled
ORDER BY sp, ep
) AS segments;
세그먼트 테이블 다각형 B
SELECT
st_astext(sp) AS sp,
st_astext(ep) AS ep
FROM segments_b
LIMIT 3;
sp | ep
-------------------------------------------+-------------------------------------------
POINT(-292.268907321861 95.0342877387557) | POINT(-287.118411917425 99.4165242769195)
POINT(-287.118411917425 99.4165242769195) | POINT(-264.62129248575 93.2470010145007)
POINT(-277.459563916327 -44.5629543976138) | POINT(-292.268907321861 95.0342877387557)
...
이라는 차분 테이블 뷰를 만들 수 있습니다 segments_diff_{a,b}
. 차이는 세그먼트 세트 A 및 B에서 정렬 된 시작점 또는 종료 점이 발생하지 않음으로 나타납니다.
CREATE VIEW segments_diff_a AS
SELECT st_makeline(b.sp, b.ep) as geom
FROM segments_b as b
LEFT JOIN segments_a as a ON (a.sp=b.sp and a.ep = b.ep)
-- filter segments without corresponding stuff in polygon A
WHERE a.sp IS NULL;
그리고 보완적인 것들 :
CREATE VIEW segments_diff_b AS
SELECT st_makeline(a.sp, a.ep) as geom
FROM segments_a as a
LEFT JOIN segments_b as b ON (a.sp=b.sp and a.ep = b.ep)
-- filter segments without corresponding stuff in polygon B
WHERE b.sp IS NULL;
결론 : 빨간색 화살표로 표시된 작은 작은 선분에 대해 적절한 결과를 얻으려면 두 다각형에 모두 노드 구조가 동일해야하며 노드 수준에서 교차 단계 (B에 다각형 A의 꼭지점 삽입)가 필요합니다. 교차로는 다음과 같이 수행 할 수 있습니다.
CREATE VIEW segments_bi AS
SELECT distinct sp, ep
FROM (
SELECT
ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) as sp,
ST_PointN(geom, generate_series(2, ST_NPoints(geom) )) as ep
FROM (
SELECT st_difference(b.seg, a.seg) as geom FROM
segments_diff_a as a, segments_diff_b as b
WHERE st_intersects(a.seg, b.seg)
) as cut
) as segments
WHERE sp IS NOT NULL AND ep IS NOT NULL
ORDER BY sp, ep;
그러나 이상한 결과가 ...