[GIS] PostGIS : ST_Within함수를 통해 지오메트리의 완전 포함여부를 확인해보자.
ST_Intersects에 이어 쓰는 글..
ST_Within는 ST_Intersects와 비슷한 녀석이다.
단 이 ST_Within는 리턴값이 BOOLEAN이며, 완전히 포함할 때만 TRUE을 리턴한다.
그럼 정리를 해보자.
※ 관련 자료를 찾아보니 Oracle 및 SQLite는 리턴값이 INTEGER이고 PostgreSQL는 BOOLEAN값을 리턴한다고 한다.
ST_Within 함수란?
ST_Within함수는 2개의 지오메트리 타입 매개변수(파라메터)를 받고,
1번째 파라메터가 2번째 파라메터 내에 완전히 포함되어 있는 경우 True를 리턴하고 그렇지 않으면 False를 리턴한다.
PolygonTable과 PointTable라는 테이블이 있다. 각 테이블은 지오메트리 컬럼을 가지고 있고
PolygonTable 테이블과 PointTable테이블의 각 컬럼 중 point가 Polygon내에 완전히 포함되어 있는지
여부를 판단하고 싶을 때 ST_Within 함수를 이용할 수 있다.
만약 위와 같은 상황에서 ST_Within함수를 통해 PolygonTable의 지오메트리를 추출한다면
A, D, E, F를 포함하는 4개의 row가 추출(TRUE 리턴) 될 것이다.
※ 위에서 Point로 했지만 다른 타입도 됨 ( Polygon이나 Line 등.. )
ST_Within 함수 코드 작성
ST_Within 함수는 기본적으로 true 또는 false를 리턴한다.
그렇기 때문에 보통 ST_Within 함수는 where의 조건절로 주로 사용된다. ( 샘플코드 참조 )
기본문법
SELECT st_within(a.geom, b.geom) FROM PointTable a, PolygonTable b;
샘플코드
-- WHERE조건절을 주어 point를 완전히 포함하는 Polygon만 추출함
-- 아래 두 쿼리를 같은 결과를 가져옴
SELECT b.geom
FROM PointTable a, PolygonTable b
WHERE st_within(a.geom, b.geom);
SELECT b.geom
FROM PointTable a, PolygonTable b
WHERE st_within(a.geom, b.geom) = 't';
※ 단 두 테이블의 지오메트리 컬럼의 좌표계가 일치해야 한다. 만약 일치 하지 않는다면
st_transform함수를 통하여 좌표계를 변경해줘야 한다.
--PolygonTable의 지오메트리 컬럼의 좌표계는 5174이고,
--PointTable의 지오메트리 컬럼의 좌표계가 4326이라고 한다면
--st_transform함수를 이용하여 PointTable의 지오메트리 컬럼의 좌표계를 5174로 변경하여 사용
SELECT a.geom FROM PointTable a, PolygonTable b
WHERE st_within(st_transform(a.geom), b.geom);
지오메트리에 좌표계 자체가 설정이 안된 경우에는
st_setsrid함수로 좌표계를 우선 설정한 후에, st_transform함수로 좌표계를 변경해줄 수 있다.
-- st_setsrid함수로 우선 좌표계 설정후, st_transform함수로 좌표계 변경
(st_transform(st_setsrid(a.geom ,4326), 5174), b.geom);