程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python 優雅地利用兩點經緯度計算地理空間距離

編輯:Python

主要內容概覽:

 

一、根據經緯度計算距離的基本原理

處理地理數據時,經常需要用到兩個地理位置間的距離。以點(經度值,緯度值)表示地點的經緯度坐標,比如 A 點經緯度(30.553949,114.357399),B點經緯度(129.1344,25.5465),求 AB 兩點之間的距離。

已知地球上任意兩點(lng1,lat1),(lng2, lat2)的經緯度坐標,求兩點間的距離可以利用 haversine 公式:

  • 首先,將經緯度坐標的角度化成弧度(rlng1,rlat1),(rlng2,rlat2)
  • 然後,利用如下公式計算:

其中, a 表示兩點緯度的差值,即 a = rlat1 - rlat2; b表示兩點經度的差值,即 b = rlng1 - rlng2,其中 r 表示地球的半徑。

以計算清華大學與北京大學距離為例,利用百度地圖( 網址:百度地圖)測距可知,清華大學與北京大學距離大約為1.8km,如下所示:

二、獲取地點的經緯度

利用高德地圖地理編碼 / 逆地理編碼 API ,來獲取北京大學和清華大學的經緯度,Python代碼實現如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
KEY = '你的高德地圖應用訪問碼'
def geocode(address):
"""
根據地名,獲取經緯度
"""
parameters = {'address': address, 'key': KEY}
base = 'http://restapi.amap.com/v3/geocode/geo'
response = requests.get(base, parameters)
answer = response.json()
# print(answer)
# print(type(answer))
print(address + "的經緯度:", answer['geocodes'][0]['location'])
if __name__ == "__main__":
address1 = '北京大學'
lon_lat1 = geocode(address1)
address2 = '清華大學'
lon_lat2 = geocode(address2)

 其中,KEY為你自己申請的高德地圖應用授權訪問碼。只需輸入地址參數,就可以打印出對應地址的經緯度坐標值。

運行結果為:

北京大學的經緯度: 116.308264,39.995304
清華大學的經緯度: 116.326759,40.003304

三、手寫 haversine 公式計算

根據 haversine 公式,自定義實現python版本計算公式,如下:

from math import sin, asin, cos, radians, fabs, sqrt
EARTH_RADIUS = 6371.137 # 地球平均半徑大約6371km
def hav(theta):
s = sin(theta / 2)
return s * s
def get_distance_hav(lat0, lng0, lat1, lng1):
# 用haversine公式計算球面兩點間的距離
# 經緯度轉換成弧度
lat0 = radians(lat0)
lat1 = radians(lat1)
lng0 = radians(lng0)
lng1 = radians(lng1)
dlng = fabs(lng0 - lng1)
dlat = fabs(lat0 - lat1)
h = hav(dlat) + cos(lat0) * cos(lat1) * hav(dlng)
distance = 2 * EARTH_RADIUS * asin(sqrt(h)) # km
return distance
if __name__ == "__main__":
result = get_distance_hav(39.995304, 116.308264, 40.003304, 116.326759)
print("距離:{:.3}km".format(result))

運行結果為:

距離:1.809km

四、利用 geopy 庫計算

geopy是一個關於地理編碼的 Python 庫。主要有以下幾個功能:

  • 地理編碼:將字符串轉換為地理位置。
  • 逆地理編碼:用於將地理坐標轉換為具體地址。
  • 計算兩個點的距離:經緯度距離和球面距離。

pip install安裝geopy庫,命令為:

pip install geopy -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

Python實現代碼如下所示:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from geopy.distance import geodesic
if __name__ == "__main__":
distance = geodesic((39.995304, 116.308264), (40.003304, 116.326759)).km
print("距離:{:.3f}km".format(distance))

運行結果如下所示:

距離:1.812km

手寫 haversine 公式計算距離為:1.809km,而直接調用 geopy 庫的 geodesic 方法計算距離為:1.812km,二者計算結果相差很小。 

更多有關 geopy 的使用,可以學習官方文檔:歡迎使用Geopy文檔! — GeoPy 2.2.0 文檔。

五、利用 haversine庫 計算

pypi地址:haversine · PyPI

Calculate the distance (in various units) between two points on Earth using their latitude and longitude.

用經緯度計算地球上兩點之間的距離(以不同單位表示),pip install安裝即可,命令為:

pip install haversine -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

Python實現代碼如下:

from haversine import haversine, Unit
if __name__ == "__main__":
# 兩點的經緯度
point1 = (39.995304, 116.308264)
point2 = (40.003304, 116.326759)
result1 = haversine(point1, point2, unit=Unit.KILOMETERS) # km
result2 = haversine(point1, point2, unit=Unit.METERS) # m
# 打印計算結果
print("距離:{:.3f}km".format(result1))
print("距離:{:.3f}m".format(result2))

運行結果為:

距離:1.809km
距離:1809.223m

可以發現,利用 haversine 庫計算距離的結果與手寫 haversine 公式計算的結果一致。


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved