执行邻近搜索的路线图

Posted

技术标签:

【中文标题】执行邻近搜索的路线图【英文标题】:road map to perform proximity search 【发布时间】:2012-03-15 13:43:05 【问题描述】:

我想找 X 英里附近的人,让我好好解释一下。

我有一个执行以下操作的应用程序

1) it shows user's current location on a google map with a radius circle of 3 miles. 

2) when ever user uses this application its current location will get stored into mysql database
  as follows

   ID          Name       currLat       currLan     radius (in miles )
  --------------------------------------------------------------------
  34334        John       23.039574     72.56602      3

此外,当新用户使用同一个应用程序时,他的当前位置也会存储在上表中。

因此,当任何用户访问此应用程序时,服务器端代码将根据当前位置检查是否有其他用户在他周围。

我用谷歌搜索,但我真的don't know what's the approach to match and perform proximity search 我读过一些公式,但真的不知道执行它的程序。

到目前为止,我已经在 php 中使用了以下代码,它返回 max 和 min lat n lan,但我真的不知道该怎么做,因为我对邻近搜索完全陌生,所以任何人都可以告诉我 @987654324 @

    $radius = 600;

    $longitude = (float) $lan;
    $latitude = (float) $lat;


    $lng_min = $longitude - $radius / abs(cos(deg2rad($latitude)) * 69);
    $lng_max = $longitude + $radius / abs(cos(deg2rad($latitude)) * 69);
    $lat_min = $latitude - ($radius / 69);
    $lat_max = $latitude + ($radius / 69);

    $data ["lat"] = $lng_min . '/' . $lng_max . PHP_EOL;
    $data ["lan"] = $lat_min . '/' . $lat_max;

我真的希望这次不是一个虚幻的问题,如果有人想了解更多信息,请随时询问

到目前为止我已经完成了

创建一个带有 POINT 字段类型和 SPATIAL 索引的表

CREATE TABLE userstatus (
  id varchar(100) NOT NULL,
  userid varchar(100) NOT NULL,
  username varchar(100) NOT NULL,
  currLoc  POINT NOT NULL,
  radius INT(10),
  SPATIAL INDEX(currLoc)

)ENGINE = MYISAM

之后是计算距离的过程

DELIMITER $$
 CREATE FUNCTION distance (a POINT, b POINT) RETURNS double DETERMINISTIC
   BEGIN
     RETURN 6371 * 2 * ASIN(SQRT(POWER(SIN(RADIANS(ABS(X(a)) - ABS(X(b)))), 2) + COS(RADIANS(ABS(X(a)))) * COS(RADIANS(ABS(X(b)))) * POWER(SIN(RADIANS(Y(a) - Y(b))), 2)));
   END  $$
DELIMITER ;

现在我不知道我会是谁compare my user's lat , lat and radius with above function

我使用插入了我的数据

$userStatusInsert = "INSERT INTO userstatus (id,userid,username,currLoc,radius) 
                    VALUES('".$id."','".$uid."','".$uname."',GeomFromText('POINT(".$lat." ".$lan.")'),'".$radius."')";

我触发了查询 在 cdist

SELECT userid, username, distance(userstatus.currLoc, GeomFromText('POINT(23.039574  72.56602)')) AS cdist FROM userstatus HAVING cdist < 10 ORDER BY cdist LIMIT 10

结果如下,但我真的不知道 cdist 列包含什么,我的意思是这个 确定一个人在范围内

id      username          cdist
-----------------------------------
1115    John    4.52726116114886
1111    Hunt    6.2734062677772
1112    Raul    7.55266860461263
1113    Nizam   7.55480140608532
1114    John    7.76912596719722

【问题讨论】:

你应该用 mysql 来做,而不是用 php 代码。这个问题之前已经解决过很多次了。这是一个示例教程:vinsol.com/blog/2011/08/30/geoproximity-search-with-mysql 你也可以搜索“mysql geo邻近搜索”来找到许多其他人 我同意。使用 mysql 或 postgresql 的空间扩展。我实际上更喜欢使用 postgresql,因为它不像 mysql 那样使用具有地理空间功能的 mbr(最小边界矩形)(至少在 v5.6 可用之前)就像查看一个点是否在一个奇数形状的多边形内。 @Ben Lee 在你的例子中他们使用 Polygon 有没有办法定义圆? 【参考方案1】:

harvesine 公式描述了 2 个圆碰撞的时间。第一个圆圈是您当前的位置,第二个圆圈是任何其他兴趣点。您需要定义第一个圆的半径并将任何其他兴趣点与之进行比较。也可以使用正方形。或者,您可以使用四键或 mysql 空间扩展等空间索引。

【讨论】:

如何使用圆形(因为我不想要多边形) @Hunt:在示例中,封闭多边形仅用作空间索引。如果您不想使用空间索引,可以从 WHERE 子句中删除它。用户 Ray Perea 使用空间索引和 harvesine 公式。 你的意思是我应该删除 WHERE 子句并将第一个参数作为所有用户存储在数据库中,第二个参数作为请求此查询的当前用户 @Hunt:看起来还可以。 currLoc 的数据类型是什么?您是否尝试过手动插入地理坐标?准备好的语句看起来没问题。 @Hunt:看看这里是如何解决的:***.com/questions/8727717/…。我不知道如何使用 mydql 点数据类型。也许程序是错误的。如果您可以从点变量中获取坐标。

以上是关于执行邻近搜索的路线图的主要内容,如果未能解决你的问题,请参考以下文章

MySQL-触发器

MySQL-触发器

如何使用百度地图查询出行路线

如何使用百度地图查询出行路线

个人前端学习路线图与github优秀前端开发者的路线图推荐

更改返回视图以在 laravel 搜索功能上返回路线