두 지점 A, B의 위도와 경도가 주어졌을 때에는 haversine을 이용해서 거리를 계산할 수 있다.
haversine의 개념에 대해서는 아래 링크에 정리하였다.
https://jost-do-it.tistory.com/16
이번에는 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/
'Programming > Python' 카테고리의 다른 글
[Python] upsert문 간접 구현하기 (0) | 2024.02.05 |
---|---|
[Python] json 출력 포맷 설정하기 (0) | 2023.12.19 |
[Python] pip freeze 시, 버전명이 '@ file:///' 로 뜨는 문제 (0) | 2023.06.16 |
[Python] Ray 라이브러리를 이용한 코드 병렬 처리와 이에 대한 고찰 (0) | 2022.09.30 |
[Python] functools의 partial 함수 알아보기 (2) | 2022.09.25 |