我想获取一个在给定纬度和经度,给定距离的圆或正方形内的用户列表。例如,我的输入Lat = 78.3232和Long = 65.3234且距离= 30英里。我想获取距离点78.3232和65.3234在30英里以内的用户列表。
是否可以通过单个查询解决此问题?还是可以给我提示开始解决此查询?
#1 楼
该SQL语句将查找距78.3232、65.3234坐标30英里范围内最近的20个位置。它根据该行的纬度/经度和目标纬度/经度计算距离,然后仅询问距离值小于30英里的行,按距离对整个查询进行排序,并将其限制为20个结果。要按公里而不是英里进行搜索,请将3959替换为6371。SELECT
id, (
3959 * acos (
cos ( radians(78.3232) )
* cos( radians( lat ) )
* cos( radians( lng ) - radians(65.3234) )
+ sin ( radians(78.3232) )
* sin( radians( lat ) )
)
) AS distance
FROM markers
HAVING distance < 30
ORDER BY distance
LIMIT 0 , 20;
这是将Google Maps API v3与您已经拥有的MySQL后端一起使用。 >
https://developers.google.com/maps/articles/phpsqlsearch_v3#findnearsql
评论
使用此选项时,我在选择中遇到语法错误,“#1582-对本机函数'radians'的调用中不正确的参数计数可能是什么?
– bluantinoo
2014年11月29日在2:09
发现:我的lng变量为空!抱歉!
– bluantinoo
2014年11月29日10:38
正是我想要的,但是数千条记录的查询性能超载了什么?准确性如何?
–阿米莎(Amit Shah)
19年2月5日,12:01
更好地将其替换为6371392.896以进行米数搜索
–Vasilii Suricov
19年2月6日在22:32
是否无法像我这样将距离结果从2.71250308462937983478013848070986568927764892578125减少到2.71?
–阿里·阿迪尔(Ali Adil)
20-2-28在19:45
#2 楼
Mapperz的答案无效。窦必须根据纬度而不是经度来计算。因此,corect SQL语句为:
SELECT
id, (
3959 * acos (
cos ( radians(78.3232) )
* cos( radians( lat ) )
* cos( radians( lng ) - radians(65.3234) )
+ sin ( radians(78.3232) )
* sin( radians( lat ) )
)
) AS distance
FROM markers
HAVING distance < 30
ORDER BY distance
LIMIT 0 , 20;
评论
您的答案应排在第一位。
–阿米莎(Amit Shah)
19年2月5日在12:06
@AmitShah如果您认为可以对提问者(@shihabK在站点上活跃了将近6年)进行ping操作和/或投票给meta.stackexchange.com/questions/268666/…
– PolyGeo♦
19年2月6日在23:33
这应该是公认的答案。
–catbadger
19-09-28在13:08
#3 楼
创建函数可能是基础..因此您可以在其他区域重用它。也会使您的查询更整洁...至少那是我的2美分。DELIMITER $$
CREATE FUNCTION calcDistance(lat FLOAT, lng FLOAT, pnt_lat FLOAT, pnt_lng FLOAT)
RETURNS FLOAT
BEGIN
DECLARE dist FLOAT;
SET dist =
3959 * acos(
cos(radians(pnt_lat))
* cos(radians(lat))
* cos(radians(lng) - radians(pnt_lng))
+ sin(radians(pnt_lat))
* sin(radians(lat))
);
RETURN dist;
END
评论
如果您修复代码样式,答案将被否决。这是正确的方法
–Vasilii Suricov
19年2月6日在23:31
#4 楼
现在是2020年,您应该使用RDBS的内置空间功能。在这种情况下,您需要使用ST_Distance函数。-- geo column in users table is of Geometry data type, with a spatial index
SET @g1 = ST_SRID(POINT(78.3232, 65.3234), 4326);
SELECT * from users WHERE ST_Distance(users.geo, @g1, 'foot') < 158400; -- 5280 feet per mile
评论
如果除此之外,我们还想按距离对它们进行排序呢?第一个,最接近的一个。我们是否使用ORDER BY ...?非常感谢@JohnC
–里卡多
20-10-24在15:53
@Ricardo正确,您可以将空间函数放在order by子句中。确保您也有一个空间索引。
– John C
20-10-28在6:11
#5 楼
这是我的查询变体,似乎稍微容易一些(http://dexxtr.com/post/83498801191/how-to-determine-point-inside-circle-using-mysql)SELECT
*
FROM
`locator`
WHERE
SQRT(POW(X(`center`) - 49.843317 , 2) + POW(Y(`center`) - 24.026642, 2)) * 100 < `radius`
评论
这比较容易,但忽略了地球是弯曲的这一事实。
– Tim Rijavec
2015年6月3日,13:35
需要一个公式才能准确。也许这仅在短距离上会比较好:D
– Jethro
15年12月27日在16:49
你会发射导弹,还是什么?
–丹尼斯·布拉加(Dennis Braga)
19年6月11日在14:12
@DennisBraga-如果是这样,那么也许这个问题是题外话,更适合http://globalthermonuclearwar.stackexchange.com ...?
–ashleedawg
19年8月22日在9:37
评论
为什么不使用PostGIS?如果您正在启动地理项目,则仍然可以更改堆栈stackoverflow.com/a/40272394/1281385在加快此查询速度(如果需要)中应该很有用
我认为他的计算方法不正确。我正在尝试计算布尔加斯(BOJ-42.416668,27.283333)和瓦尔纳(VAR-43.237260,27.829096)之间的距离。与此请求(6371 * acos(cos(弧度(43.237260))* cos(弧度(lat))* cos(弧度(lon)-弧度(27.829096))+ sin(弧度(43.237260))* sin(弧度(lat ))))AS距离的结果是101,52135729600961 KM,在Google地图中,距离是78.88 km。 ![在此处输入图片描述](i.stack.imgur.com/FGnCC.png)