如何计算python中几个地理定位的中点

时间:2016-06-17 15:58:04

标签: python geolocation centering ip-geolocation

是否有图书馆或计算几个地理位置点中心点的方法? 这是我在纽约的地理定位列表,希望找到近似的中点地理定位

L = [
     (-74.2813611,40.8752222),
     (-73.4134167,40.7287778),
     (-74.3145014,40.9475244),
     (-74.2445833,40.6174444),
     (-74.4148889,40.7993333),
     (-73.7789256,40.6397511)
    ]

5 个答案:

答案 0 :(得分:3)

我收到comments之后https://jsfiddle.net/cb8ctkfo/3/

发表评论

使用close to each other的坐标,您可以将地球视为局部平坦,并简单地找到质心,就像它们是平面坐标一样。然后,您只需取纬度的平均值和经度的average即可找到latitude的{​​{1}}和longitude

centroid

答案 1 :(得分:2)

基于:https://gist.github.com/tlhunter/0ea604b77775b3e7d7d25ea0f70a23eb

假设您有一个带有经度和纬度列的pandas DataFrame,下一个代码将返回一个带有平均坐标的字典。

import math

x = 0.0
y = 0.0
z = 0.0

for i, coord in coords_df.iterrows():
    latitude = math.radians(coord.latitude)
    longitude = math.radians(coord.longitude)

    x += math.cos(latitude) * math.cos(longitude)
    y += math.cos(latitude) * math.sin(longitude)
    z += math.sin(latitude)

total = len(coords_df)

x = x / total
y = y / total
z = z / total

central_longitude = math.atan2(y, x)
central_square_root = math.sqrt(x * x + y * y)
central_latitude = math.atan2(z, central_square_root)

mean_location = {
    'latitude': math.degrees(central_latitude),
    'longitude': math.degrees(central_longitude)
    }

答案 2 :(得分:2)

这个 link 很有用,首先将纬度/经度转换为 n 向量,然后求平均值。第一次尝试将代码转换为 Python 在下面

import numpy as np
import numpy.linalg as lin

E = np.array([[0, 0, 1],
              [0, 1, 0],
              [-1, 0, 0]])

def lat_long2n_E(latitude,longitude):
    res = [np.sin(np.deg2rad(latitude)),
           np.sin(np.deg2rad(longitude)) * np.cos(np.deg2rad(latitude)),
           -np.cos(np.deg2rad(longitude)) * np.cos(np.deg2rad(latitude))]
    return np.dot(E.T,np.array(res))

def n_E2lat_long(n_E):
    n_E = np.dot(E, n_E)
    longitude=np.arctan2(n_E[1],-n_E[2]);
    equatorial_component = np.sqrt(n_E[1]**2 + n_E[2]**2 );
    latitude=np.arctan2(n_E[0],equatorial_component);
    return np.rad2deg(latitude), np.rad2deg(longitude)

def average(coords):
    res = []
    for lat,lon in coords:
        res.append(lat_long2n_E(lat,lon))
    res = np.array(res)
    m = np.mean(res,axis=0)
    m = m / lin.norm(m)
    return n_E2lat_long(m)
        

n = lat_long2n_E(30,20)
print (n)
print (n_E2lat_long(np.array(n)))

# find middle of france and libya
coords = [[30,20],[47,3]]
m = average(coords)
print (m)

enter image description here

答案 3 :(得分:1)

考虑到您使用的是符号度数格式(more),由于经度的不连续性,对纬度和经度进行简单的平均运算甚至会对靠近子午线的小区域(即+或-180度经度)造成问题。此行的值(突然在-180到180之间跳转)。

考虑两个经度分别为-179和179的位置,它们的均值为0,这是错误的。

答案 4 :(得分:0)

我想改进@BBSysDyn 的回答。 如果您正在计算一侧具有额外顶点的多边形的中心,则平均计算可能会有偏差。因此 average 函数可以替换为质心计算解释 here

def get_centroid(points):

    x = points[:,0]
    y = points[:,1]
    
    # Solving for polygon signed area
    A = 0
    for i, value in enumerate(x):
        if i + 1 == len(x):
            A += (x[i]*y[0] - x[0]*y[i])
        else:
            A += (x[i]*y[i+1] - x[i+1]*y[i])
    A = A/2

    #solving x of centroid
    Cx = 0
    for i, value in enumerate(x):
        if i + 1 == len(x):
            Cx += (x[i]+x[0]) * ( (x[i]*y[0]) - (x[0]*y[i]) )
        else:
            Cx += (x[i]+x[i+1]) * ( (x[i]*y[i+1]) - (x[i+1]*y[i]) )
    Cx = Cx/(6*A)

    #solving y of centroid
    Cy = 0
    for i , value in enumerate(y):
        if i+1 == len(x):
            Cy += (y[i]+y[0]) * ( (x[i]*y[0]) - (x[0]*y[i]) )
        else:
            Cy += (y[i]+y[i+1]) * ( (x[i]*y[i+1]) - (x[i+1]*y[i]) )
    Cy = Cy/(6*A)

    return Cx, Cy

注意:如果是多边形或超过 2 个点,则必须列出它们,以便绘制多边形或形状。