두 위도 경도 지점 간 거리 계산 (헤버사인 공식)

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

위 코드에서 다음과 같은 단계를 수행합니다.

  1. 두 지점 간의 위도와 경도 차이를 계산합니다.
  2. 헤버사인 공식을 사용하여 두 지점 사이의 중심각을 계산합니다.
  3. 지구 반지름을 사용하여 두 지점 사이의 거리를 계산합니다.

예시

# 서울 (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입니다.

설명

  1. haversine_distance 함수:
    • 이 함수는 두 위도 경도 지점 사이의 거리를 계산합니다.
    • 위도와 경도를 라디안 단위로 변환하고, 헤버사인 공식을 사용하여 두 지점 사이의 중심각을 계산합니다.
  2. 사용 예시:
    • 서울과 부산의 위도와 경도를 지정하고, 라디안 단위로 변환합니다.
    • 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

algorithm math maps

알고리즘, 최적화, 복잡성 이론과 관련된 Big O 계산 및 근사

Big O 계산 방법:알고리즘 분석: 알고리즘을 단계별로 분석하고 각 단계에서 수행되는 작업 수를 계산합니다.주요 연산 식별: 가장 지배적인 연산을 식별하고 해당 연산의 반복 횟수를 계산합니다.최악의 경우 입력 고려: 입력 크기가 커질 때 연산 횟수가 어떻게 변하는지 고려합니다