파이썬으로 GPS 두 위경도 좌표간 거리 구하기
파이썬으로 GPS 두 위경도 좌표 간 거리 구하기
안녕하세요.
어느 두 지점간의 거리를 계산을 해야 할 때가 있습니다.
두 지점간을 직선거리로 이었을 때의 그 거리가 얼마나 나오는지, 확인이 필요할 때 유용하게 쓸 수 있습니다.
아래 지도를 보시면 카카오맵을 통해서 두 지점 간의 직선거리를 잰 것입니다.
※서론
우리가 두 지점 간의 직선거리를 잴 때 아래 공식을 이용하죠.
두 좌표 (x1, y1), (x2, y2)가 있을 때 두 지점 사이의 거리는 x좌표의 차이의 제곱과 y좌표의 차이의 제곱의 합에 대한 제곱근으로 구합니다.
하지만, 위에서 언급한 피타고라스의 정리는 평평한 곳에서의 거리를 구할 때 쓰이는 것이고, 우리가 살고 있는 이 지구 위에서 두 지점 간의 거리를 알고 싶다면 두 지점의 위도(Latitude)와 경도(Longitude) 값을 알아야 하고, 이 값을 동그란 큰 구위에서 구해야 합니다.
지구는 둥그닌깐요. 아래 그림을 한번 보실까요?
두 지점을 이은 각각의 두 개의 빨간 선이 있습니다. 사진상으로는 아래의 빨간 직선이 더 가까운 경로라고 생각이 되지만, 사실 실제 지구 위에서 위에 있는 빨간 곡선이 더 최단 거리를 나타내고 있습니다.
3차원 공간상의 최단거리는 직선이 아닌 호의 모습을 띄고 있기 때문이죠.
※하버 사인 공식
그래서 이 구모 양인 지구 위에서의 최단 거리를 구하기 위해서는 Haversine Formula를 써야 합니다.
하버 사인 공식(Haversine Formula)에 대한 설명은 아래와 같습니다.
여기에서 마지막에 있는 공식을 이용하면 위경도로 이루어진 두 지점 간의 거리를 구할 수 있습니다.
그럼 이 하버 사인 공식(Haversine Formula)을 사용하여 파이썬 코드로 두 개의 위경도 사이의 거리를 구하는 소스를 시연해 보겠습니다.
※필요 라이브러리 import
import pymysql
import pandas
from haversine import haversine
DB에서 각 주소 값의 위경도 값을 읽어와야 하기에 pymysql과 데이터 처리를 위해서 pandas를 import 했습니다.
그리고 두 위경도 사이의 거리를 계산해줄 haversine을 import 합니다.
※DB 연결
# db connect
conn = pymysql.connect(host='localhost',
user = 'DB계정', password='DB계정비밀번호', db = '스키마명',charset = 'utf8')
curs = conn.cursor(pymysql.cursors.DictCursor)
위와 같이 DB와 connect를 합니다.
※DB에서 출발지의 GPS 위경도 좌표를 읽어오기
s_sql = "select inf_full_road_addr_build, inf_latitude, inf_longtitude from address_svc_m.juso_info_m where inf_full_road_addr_build = '서울특별시 종로구 세종대로 209, (세종로)'"
curs.execute(s_sql)
s_val = curs.fetchall()
s_df = pandas.DataFrame(s_val, columns = ["inf_full_road_addr_build","inf_latitude","inf_longtitude"])
s_inf_full_road_addr_build = s_df.inf_full_road_addr_build[0]
s_inf_latitude = s_df.inf_latitude[0]
s_inf_longtitude = s_df.inf_longtitude[0]
일전에 블로그에서 공유했던 주소 DB에서 "정부서울청사"의 주소를 select 해 옵니다.
# 주소DB 구축 포스팅 #
2020/01/17 - [DB 엔지니어가 공부하는 python] - 파이썬_주소 DB 공공데이터포털 에서 주소DB 다운로드하여 DB에 insert 하기 #1
※DB에서 도착지의 GPS 위경도 좌표를 읽어오기
g_sql = "select inf_full_road_addr_build, inf_latitude, inf_longtitude from address_svc_m.juso_info_m where inf_full_road_addr_build = '세종특별자치시 다솜2로 94, (어진동)'"
curs.execute(g_sql)
g_val = curs.fetchall()
g_df = pandas.DataFrame(g_val, columns = ["inf_full_road_addr_build","inf_latitude","inf_longtitude"])
g_inf_full_road_addr_build = g_df.inf_full_road_addr_build[0]
g_inf_latitude = g_df.inf_latitude[0]
g_inf_longtitude = g_df.inf_longtitude[0]
도착지는 "세종 정부종합청사"의 주소를 불러왔습니다.
출발지와 도착지에서 각 주소와 위도, 경도 값을 select 해서 각각의 변수에 저장을 했습니다.
※출발지, 도착지 두 곳의 위경도 값을 start와 goal 변수에 저장하기
start = (float(s_inf_latitude), float(s_inf_longtitude)) # (lat, lon)
goal = (float(g_inf_latitude), float(g_inf_longtitude))
위와 같이 출발지, 도착지 두 곳의 위경도 값을 start와 goal 변수에 저장합니다. 순서는 위도, 경도 순서입니다.
※두 지점 거리 계산하기 (킬로미터)
haversine(start, goal)
위와 같이 파이썬 코드를 실행하면 아래와 같이 결과가 나옵니다.
121.7 km 정도의 거리로 측정이 되었습니다.
그럼 실제 지도에서 거리를 측정한 것과 비교해 보겠습니다.
아래 결과는 구글맵을 이용한 결과입니다.
121.6km 정도라고 나왔습니다.
클릭 미스?? 를 감안하면 동일한 결과로 볼 수 있겠습니다.
킬로미터가 아닌 마일로도 결과를 받아볼 수 있습니다.
haversine(start, goal, unit='mi')
unit 옵션을 'mi'로 두고 파이썬 코드를 실행하면 됩니다.
이렇게 간단하게 두 지점 간의 거리를 구해올 수 있습니다.
최종적으로는 아래와 같이 표현할 수 있겠네요.
"<"+s_inf_full_road_addr_build+"> 와 <"+g_inf_full_road_addr_build+"> 간의 거리는 "+str(haversine(start, goal))+"km 입니다."
지금까지 두 GPS 거리 간의 직선거리를 파이썬으로 구현하는 방법이었습니다.
문의사항은 댓글로 부탁드립니다.
감사합니다.
by.sTricky