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,并且lat
和 lan
来自 SQL 查询中的表。
【讨论】:
+1 引起我的注意,好吧,那我应该使用什么是标准和正确的? 公式二是一个有效的Haversine公式,虽然?以上是关于Haversine 公式的不同结果的主要内容,如果未能解决你的问题,请参考以下文章
CakePHP 2.2.4 无法使用 HAVING 子句和计算字段对结果进行分页 - Haversine 公式