在计算地球上两点之间的距离时,为什么我的Haversine与Geodesic计算有差异? [英] When calcuating distance between points on earth why are my Haversine vs. Geodesic calculations diverging?

查看:137
本文介绍了在计算地球上两点之间的距离时,为什么我的Haversine与Geodesic计算有差异?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用两个近似值来计算地球表面上的点之间的距离,我的距离变得越来越大.我正在使用 Haversine ( >向量化)近似和(可能更精确) geopy.distance.geodesic .

I am getting wildly diverging distances using two approximations to calculate distance between points on Earth's surface. I am using the Haversine (vectorized) approximation and the more precise (presumably) geopy.distance.geodesic .

如您所见,随着点之间的距离变大,我的工作量减少了5%.这种差异是由于Haversine中的舍入误差引起的吗?我确实相信测地线吗?这是代码:

As you can see I am off by five percent as the distances between points becomes large. Is this divergence due to rounding error in Haversine? Do I indeed trust the Geodesic? Here is code:

import numpy as np
lat = np.linspace(35,45,100)
lon = np.linspace(-120,-110,100)

data = pd.DataFrame({'Latitude':lat,'Longitude':lon})




def Haversine(v):
    """
    distance between two lat,lon coordinates 
    using the Haversine formula. Assumes one
    radius. r = 3,950 to 3,963 mi 
    """
    from timeit import default_timer as timer
    start = timer()
    R = 3958 # radius at 40 deg 750 m elev
    v = np.radians(v)

    dlat = v[:, 0, np.newaxis] - v[:, 0]
    dlon = v[:, 1, np.newaxis] - v[:, 1]
    c = np.cos(v[:,0,None])

    a = np.sin(dlat / 2.0) ** 2 + c * c.T * np.sin(dlon / 2.0) ** 2

    c = 2 * np.arcsin(np.sqrt(a))
    result = R * c
    print(round((timer() - start),3))
    return result



def slowdistancematrix(data):

    from geopy.distance import geodesic
    distance = np.zeros((data.shape[0],data.shape[0]))
    for i in range(data.shape[0]):

        lat_lon_i = data.Latitude.iloc[i],data.Longitude.iloc[i]

        for j in range(i):

            lat_lon_j = data.Latitude.iloc[j],data.Longitude.iloc[j]

            distance[i,j] = geodesic(lat_lon_i, lat_lon_j).miles
            distance[j,i] = distance[i,j] # make use of symmetry

    return distance

distanceG = slowdistancematrix(data)
distanceH = Haversine(data.values)



plt.scatter(distanceH.ravel(),distanceG.ravel()/distanceH.ravel(),s=.5)
plt.ylabel('Geodesic/Haversine')
plt.xlabel('Haversine distance (miles)')
plt.title('all points in distance matrix')

我宁愿使用矢量化版本,因为它速度很快.但是,5%对我来说太大了,无法接受.假设Haversine仅下降了0.5%.

I would rather use the vectorized version becuase it is fast. However,the 5% is too big for me to be comfortable with it. Supposedly Haversine is only suppose to be off by .5%.

更新:

发现错误.当实现向量化版本时,我并不是在计算点之间的所有距离,而只是在一些点之间.我更新了代码以反映这一点.这是Haversine和Geodesic之间对于我的域的区别(25-55 *乘-125--110):

Found error. when implementing the vectorized version I wasn't calculating all the distances between points, but only between some. I updated code to reflect this. Here is what the difference between Haversine and Geodesic are for my domain (25-55* by -125--110):

太好了!

推荐答案

Haversine公式中存在矩阵代数错误.我更新了问题中的代码.我现在在Haversine和Geodesic之间达成了更好的协议:

There was a matrix algebra error in the Haversine formula. I updated the code in the question. I am getting much better agreement between Haversine and geodesic now:

在我的实际数据集上:

这篇关于在计算地球上两点之间的距离时,为什么我的Haversine与Geodesic计算有差异?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆