웹 애플리케이션에서는 사용자 경험을 향상하기 위해 지리적 위치 데이터를 활용하는 경우가 많습니다.
예를 들어, 지도 및 내비게이션 서비스에서 두 지점 간의 경로를 안내하거나, 주변 장소를 검색하는 기능이 필요합니다.
오픈 소스 DBMS인 PostgreSQL과 이를 확장하여 공간 데이터를 처리할 수 있게 해주는 PostGIS는 공간 참조 시스템, 공간 데이터 타입, 공간 인덱스 등을 제공하여 복잡한 공간 데이터를 효율적으로 처리할 수 있도록 지원합니다.
이를 활용해 두 지점 간의 거리 계산, 주변 반경 검색, 경로 최적화 등 다양한 공간 연산을 수행할 수 있는데, 이 중 두 지점 간의 거리 계산에 대해 알아보도록 하겠습니다.
PostgreSQL & PostGIS 설치하기
저는 Docker Compose 환경을 구성했습니다.
여러 환경별 자세한 설치 방법은 아래 링크를 참고해 주세요.
PostgreSQL에 PostGIS가 설치된 이미지를 사용해 아래와 같이 스크립트를 작성해 줍니다.
services:
postgres:
image: 'postgis/postgis:15-3.3'
container_name: 'postgres'
restart: always
environment:
- 'POSTGRES_DB=mydatabase'
- 'POSTGRES_USER=root'
- 'POSTGRES_PASSWORD=root1234'
ports:
- '5432:5432'
volumes:
- 'postgres-data:/var/lib/postgresql/data'
volumes:
postgres-data:
사용해 보기
아래 쿼리를 통해 PostGIS가 정상적으로 설치되었는지 확인할 수 있습니다.
-- PostGIS Version Check
SELECT postgis_full_version();
두 지점 간의 직선거리 계산 함수
- ST_DistanceSphere
ST_DistanceSphere 함수는 지구를 완벽한 구로 가정하여, 두 지점 간의 구면 거리를 계산합니다.
실제 지구는 완벽한 구가 아닌, 타원형이기 때문에 실제 거리보다 약간의 오차가 발생할 수 있습니다.
그러나, 이 함수는 계산 속도가 매우 빠르다는 장점이 있습니다.
SELECT ST_DistanceSphere(
ST_GeomFromText('POINT(127.009358 37.566388)'), -- 경도 위도 순입니다. 주의!
ST_GeomFromText('POINT(127.010655 37.566988)')
);
- ST_DistanceSpheroid
ST_DistanceSpheroid 함수는 지구를 타원체로 가정하여 , 두 지점 간의 타원체 거리를 계산합니다.
Spheroid 매개변수를 생략하면 기본값으로 WGS84 타원체 모델을 사용하고, ST_DistanceSphere 함수보다 더 정밀하게 거리를 계산할 수 있습니다.
SELECT ST_DistanceSpheroid(
ST_GeomFromText('POINT(127.009358 37.566388)', 4326),
ST_GeomFromText('POINT(127.010655 37.566988)', 4326),
'SPHEROID["WGS 84",6378137,298.257223563]'
);
💡용어 정리
- 구면 거리
지구와 같은 둥근 표면 위에서 두 점 사이를 직선으로 잇는 것이 아니라, 둥근 표면을 따라가는 거리를 말합니다.
- 타원체 거리
타원체 표면 위에서 두 점 사이의 거리를 말합니다. 실제 지구는 완벽한 구가 아니라 적도 부근이 약간 부풀어 오른 타원체(지구 타원체)이므로, 타원체 거리는 이러한 지구의 형태를 고려하여 계산한 거리입니다.
- 타원체 모델
지구의 형상을 타원체로 가정하여 정의한 모델
- WGS84
현재 가장 널리 사용되는 지리좌표계
Google Map 거리 측정과 비교해 보기
- 지점 1
- 위도: 37.566388
- 경도: 127.009358
- 지점 2
- 위도: 37.566988
- 경도: 127.010655
ST_DistanceSphere → 실행시간 0.003 ms / Google Map과 오차 약 29cm
ST_DistanceSpheroid → 실행시간 0.025 ms / Google Map과 오차 약 11cm
(Google Map 조작 과정에서 오차가 포함되었을 수 있습니다.)
두 함수의 실행 결과를 통해 실행 시간 차이, 정밀도를 확인할 수 있었습니다.
실제 사용 시에는 이 차이를 고려해 적절한 함수를 선택하는 것이 좋을 듯합니다.
탐구 - 어떻게 계산하고 있는 걸까?
하버사인 공식