Jost Do It.

그냥 IT해.

Programming/Python

[Python] 하버사인 (haversine)으로 위경도가 주어진 두 지점 거리 구하기

그냥하Jo. 2022. 10. 12. 07:26
반응형

두 지점 A, B의 위도와 경도가 주어졌을 때에는 haversine을 이용해서 거리를 계산할 수 있다.

 

haversine의 개념에 대해서는 아래 링크에 정리하였다.

 

 

https://jost-do-it.tistory.com/16

 

[haversine] 두 지점의 위도, 경도를 이용해서 거리 구하기

두 지점의 좌표 (x1, y1)과 (x2, y2)가 주어질 때 보통 피타고라스의 정리를 이용해서 거리를 구할 수 있다. 하지만 지구는 타원체이기 때문에 두 지점의 위경도가 주어진 경우 거리를 간단하게 구할

jost-do-it.tistory.com

 

 

 

 

이번에는 python의 haversine package를 이용해서 실제로 위경도가 주어진 지점들의 거리를 계산해보자.

 

 

 

 

 

haversine package install

파이썬에서는 haversine 패키지를 이용하여 두 지점의 위경도가 주어졌을 때 거리를 구할 수 있다.

 

haversine 패키지에 대한 공식 다큐먼트는 다음과 같다.

 

 

 

먼저 haversine package를 사용하기 위해 아래 명령어로 Install을 해준다.

 

# In Shell
pip install haversine

 

 

 

 

 

두 지점의 위경도로 거리 구하기

그러면 haversine 패키지를 이용해서 거리를 계산해보자.

 

예시로 서울 부산의 위경도를 이용하였다.

 

import haversine

seoul = (37.5642135, 127.0016985) # (latitude, longitude)
busan = (35.1379222, 129.05562775)

haversine.haversine(seoul, busan)
>> 326.50873185051285  # unit: km

 

사용 규칙은 다음과 같다.

  • 위도와 경도의 값을 넣을 때, (위도, 경도) 순으로 들어가야 한다.
    • 위도의 범위 [-90, 90]과 경도의 범위 [-180, 180]을 넘어선 값이 입력되면 에러가 발생한다.

 

  • 거리를 계산할 때는 haversine 패키지의 haversine 함수(haversine.haversine)을 사용한다.
    • 여기서 출력되는 결과물의 디폴트 단위는 km다.

 

 


 

 

한편 출력되는 단위를 아래와 같이 변경할 수도 있다.

from haversine import haversine, Unit

haversine(seoul, busan, unit = 'km') 
>> 326.50873185051285


haversine(seoul, busan, unit = 'm')
>> 326508.73185051285



haversine(seoul, busan, unit = 'mi')
>> 202.88311990836152



haversine(seoul, busan, unit = Unit.NAUTICAL_MILES)
>> 176.3006110015872

 

여기서 자주 사용되는 거리 척도 string값을 전달할 수 있다.

 

이외의 다른 척도를 사용하기 위해서는 haversine.Unit을 이용할 수 있다.

 

 


 

haversine.Unit은 아래의 척도들을 지원한다.

 

tuple(Unit)

>> (<Unit.KILOMETERS: 'km'>,
 <Unit.METERS: 'm'>,
 <Unit.MILES: 'mi'>,
 <Unit.NAUTICAL_MILES: 'nmi'>,
 <Unit.FEET: 'ft'>,
 <Unit.INCHES: 'in'>,
 <Unit.RADIANS: 'rad'>,
 <Unit.DEGREES: 'deg'>)

 

 

 

 

 

여러 지점의 위경도로 각각 거리 구하기

위에서 haversine function으로 두 지점간의 위경도로 거리를 구할 수 있었다.

 

 

 

한편 여러 지점들이 있을 때 이 지점들간 거리를 출력하는 함수도 있다.

 

haversine_vector 함수를 이용하면 된다.

  • haversine_vector: 지점들의 좌표를 포함하는 두 어레이가 있을 때, 어레이 간 좌표들 사이의 모든 거리 조합을 matrix 형태로 출력한다.

 

 

 

아래 예를 통해서 더 쉽게 알아보자.

 

예시 코드를 통해서 대한민국 도시(서울, 부산)과 여러 해외 도시간 거리를 구할 수 있다.

 

from haversine import haversine_vector

# Cities of Korea
seoul = (37.5642135, 127.0016985) # (latitude, longitude)
busan = (35.1379222, 129.05562775)


# Cities of global countries
lyon = (45.7597, 4.8422) # (lat, lon)
london = (51.509865, -0.118092)
paris = (48.8567, 2.3508)
new_york = (40.7033962, -74.2351462)



haversine_vector([seoul, busan], [lyon, london, paris, new_york], comb=True, unit = 'km')
>> array([[ 9097.20358827,  9423.56365695],
       [ 8857.99677288,  9183.46069182],
       [ 8967.16361805,  9293.5408089 ],
       [11047.67049246, 11251.99657621]])

 

  • 여기서 두 리스트(어레이)의 지점간 거리를 matrix로 출력하려면 comb=True 옵션을 설정해야 한다.

 

결과를 보면 4 X 2 형태의 어레이가 출력된다.

 

이는 아래와 같이 해석할 수 있다.

 

  Seoul Busan
Lyon Seoul <-> Lyon Busan <-> Lyon
London Seoul <-> London Busan <-> London
Paris Seoul <-> Paris Busan <-> Paris
New York Seoul <-> New York Busan <-> New York

 

  • 즉, 두 리스트에 있는 지점들 간 거리 조합(combination)을 matrix 형태로 출력하게 된다.
  • 여러 지점들 간의 각 거리를 구해야 할 때 유용하게 사용할 수 있는 함수이다.

 

 


 

이를 다음과 같이 일반화 할 수 있다.

  • a: n개의 지점을 포함한 어레이
  • b: m개의 지점을 포함한 어레이
  • M = haversine_vector(a, b, comb = True)라고 하면,
    • M: m * n의 크기를 가지는 어레이
    • M[k, j]: b 어레이의 k번째 지점과 a 어레이의 j번째 지점간 거리

 

 

 

 

역하버사인 함수를 이용해서 특정 지점에서 떨어진 곳의 위경도 구하기

 

한편 haversine 패키지는 역 하버사인(inverse haversine) 함수도 지원한다.

 

역 하버사인은 어느 지점의 위경도와 떨어진 거리가 주어졌을 때, 이 위경도에서 특정 방향으로 떨어진 거리의 위경도를 계산하는 함수이다.

 

위에서 사용한 서울 위경도를 이용해 예시를 들어보자.

 

from haversine import inverse_haversine, Direction
from math import pi

seoul = (37.5642135, 127.0016985) # (latitude, longitude)


# 서울로부터 32km 서쪽으로 떨어진 지점의 위경도 구하기
inverse_haversine(seoul, 32, Direction.WEST) # unit을 지정하지 않을 시, km가 디폴트
>> (37.56365764486571, 126.63864593835525)




# 서울로부터 50마일 북쪽으로 떨어진 지점의 위경도 구하기
inverse_haversine(seoul, 50, Direction.NORTH, unit=Unit.MILES)
>> (38.287871415995355, 127.0016985)

 

  • 시작 지점(서울)으로 부터 특정 방향과 거리로 떨어진 지점의 위경도를 구할 수 있다.
  • 지점에서 특정 방향으로 떨어진 곳의 위경도를 구할 때 유용하게 사용할 수 있는 함수이다.

 


 

한편 방향은 아래와 같이 북, 북동, 동, 남동, 남, 남서, 서, 북서를 지원한다.

tuple(Direction)

>> (<Direction.NORTH: 0>,
 <Direction.NORTHEAST: 0.7853981633974483>,
 <Direction.EAST: 1.5707963267948966>,
 <Direction.SOUTHEAST: 2.356194490192345>,
 <Direction.SOUTH: 3.141592653589793>,
 <Direction.SOUTHWEST: 3.9269908169872414>,
 <Direction.WEST: 4.71238898038469>,
 <Direction.NORTHWEST: 5.497787143782138>)
  • 방향: 라디안으로 표현된 각도 가 나타난다.
  • 출력 결과를 통해 알 수 있듯이, 북쪽이 디폴트(0)이다. 따라서 pi 각도만큼 회전하면 남쪽이다.
  • 라디안 각도는 시계방향으로 계산된다.

 

 


 

또한 아래와 같이 라디안으로 표현된 각도를 명시적으로 입력할 수도 있다.

# 서울 지점에서 15km 남쪽으로 떨어진 곳의 위경도
inverse_haversine(seoul, 15, pi, unit="km")
>> (37.42931544544132, 127.0016985)



# 서울 지점에서 30km 북쪽으로 떨어진 곳의 위경도
inverse_haversine(seoul, 30, 0, unit="km")
>> (37.834009609117366, 127.0016985)




# 서울 지점에서 45km 동쪽으로 떨어진 곳의 위경도
inverse_haversine(seoul, 45, pi/2, unit="km")
>> (37.563724955103304, 127.34206048155971)

 

 

 

참조

https://pypi.org/project/haversine/

 

 

 

반응형