介紹
眾所周知地球是一個球體,地平面是一個弧形,那么兩個地理位置之間的中點該如何確定,比如北京與上海兩個城市之間的中點在哪里?
可以直接對經緯度進行平均,求中點嗎?答案:當然不可以
我們都知道一個地理位置是由經度、維度來確定,平時在計算地理信息時基本都是兩列數據,一列是經度,一列是維度,比如:
北京:"lon":116.512885,"lat":39.847469,
上海:"lon":116.332334,"lat":39.882806
- lon:longitude 經度
經度是指通過某地的經線面與本初子午面所成的二面角。
在本初子午線以東的經度叫東經,在本初子午線以西的叫西經。
東經用“E”表示,西經用“W”表示。- lat:latitude 維度
赤道的緯度為0°,將行星平分為南半球和北半球。
緯度是指某點與地球球心的連線和地球赤道面所成的線面角,其數值在0至90度之間。
位于赤道以北的點的緯度叫北緯,記為N,位于赤道以南的點的緯度稱南緯,記為S。
概念-----計算原理
那么應該怎么計算呢?
我們可以把地球看做是一個立體坐標系,有x
軸,y
軸,z
軸三個方向,對于球面上的一個點,可以分別計算出在x
軸,y
軸,z
軸的投影,那么在三個軸上面的分量是可以直接求均值,最后再進行反向合成,這樣即可求出球面上對應的中點。
下圖手工畫出了,在x
軸,y
軸,z
軸如何進行投影(可進行參考):
球面點進行分解
根據手繪圖可以計算出,各個分量:
x = cos(lat) * sin(lon)
y = cos(lat) * cos(lon)
z = sin(lat)
角度和弧度相互轉換
由于我們實際數據中的經緯度是角度,而我們在計算分量時需要用弧度,比如cos(π/2)
,這里就先需要轉換,那么怎么進行轉換:
python的math模塊里面有相應轉換函數
radians()-----將角度轉換為弧度
degrees()-----將弧度轉換為角度
腦補一下角度與弧度:
度和弧度都是衡量角的大小的單位,就像米(m)和英寸(in)都是用來衡量長度的單位。度用°來表示,弧度用rad表示。
1rad = (180/π)° ≈ 57.3°
1° = (π/180)rad ≈ 0.01745rad
弧度的定義
在一個圓中,弧長等于半徑的弧,其所對的圓心角就是 1rad。也就是說,兩條射線從圓心向圓周射出,形成一個夾角和夾角正對的一段弧。當這段弧的長度正好等于圓的半徑時,兩條射線的夾角的弧度為 1。
弧度
根據定義,圓一周的弧度數為 2πr/r = 2π,360° = 2πrad,平角(即 180° 角)為 πrad,直角為 π/2rad
角度與弧度
在具體計算中,角度以弧度給出時,通常不寫弧度單位,直接寫值。最典型的例子是三角函數,例如sin(8π)、tan(3π/2)
自定義函數
import pandas as pd
import numpy as np
from math import cos, sin, atan2, sqrt, radians, degrees
data=pd.read_excel('./data.xlsx')
def center_geolocation(df):
"""
輸入多個經緯度坐標,找出中心點 [lon,lat]->[經度,維度]
:param geolocations: 列表
:return 中心經緯度
"""
x = 0
y = 0
z = 0
lenth = len(df)
for lon, lat in zip(df['lon'].to_list(),df['lat'].to_list()):
lon = radians(float(lon)) #radians將角度轉換為弧度
lat = radians(float(lat))
x += cos(lat) * sin(lon)
y += cos(lat) * cos(lon)
z += sin(lat)
x = float(x / lenth)
y = float(y / lenth)
z = float(z / lenth)
#degrees將弧度轉換為角度
lon=degrees(atan2(x, y))
lat=degrees(atan2(z, sqrt(x * x + y * y)))
return pd.DataFrame({'lon':[lon],'lat':[lat]})
#使用
result_data=data.groupby('ID').apply(center_geolocation)
result_data.index=result_data.index.droplevel(level=1)
result_data.to_excel('./result_data.xlsx')