PHP Radius搜索

时间:2016-05-11 09:56:53

标签: php sql location maps distance

我打算构建一个应用,用户可以在预定义的半径范围内查看兴趣点。

我的第一个想法是将所有POI的纬度和经度存储在数据库中,并通过SQL将用户位置与POI的位置进行比较。

问题在于我认为的表现。如果有数以千计的POI和数千个用户请求及其位置,那么对于当今的服务器来说这不是很经济,或者这不是问题吗?

我的下一个方法是将地图划分为象限,并仅观察周围的象限。

TL; DR:

总而言之,我正在寻找:

  • 一种进行半径搜索的方法
  • 最好为其他用户缓存结果
  • 注册新POI时将更新缓存。

如果你有任何想法如何实现这样的事情,请告诉我。

谢谢

费边

1 个答案:

答案 0 :(得分:1)

我认为您正在寻找的是Harversine formula,它可以让您找到球体中两点之间的距离(在本例中为地球)。使用SQL的实现将是这样的:

ACOS (
  SIN(RADIANS($latitude)) * 
  SIN(RADIANS(T.latitude))+ 
  COS(RADIANS($latitude)) * 
  COS(RADIANS(T.latitude))* 
  COS(RADIANS($longitude-T.longitud)))*6378.137 AS distance  

将此选项添加到您的查询选择中将返回一个名为距离计算(以Km为单位)的列,该点($ latitude,$ longitude)(通常是用户)距离(T.latitude,T.longitude)有多远,通常是表格的元素。

如果你想要过滤,并且不显示超过一定距离的元素,你可以做出如下条件:

HAVING distance<$radius  

我想你正在使用MySQL,如果是这种情况,你必须使用HAVING而不是WHERE来计算计算列(距离)的条件。

查询的完整示例如下:

SELECT T.*, ACOS (
      SIN(RADIANS($latitude)) * 
      SIN(RADIANS(T.latitude))+ 
      COS(RADIANS($latitude)) * 
      COS(RADIANS(T.latitude))* 
      COS(RADIANS($longitude-T.longitud)))*6378.137 AS distance
FROM your_table as T  
HAVING distance < $radius
ORDER BY distance LIMIT $limit

如果您想进一步优化性能,请为查询添加限制,以便您拥有例如最近的10个位置。

请花时间考虑Spatial data types,因为他们是专门为这类工作而做的。

请注意,我不建议您将php变量直接插入查询中,真的不安全,我只是作为一个例子。

希望这会对你有所帮助。