我有一个MySQL表,其中包含纬度,经度,用户ID和半径。当用户提供他当前的位置(纬度,长度)和半径时,我想查询表格,根据两个半径为他提供重叠位置。
例如,如果用户给我一个12.5的纬度;经度73.5,半径5英里;我应该能够检索MySQL表中两个半径都重叠的所有条目。
我最初的想法是为数据库中的每个纬度创建一个边界框(基于半径),然后根据此边界框查询传入的位置详细信息。这种方法是否正确?如果我走这条路,有什么我应该关注的吗?非常感谢任何指导我正确方向的帮助。
PS:以下链接是我用作参考的内容。
答案 0 :(得分:4)
这样的事情应该可以解决问题:
SELECT
*
FROM
YOUR_TABLE
WHERE
SQRT((input_lat - db_lat) * (input_lat - db_lat) + (input_long - db_long) * (input_long - db_long)) <= input_radius
我使用了这个:Distance between two points
只有一件事:将半径转换为与坐标相同的单位
链接的内容(如果它已关闭)
这个小操作计算两点之间的距离。该例程可以在任意数量的维度上工作,因此您可以将其冷应用于2D或3D。
在2D中 定义你的两点。点1在(x1,y1),点2在(x2,y2)。
xd = x2-x1
yd = y2-y1
Distance = SquareRoot(xd*xd + yd*yd)
在3D中 定义你的两点。点1在(x1,y1,z1)和点2在(x2,y2,z2)。
xd = x2-x1
yd = y2-y1
zd = z2-z1
Distance = SquareRoot(xd*xd + yd*yd + zd*zd)
如您所见,这需要您执行平方根。如果你想编写快速代码,应该像瘟疫一样避免平方根。如果你真的需要,只执行平方根。
避免Square Roots的方法: 如果您不需要非常精确的距离,可以使用查找表来计算它。
例如,如果您在球体之间执行碰撞检测,并且您想要知道的是两个是否发生碰撞,那么您不需要使用平方根。只需更改代码
即可自: 如果SquareRoot(xd xd + yd yd)&lt;直径
于: if(xd xd + yd yd)&lt; (直径*直径)
答案 1 :(得分:1)
该欧几里德距离,而不是大圆距离,这是用于制作5英里半径的距离,因为距离地图使用的是距离。欧几里德距离将与用户离地球赤道越远的大圆相比具有强烈的误差。
更好的解决方案是使用新的mysql gis函数,但它仍然会很慢,除非你做一个子查询:找到最近的欧几里得(甚至曼哈顿)点,然后计算它们的距离。
另外,请记住距离函数是单调的,因此您可以在没有最终平方根的情况下进行操作。