我正在使用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是以公里为单位的半径
答案 0 :(得分:3)
表达式的一个版本是使用ABS(X(a))等,而另一个版本则不是。使用ABS的人是可疑的。你不能忽视角度上的标志。你会在世界某些地区得到不同的结果(例如靠近赤道或本初子午线,或靠近两极)。
你的常数也不同。
60*1.1515*1.609344
VS
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查询中的表。