由于您说的是大约 5 公里的小距离,而且我们可能不在北极或南极附近,我们可以使用经度和纬度值的近似网格系统。纬度的每一度相当于km_per_lat=6371km*2*pi/360degrees = 111.195km 的距离。两条相距 1 度的经线之间的距离取决于实际纬度:
km_per_long=km_per_lat * cos(lat)
对于德国北部(北 51 度)的地区,该值约为 69.98 公里。
因此,假设我们对 lat0 和 long0 附近的小距离感兴趣,我们可以放心地假设经度角和纬度角的平移因子将保持不变,我们可以简单地应用公式
SELECT 111.195*sqrt(power(lat-@lat0,2)
+power(cos(pi()/180*@lat0)*(long-@long0),2)) dist_in_km FROM tbl
由于您想在您的选择的WHERE 子句中使用公式,您可以使用以下内容:
SELECT * FROM tbl
WHERE 111.195*sqrt(power(lat-@lat0,2)
+power(cos(pi()/180*@lat0)*(long-@long0),2)) < 5
select 语句适用于以度数(十进制表示法)给出的纬度和经度值。因此,我们必须将cos() 函数中的值乘以pi()/180,将其转换为弧度。
如果您必须处理更大的距离(>500 公里),那么最好应用导航中使用的适当距离公式,例如
cos(delta)=cos(lat0)*cos(lat)*cos(long-long0) + sin(lat0)*sin(lat)
通过应用acos() 计算出实际角度增量后,您只需将该值乘以地球半径R = 6371km = 180/pi()*111.195km,即可获得所需的距离(参见此处:Wiki: great circle distance)
更新(回复评论):
不确定您打算做什么。如果您只想比较 一个 参考位置,那么您当然可以预编译您的距离计算,有点像
SELECT @lat0:=51,@long0:=-9; -- assuming a base position of: 51°N 9°E
SELECT @rad:=PI()/180,@fx:=@rad*6371,@fy:=@fx*cos(@rad*@lat0);
然后您的距离计算将简化为
SELECT @dist:=sqrt(power(@fx*(lat-@lat0),2)+power(@fy*(long-@long0),2))
在lat 和long 中的当前位置(不再需要余弦函数)。您是想先将所有传入的位置存储在数据库中,还是想在 Spring、Java 或您使用的任何语言之外的某个地方进行计算,这取决于您。方程在那里并且易于使用。