python庫geopy計算多組經(jīng)緯度距離的實現(xiàn)方式
python庫geopy計算多組經(jīng)緯度距離
日常工作中有時會用到需要計算gnss定位模組的定位精確度,需要將被測設備和真值設備進行經(jīng)緯度坐標之間的對比,由于經(jīng)緯度坐標想要計算差值,需要涉及到坐標系的轉換,計算方法比較復雜,geopy庫很好的解決了這個問題,集成了大量的方法,可以做很多地理坐標相關的事情,其中就有計算兩個坐標點之間距離的方法。
下面是我寫的計算一系列坐標點之間的距離的python腳本,可以給大家提供參考。整理出兩個設備輸出的gps的utc時間以及經(jīng)緯度,按照下面格式寫到txt文本中,腳本讀取txt文本,進行整秒的經(jīng)緯度進行比較,輸出某一時間點的定位誤差,單位為m。
locationA.txt
1641541189000 38.018449 119.205511 1641541190000 38.018492 119.205554 1641541191000 38.018551 119.205591 1641541192000 38.018589 119.205625 1641541193000 38.018629 119.205657 1641541194000 38.018660 119.205693
locationB.txt
1641541189000 33.018449 119.205511 1641541190000 33.018492 114.205554 1641541191000 38.018551 116.205591 1641541192000 38.018589 116.205625 1641541193000 38.018629 119.205657 1641541194000 38.018660 119.205693
diff.txt
1641541189000 1.0 1641541190000 2.0 1641541191000 3.0 1641541192000 3.0 1641541193000 4.0 1641541194000 1.0
postion.py
# -*- coding:utf-8 -*- #!/usr/bin/python3 from geopy.distance import distance import time dictpostionA = {} dictpostionB = {} dictdiff = {} #轉換時間戳 dt為字符串 def datetime_timestamp(dt): #中間過程,一般都需要將字符串轉化為時間數(shù)組 time.strptime(dt, '%Y/%m/%d %H:%M:%S') s = time.mktime(time.strptime(dt, '%Y/%m/%d %H:%M:%S')) return int(s) def saveATempData(filename): with open(filename, "w") as f: for time, pos in dictpostionA.items(): data = str(time) + "\t" + pos[0] + "\t" + pos[1] + "\n" #print(data) f.write(data) #讀取excel數(shù)據(jù)轉成txt def readAData(filename): with open(filename, "r") as f: for line in f.readlines(): line = line.strip('\n') #print(line) poslist = line.split() #print(poslist[0]) #print(poslist[1]) #print(poslist[2]) #print(poslist[3]) #print(poslist[4]) #print(poslist[5]) dt = poslist[0]+' '+poslist[1]+':'+poslist[2]+':'+poslist[3] #print(dt) index = datetime_timestamp(dt) * 1000 #print(index) sublist = poslist[4:6] #print(sublist) dictpostionA[index] = tuple(sublist) def readBData(filename): with open(filename, "r") as f: for line in f.readlines(): line = line.strip('\n') #print(line) poslist = line.split() #print(poslist[0]) #print(poslist[1]) #print(poslist[2]) sublist = poslist[1:3] #print(sublist) index = int(poslist[0]) dictpostionB[index] = tuple(sublist) def processData(): for timeA, posA in dictpostionA.items(): for timeB, posB in dictpostionB.items(): #print(timeA, timeB) if timeA == timeB: d = distance(posA, posB).m # m是單位 print(timeA, d) dictdiff[timeA] = d continue def saveDiffData(filename): with open(filename, "w") as f: for time, diff in dictdiff.items(): data = str(time) + "\t" + str(diff) + "\n" #print(data) f.write(data) #讀取數(shù)據(jù) readAData("locationA.txt") saveATempData("locationA_temp.txt") readBData("locationB.txt") #處理數(shù)據(jù) processData() #保存數(shù)據(jù) saveDiffData("diff.txt")
python庫Geopy用法,經(jīng)緯度坐標轉換、經(jīng)緯度距離計算
Geopy庫介紹
這里介紹一個Python 包 Geopy ,借助它也可以實現(xiàn)經(jīng)緯度地理位置轉換,
這款包之經(jīng)緯度轉換原理其實還是借助了第三方 API 平臺,因為市面上提供經(jīng)緯度轉換 第三方平臺很多,為了方便, Geopy 把這些接口都分別封裝在一個類中,借助 Geopy 模塊來調(diào)用,支持的第三放平臺如下
Geopy作為一個專注于地理處理包之外, 除了能實現(xiàn)上面地理編碼、逆地理編碼功能之外,還有一個其它令我經(jīng)驗的功能, 提供兩個經(jīng)緯度坐標,計算他們在地球上的最短距離
下面將介紹一下 Geopy 的具體用法,
地理編碼
使用 地理編碼功能時,需要借助 Geopy 的 geocoders 模塊,Geopy 把所有第三方API封裝到 geocoders 中
這里選用 OpenStreetMap 平臺上提供的 Nominatim 地理編碼器,因為可以免費供我們使用,不需要申請 API ,但缺點是限流,限額,不能大規(guī)模頻繁訪問,否則會返回 403,429錯誤代碼
from geopy.geocoders import Nominatim geolocator=Nominatim() location= geolocator.geocode("北京市海淀區(qū)西二旗北路") print(location.address) print(location.latitude,location.longitude)
結果如下
西二旗北路, 東北旺村, 海淀區(qū), 北京市, 102208, 中國
40.056793 116.305811
逆地理編碼
from geopy.geocoders import Nominatim geolocator=Nominatim() location= geolocator.reverse("40.056793 116.305811") print(location.address)
結果如下
1#, 西二旗北路, 東北旺村, 海淀區(qū), 北京市, 102208, 中國
結果看起來還不錯,簡單方便;但提醒一下,因為前面說過 Nominatim 模塊是限額度的,不要頻繁訪問,否則會出現(xiàn)以下錯誤
根據(jù)經(jīng)緯度計算距離
Geopy 最讓我驚喜的是這個用法,提供兩個經(jīng)緯度坐標計算他們之間的距離,因為地球具體來說是橢圓,所以不能按照常規(guī)方法來計算 ,目前現(xiàn)有比較流行的幾個模型有以下幾個
model major (km) minor (km) flattening ELLIPSOIDS = {'WGS-84': (6378.137, 6356.7523142, 1 / 298.257223563), 'GRS-80': (6378.137, 6356.7523141, 1 / 298.257222101), 'Airy (1830)': (6377.563396, 6356.256909, 1 / 299.3249646), 'Intl 1924': (6378.388, 6356.911946, 1 / 297.0), 'Clarke (1880)': (6378.249145, 6356.51486955, 1 / 293.465), 'GRS-67': (6378.1600, 6356.774719, 1 / 298.25), }
根據(jù)官方介紹,官網(wǎng)選擇的是 WGS-84 模型,根據(jù)統(tǒng)計最終計算到的距離誤差最高在0.5%左右;使用方法如下
from geopy import distance newport_ri = (41.49008, -71.312796) cleveland_oh = (41.499498, -81.695391) print(distance.distance(newport_ri, cleveland_oh).miles)#最后以英里單位輸出 #output 538.39044536 wellington = (-41.32, 174.81) salamanca = (40.96, -5.50) print(distance.distance(wellington, salamanca).km)# 以 km 作為單位輸出 19959.6792674
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
如何用Python數(shù)據(jù)可視化來分析用戶留存率
今天和大家來分享一些數(shù)據(jù)可視化方向的干貨,我們來嘗試用Python來繪制一下“漏斗圖”,感興趣的小伙伴和小編一起進入課題吧,但愿大家會有所收獲2021-09-09