【问题标题】:Geo fencing in PHP and MySQL using latitude, longitude and radiusPHP和MySQL中使用纬度、经度和半径的地理围栏
【发布时间】:2014-01-18 08:13:48
【问题描述】:

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

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

我最初的想法是在数据库中为每个 lat、long 创建一个边界框(基于半径),然后根据这个边界框查询传入的位置详细信息。这种方法正确吗?如果我走这条路,有什么我应该担心的吗?任何能指导我正确方向的帮助将不胜感激。

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

http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates

【问题讨论】:

标签: php mysql latitude-longitude geofencing


【解决方案1】:

这样的事情应该可以解决问题:

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)

如您所见,这需要您执行平方根。如果您想编写快速代码,应该像瘟疫一样避免平方根。仅在确实需要时才执行平方根。

避免平方根的方法: 如果您不需要非常精确的距离,可以使用查找表来计算。

例如,如果您正在执行球体之间的碰撞检测,而您只想知道两个球体是否发生了碰撞,那么您就不需要使用平方根。只需更改一段代码

来自: if SquareRoot(xdxd + ydyd)

到: if (xdxd + ydyd)

【讨论】:

    【解决方案2】:

    这是欧几里得距离,而不是大圆距离,这是必须使用半径 5 英里的距离,因为这是地图使用的距离。用户离地球赤道越远,欧几里得距离就会有很大的误差。

    更好的解决方案是使用新的 mysql gis 函数,但它仍然会很慢,除非您执行子查询:找到最近的欧几里得(甚至曼哈顿)点,然后计算这些点的距离。

    另外,请记住距离函数是单调的,因此您可以不用最终的平方根。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多