使用纬度,经度和半径在PHP和MySQL中进行地理围栏

时间:2013-12-31 11:21:15

标签: php mysql latitude-longitude geofencing

我有一个MySQL表,其中包含纬度,经度,用户ID和半径。当用户提供他当前的位置(纬度,长度)和半径时,我想查询表格,根据两个半径为他提供重叠位置。

例如,如果用户给我一个12.5的纬度;经度73.5,半径5英里;我应该能够检索MySQL表中两个半径都重叠的所有条目。

我最初的想法是为数据库中的每个纬度创建一个边界框(基于半径),然后根据此边界框查询传入的位置详细信息。这种方法是否正确?如果我走这条路,有什么我应该关注的吗?非常感谢任何指导我正确方向的帮助。

PS:以下链接是我用作参考的内容。

http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates

2 个答案:

答案 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函数,但它仍然会很慢,除非你做一个子查询:找到最近的欧几里得(甚至曼哈顿)点,然后计算它们的距离。

另外,请记住距离函数是单调的,因此您可以在没有最终平方根的情况下进行操作。