我正在使用 mysql 来计算接近度,为此我创建了一个名为 distance 的过程,如下所示,但该过程无法正常工作,但 sql 语句正在运行,所以这里有什么区别,因为我猜两者都是Haversine 公式
但没有给我正确的结果。我真的不知道我在一级方程式赛车中错过了什么。
我的表的数据结构如下
一级方程式
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是以千米为单位的半径
最佳答案
表达式的一个版本使用 ABS(X(a)) 等,而另一个则不使用。使用ABS的那个值得怀疑。你不能忽视角度上的标志。在世界的某些地区(例如,靠近赤道或本初子午线,或靠近两极),您会得到不同的结果。
你的常数也不同。
60*1.1515*1.609344
对比
6371 * 2
一个表达式涉及 SQRT,另一个不涉及。
一个表达式涉及 ASIN,另一个使用 ACOS。
两者之间基本上没有任何共同点......
请参阅维基百科上的讨论 '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 查询中的表.
关于mysql - Haversine 公式的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9446068/