GIS
[GIS 일기] PostGIS에서 Polygon에서 각 변의 길이 불러오기
정햄
2022. 1. 3. 19:03
PostGIS에 저장되어있는 Polygon에 대해 가장 긴 변의 길이를 구하고 싶다는 요청이 들어왔다.
이에 구글링하면서 레퍼런스를 찾았고 그 결과에 대해 좀 더 덧붙여서 기록하려고 한다.
원본
SELECT ST_AsText( ST_MakeLine(sp,ep) )
FROM
-- extract the endpoints for every 2-point line segment for each linestring
-- call two points as start point and end point from each boundary(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
-- ST_Dump : multi-part to single-parts ex) Multipolygon to a set of polygons
(SELECT (ST_Dump(ST_Boundary(geom))).geom
FROM mypolygontable
) AS linestrings
) AS segments;
- ST_Dump : 한 feature를 이루고 있는 하위 단계의 feature들이 존재한다면 ST_Dump는 이를 하위 단계의 feature들의 집합으로 변환해서 내보낸다. multipolygon의 경우 여러 polygon들이 모여서 multipolygon을 이루기 때문에 ST_Dump(multipolygon)의 결과는 polygon의 집합이다.
- generate_series : generate_series(start, stop, step)
- ST_PointN : N번째 점을 얻는 함수.
2개의 view가 사용되어 좀 정신없을 수 있는데 차근 차근 보면 view의 결과를 엮을 수 있을 것이다.
예시코드
SELECT ST_length( ST_MakeLine(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_Transform(ST_Boundary(ST_Polygon('LINESTRING(75 29, 77 29, 77 25, 75 25, 75 29)'::geometry, 4326)), 3857))).geom
) AS linestrings
) AS segments;
결과
222638.98158654384
499901.41056706756
222638.98158654384
499901.41056706756
ST_length는 대상의 좌표계의 unit에 따라 길이를 계산하기 때문에, meter로 계산하려면 3857로 transform해줘야 한다.