如何在MySQL中以公里搜索附近位置

问题描述 投票:0回答:4

我的数据库结构如下。我怎样才能得到列表中5公里以内的location_id。数据库表中已有纬度和经度数字。请看我的数据库结构图。

- school_id
- location_id
- school_name
- lat
- lng

这是数据库结构图:

我已经从这个链接搜索过 如何使用sql数据库中的纬度和经度查找最近的位置? 我不明白代码。

选择id,(3959 * acos(cos(弧度(37))* cos(弧度(纬度))* cos( 弧度( lng ) - 弧度(-122) ) + sin( 弧度(37) ) * sin( 弧度( 纬度 ) ) ) ) AS 距离标记的距离 < 25 ORDER BY distance LIMIT 0 , 20;

mysql location
4个回答
14
投票

常量文字3959表示地球半径的近似值(以英里为单位)。这就是为什么“大圆距离”表达式返回以英里为单位的值。

要获取以公里为单位的距离,只需将 3959 替换为 6371(地球半径的近似值,以公里为单位)。

参考:https://en.wikipedia.org/wiki/Great-circle_distance


查询所做的是计算地球上两点之间的距离(以英里为单位),用纬度和经度表示。

其中一个点由 GCD 表达式 (37.000000,-122.000000) 中的文字值表示。另一点是数据库中行的 (lat,lng)(纬度和经度)。

查询遍历表中的每一行,并评估 GCD 表达式以计算距离。 (两点之间沿球体表面的最短线的长度。)

HAVING distance < 25
子句排除计算距离大于或等于 25 或 NULL 的任何行。

ORDER BY distance
子句按距离值升序返回行,首先是最近的点。

LIMIT 20
子句将返回限制为前二十行。


跟进

距离什么五公里以内?圣莫尼卡码头水族馆?

即纬度 34.010396,经度 -118.496029。

我们可以设置用户定义的变量(以避免在查询文本中传播文字):

 SET @lat =   34.010396 ;
 SET @lng = -118.496029 ;

我们的 SQL 文本在 SELECT 列表中包含我们想要从表中返回的列。我们还将包含一个看起来复杂的“大圆距离”表达式,它返回以公里为单位的距离。

类似这样的:

 SELECT m.school_id
      , m.location_id
      , m.school_name
      , m.lat
      , m.lng

      , ( ACOS( COS( RADIANS( @lat  ) ) 
              * COS( RADIANS( m.lat ) )
              * COS( RADIANS( m.lng ) - RADIANS( @lng ) )
              + SIN( RADIANS( @lat  ) )
              * SIN( RADIANS( m.lat ) )
          )
        * 6371
        ) AS distance_in_km

  FROM mytable m
 ORDER BY distance_in_km ASC
 LIMIT 100

表达式中的GCD公式正在计算两个点之间的距离。

在此查询中,其中一个点是 constant

(@lat,@lng)
,我们之前将其设置为圣莫尼卡码头水族馆的坐标。

另一点是

(m.lat,m.lng)
,即表中行的纬度和经度。

因此在这个查询中,

distance_in_km
表示表中行的
(lat,lng)
与圣莫尼卡码头水族馆之间的距离。

因为

distance_in_km
值在访问行时可用,所以我们无法在
WHERE
子句中引用该值。

但是我们可以在

HAVING
子句中引用它。这与
WHERE
类似,因为它会过滤掉行,但有很大不同,因为它是在查询执行的后期进行评估的。当访问行、评估
WHERE
子句时,它可以引用不可用的表达式。

我们可以修改查询以包含 HAVING 子句。在本例中,我们限制为 100 公里内的行,并且我们将仅返回最近的 12 行...

  FROM mytable m
HAVING distance_in_km <= 100
 ORDER BY distance_in_km ASC
 LIMIT 12

如果我们想找到到圣莫尼卡码头以外的某个点的距离,我们为该点设置

@lat
@lng
,然后重新执行 SQL。


3
投票
SELECT *, ((ACOS(SIN(inputLat * PI() / 180) * 
SIN(tableColLat * PI() / 180) + COS(inputLat * PI() / 180) * 
COS(tableColLat * PI() / 180) * COS((inputLng - tableColLng) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) 
as distance FROM gm_shop HAVING distance <= 5 ORDER BY distance ASC;

距离是可以改变的。是KM


0
投票

当我解决了类似的问题而不是担心地球的曲率和角度时。我刚刚使用了毕达哥拉斯距离。恕我直言,这是一个足够接近的近似值。

即获取毕达哥拉斯距离大约 5 公里内的所有学校。

select sqrt(pow(lat - curlat,2) + pow(lng - curlng,2)) as distance from markers having distance < XXXXX

您必须计算 XXXX 的近似值。 I度约为111km。如果您没有进行任何极端的纬度,则不必担心调整它。所以你可以将 XXXX 设置为 0.045


0
投票

我有相同的逻辑,我必须使用 php mysql 数据库找到用户附近的当前位置,所以请查看此链接,这可能对您有帮助:https://myphpinformation.blogspot.com/2015/12/get-near-by-location -使用纬度和经度-php-in-kilometer.html

© www.soinside.com 2019 - 2024. All rights reserved.