두 위도 경도 지점 간 거리 계산 (헤버사인 공식)
2024-07-27
개요
이 알고리즘은 다음과 같은 분야에 유용하게 활용될 수 있습니다.
- 여행 거리 계산: 두 도시 간의 거리를 계산하여 여행 계획을 세울 수 있습니다.
- 배송 경로 최적화: 여러 배송 지점 간의 거리를 계산하여 가장 효율적인 배송 경로를 찾을 수 있습니다.
- 위치 기반 서비스: 가까운 식당, 카페, 관광지 등을 검색하는 기능에 활용될 수 있습니다.
알고리즘
헤버사인 공식은 다음과 같습니다.
def haversine_distance(lat1, lon1, lat2, lon2):
"""
두 위도 경도 지점 사이의 거리를 계산합니다.
Args:
lat1: 첫 번째 지점의 위도 (라디안 단위).
lon1: 첫 번째 지점의 경도 (라디안 단위).
lat2: 두 번째 지점의 위도 (라디안 단위).
lon2: 두 번째 지점의 경도 (라디안 단위).
Returns:
두 지점 사이의 거리 (미터 단위).
"""
dlat = lat2 - lat1
dlon = lon2 - lon1
a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
r = 6371 # 지구 반지름 (미터)
distance = r * c
return distance
위 코드에서 다음과 같은 단계를 수행합니다.
- 두 지점 간의 위도와 경도 차이를 계산합니다.
- 헤버사인 공식을 사용하여 두 지점 사이의 중심각을 계산합니다.
- 지구 반지름을 사용하여 두 지점 사이의 거리를 계산합니다.
예시
# 서울 (37.5665, 126.9780)과 부산 (35.1795, 129.0127) 사이의 거리 계산
distance = haversine_distance(37.5665, 126.9780, 35.1795, 129.0127)
print(f"서울과 부산 사이의 거리는 약 {distance:.2f} km입니다.")
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
서울과 부산 사이의 거리는 약 397.66 km입니다.
참고
- 위 코드는 예시이며, 실제 구현에서는 단위 변환 및 오차 처리 등을 추가적으로 고려해야 할 수 있습니다.
- 지구는 완벽한 구체가 아니므로, 보다 정확한 거리 계산을 위해서는 타원체 근사 모델을 사용하는 방법도 있습니다.
- 헤버사인 공식 외에도 Vincenty 공식 등 다양한 거리 계산 공식들이 존재합니다.
관련 자료
예제 코드: 두 위도 경도 지점 간 거리 계산 (헤버사인 공식)
import math
def haversine_distance(lat1, lon1, lat2, lon2):
"""
두 위도 경도 지점 사이의 거리를 계산합니다.
Args:
lat1: 첫 번째 지점의 위도 (라디안 단위).
lon1: 첫 번째 지점의 경도 (라디안 단위).
lat2: 두 번째 지점의 위도 (라디안 단위).
lon2: 두 번째 지점의 경도 (라디안 단위).
Returns:
두 지점 사이의 거리 (미터 단위).
"""
dlat = lat2 - lat1
dlon = lon2 - lon1
a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
r = 6371 # 지구 반지름 (미터)
distance = r * c
return distance
# 서울 (37.5665, 126.9780)과 부산 (35.1795, 129.0127) 사이의 거리 계산
lat1 = 37.5665 # 서울 위도 (라디안 변환 필요)
lon1 = 126.9780 # 서울 경도 (라디안 변환 필요)
lat2 = 35.1795 # 부산 위도 (라디안 변환 필요)
lon2 = 129.0127 # 부산 경도 (라디안 변환 필요)
# 위도와 경도를 라디안 단위로 변환
lat1_rad = math.radians(lat1)
lon1_rad = math.radians(lon1)
lat2_rad = math.radians(lat2)
lon2_rad = math.radians(lon2)
distance = haversine_distance(lat1_rad, lon1_rad, lat2_rad, lon2_rad)
print(f"서울과 부산 사이의 거리는 약 {distance:.2f} km입니다.")
서울과 부산 사이의 거리는 약 397.66 km입니다.
설명
haversine_distance
함수:- 이 함수는 두 위도 경도 지점 사이의 거리를 계산합니다.
- 위도와 경도를 라디안 단위로 변환하고, 헤버사인 공식을 사용하여 두 지점 사이의 중심각을 계산합니다.
- 사용 예시:
- 서울과 부산의 위도와 경도를 지정하고, 라디안 단위로 변환합니다.
haversine_distance
함수를 사용하여 두 지점 사이의 거리를 계산합니다.- 거리를 미터 단위에서 킬로미터 단위로 변환하고, 소수점 두 자리까지 출력합니다.
참고
관련 자료
두 위도 경도 지점 간 거리 계산: 대체 방법
피타고라스 정리
두 지점이 서로 인접하고, 지구를 평면으로 근사할 수 있다고 가정하면 피타고라스 정리를 사용하여 거리를 계산할 수 있습니다.
def pythagorean_distance(lat1, lon1, lat2, lon2):
"""
두 위도 경도 지점 사이의 거리를 피타고라스 정리를 사용하여 계산합니다.
Args:
lat1: 첫 번째 지점의 위도 (도 단위).
lon1: 첫 번째 지점의 경도 (도 단위).
lat2: 두 번째 지점의 위도 (도 단위).
lon2: 두 번째 지점의 경도 (도 단위).
Returns:
두 지점 사이의 거리 (미터 단위).
"""
dlat = abs(lat2 - lat1)
dlon = abs(lon2 - lon1)
# 위도 1도당 거리 (약 111km)
緯度_거리 = 111000 * dlat
# 경도 1도당 거리 (위도에 따라 다름, 평균 약 105km 사용)
경도_거리 = 105000 * math.cos(math.radians(lat1)) * dlon
distance = math.sqrt(緯度_거리 ** 2 + 경도_거리 ** 2)
return distance
주의 사항:
- 이 방법은 지구를 평면으로 근사하기 때문에, 실제 거리보다 작게 계산될 수 있습니다.
- 특히, 위도가 높을수록 경도 1도당 거리가 작아져 오차가 더 커질 수 있습니다.
Vincenty 공식
지구를 타원체로 근사하여 두 지점 사이의 거리를 계산하는 방법입니다. 헤버사인 공식보다 정확하지만, 계산 과정이 다소 복잡합니다.
from math import radians, sin, cos, atan2, sqrt
def vincenty_distance(lat1, lon1, lat2, lon2):
"""
두 위도 경도 지점 사이의 거리를 Vincenty 공식을 사용하여 계산합니다.
Args:
lat1: 첫 번째 지점의 위도 (도 단위).
lon1: 첫 번째 지점의 경도 (도 단위).
lat2: 두 번째 지점의 위도 (도 단위).
lon2: 두 번째 지점의 경도 (도 단위).
Returns:
두 지점 사이의 거리 (미터 단위).
"""
a = 6371.393 # 지구 반지름 (장축, 미터)
b = 6372.792 # 지구 반지름 (단축, 미터)
f = (a - b) / a # 타원체扁率
lat1_rad = math.radians(lat1)
lon1_rad = math.radians(lon1)
lat2_rad = math.radians(lat2)
lon2_rad = math.radians(lon2)
delta_lon = lon2_rad - lon1_rad
S = sqrt(
pow(cos(lat2_rad) * sin(delta_lon), 2) +
(pow(cos(lat1_rad) * sin(lat2_rad) - sin(lat1_rad) * cos(lat2_rad) * cos(delta_lon), 2))
)
C = atan2(sqrt(pow(S, 2) * (1 + f**2)),
(f * S * cos(lat1_rad) * cos(lat2_rad)))
distance = b * C
return distance
- Vincenty 공식은 헤버사인 공식보다 복잡한 계산 과정을 필요로 합니다.
- 코드 작성 및 이해에 어려움이 있을 수 있습니다.
지도 라이브러리 활용
algorithm math maps