我有一个带有空间点的MySQL表,需要计算距离。我发现使用Haversine公式做了很多这方面的材料,但是所有这些都假设点之间有很大的距离。在我的情况下,我只关心短距离(<1英里),所以我不需要纠正地球的曲率。我的直觉是使用Haversine公式在这么小的距离上会不准确。有什么建议吗?
答案 0 :(得分:3)
你的直觉是不正确的。根据维基百科(φ是纬度而ψ是经度),考虑hasrsine公式和hasrsine的定义:
还有一个相关的事实:对于θ的小值,sin θ大约等于θ;更相关的是,它在θ中大约是线性。因此,hasrsinθ约为(θ / 2)²。当θ接近零时,这种近似会变得更好。
如果纬度和经度接近,那么φ 2 - φ 1和ψ 2 - ψ 1,这是应用于此处的半正函数,将接近于零,这意味着公式大约是
(d / 2r)²=((φ 2 - φ 1)/ 2)²+ cos(φ 1)cos (φ 2)((ψ 2 - ψ 1)/ 2)²
现在请注意,此公式与二维欧几里德距离具有相同的形式,具有一些任意比例因子(记住( kx )²= k ² x ²所以我们可以将常数移入和移出正方形):
k 1 d ²= k 2Δφ²+ k 3Δψ²
最后,我断言没有证据证明这些任意比例因子与将纬度/经度变化转换为线性距离的结果相同。
因此,对于小距离而言, 它与普通的欧几里德距离计算完全一样,在小距离的限制内。
答案 1 :(得分:0)
使用Geometry数据类型的Point值创建点 MyISAM表
在这些点上创建一个SPATIAL索引
使用MBRContains()查找值:
SELECT *
FROM table
WHERE MBRContains(LineFromText(CONCAT(
'('
, @lon + 10 / ( 111.1 / cos(RADIANS(@lon)))
, ' '
, @lat + 10 / 111.1
, ','
, @lon - 10 / ( 111.1 / cos(RADIANS(@lat)))
, ' '
, @lat - 10 / 111.1
, ')' )
,mypoint)
,或者,在MySQL 5.1及以上版本中:
SELECT *
FROM table
WHERE MBRContains
(
LineString
(
Point
(
@lon + 10 / ( 111.1 / COS(RADIANS(@lat))),
@lat + 10 / 111.1
)
Point
(
@lon - 10 / ( 111.1 / COS(RADIANS(@lat))),
@lat - 10 / 111.1
)
),
mypoint
)
这将选择大约在框内的所有点(@lat +/- 10 km,@ ron +/- 10km)。
这实际上不是一个盒子,而是一个球形矩形:球体的纬度和经度束缚段。这可能与Franz Joseph Land上的一个普通矩形不同,但在大多数有人居住的地方都非常接近。
应用其他过滤来选择圆圈内的所有内容(不是方形)
可能应用额外的精细过滤来计算大圆距离(对于大距离)