Haversine 公式的不同结果

Posted

技术标签:

【中文标题】Haversine 公式的不同结果【英文标题】:Different result for Haversine formulas 【发布时间】:2012-03-15 19:22:35 【问题描述】:

我正在使用 mysql 来计算接近度,为此我创建了一个名为 distance 的过程,如下所示,但该过程无法正常工作,但 sql 语句正在工作,所以这里有什么区别,因为我猜两者都是Haversine formulas 但没有给我正确的结果。我真的don't know wht i am missing in formula one.

我的表的数据结构如下

对于一级方程式

id  varchar(100)    
userid  varchar(100)    
username varchar(100)
currLoc point           
radius  int(10)

对于公式二

id  varchar(30)
userid  varchar(30)
username varchar(40)
lat float(10,6)
lan float(10,6)
radius  varchar(100)

一级方程式: reference

sql statement to execute distance function

SELECT userid, username, distance(userstatus.currLoc, 
 GeomFromText('POINT(23.039574  72.56602)')) AS cdist 
    FROM userstatus HAVING cdist <= 0.6 ORDER BY cdist LIMIT 10


 RETURN 6371 * 2 *
    ASIN( SQRT(POWER(SIN(RADIANS(ABS(X(a)) - ABS(X(b)))), 2) + 
               COS(RADIANS(ABS(X(a)))) * COS(RADIANS(ABS(X(b)))) *
                    POWER(SIN(RADIANS(Y(a) - Y(b))), 2)));

公式二: reference

SELECT *,(((acos(sin((23.039574*pi()/180)) * 

        sin((lat *pi()/180))+cos((23.039574*pi()/180)) * 

         cos((lat *pi()/180)) * cos(((72.56602- lon)*pi()/180))))*

     180/pi())*60*1.1515*1.609344) as distance

FROM status HAVING distance <= 0.6

这里0.6是以公里为单位的半径

【问题讨论】:

【参考方案1】:

表达式的一个版本是使用 ABS(X(a)) 等,而另一个不是。使用 ABS 的那个是可疑的。你不能忽视角度上的标志。在世界的某些区域(例如赤道或本初子午线附近,或两极附近),您会得到不同的结果。

你的常数也不同。

60*1.1515*1.609344

6371 * 2

一个表达式涉及 SQRT,另一个不涉及。

一种表达方式涉及ASIN,另一种使用ACOS。

两者之间基本上没有任何共同点......

请参阅 Wikipedia 'Haversine Formula' 上的讨论,特别是当点之间的距离很小时时对数值稳定性的引用。

您还可以通过将您使用的公式分成几行来提高人们帮助您的机会。

例如:

 RETURN 6371 * 2 *
        ASIN( SQRT(POWER(SIN(RADIANS(ABS(X(a)) - ABS(X(b)))), 2) + 
                   COS(RADIANS(ABS(X(a)))) * COS(RADIANS(ABS(X(b)))) *
                        POWER(SIN(RADIANS(Y(a) - Y(b))), 2)));

还有:

(((acos(sin((23.039574*pi()/180)) * sin((lat *pi()/180)) +
        cos((23.039574*pi()/180)) * cos((lat *pi()/180)) *
        cos(((72.56602-lan)*pi()/180))
       )
   ) * 180/pi()) * 60 * 1.1515 * 1.609344)

后者引用'lan';那是'lon'吗?在第二个示例中,您似乎将两个位置之一编码为 23.039574°N 和 72.56602°W,并且latlan 来自 SQL 查询中的表。

【讨论】:

+1 引起我的注意,好吧,那我应该使用什么是标准和正确的? 公式二是一个有效的Haversine公式,虽然?

以上是关于Haversine 公式的不同结果的主要内容,如果未能解决你的问题,请参考以下文章

Java中的Haversine公式产生不正确的结果

使用haversine公式,结果太高

根据haversine距离公式选择不同的列值?

CakePHP 2.2.4 无法使用 HAVING 子句和计算字段对结果进行分页 - Haversine 公式

Codeigniter 和 SQL/Haversine 公式

对haversine公式使用列表推导