执行邻近搜索的路线图
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 点数据类型。也许程序是错误的。如果您可以从点变量中获取坐标。以上是关于执行邻近搜索的路线图的主要内容,如果未能解决你的问题,请参考以下文章