为了账号安全,请及时绑定邮箱和手机立即绑定

在mysql中使用经度和纬度查找两点之间的距离

/ 猿问

在mysql中使用经度和纬度查找两点之间的距离

慕容3067478 2019-11-14 09:32:28

嗨,我有下表


 --------------------------------------------

 |  id  |  city  |  Latitude  |  Longitude  |

 --------------------------------------------

 |  1   |   3    |   34.44444 |   84.3434   |

 --------------------------------------------

 |  2   |   4    | 42.4666667 | 1.4666667   |

 --------------------------------------------

 |  3   |   5    |  32.534167 | 66.078056   |

 --------------------------------------------

 |  4   |   6    |  36.948889 | 66.328611   |

 --------------------------------------------

 |  5   |   7    |  35.088056 | 69.046389   |

 --------------------------------------------

 |  6   |   8    |  36.083056 |   69.0525   |

 --------------------------------------------

 |  7   |   9    |  31.015833 | 61.860278   |

 --------------------------------------------

现在我想获得两点之间的距离。假设一个用户有一个城市3,一个用户有一个城市7。我的情况是一个用户有一个城市和纬度,纬度正在搜索其他用户与城市的距离。例如,拥有城市3的用户正在搜索。他想得到其他城市的用户的距离是7。我已搜索到以下查询


SELECT `locations`.`city`, ( 3959 * acos ( cos ( radians(31.589167) ) * cos( radians( Latitude ) ) * cos( radians( Longitude ) - radians(64.363333) ) + sin ( radians(31.589167) ) * sin( radians( Latitude ) ) ) ) AS `distance` FROM `locations` HAVING (distance < 50)

据我所知,此查询查找从一个点到所有其他点的距离。现在我想获得一个点到另一点的距离。


任何指导方针将不胜感激。


查看完整描述

3 回答

?
www说

我认为您的问题是您具有city两个城市之间的值,您希望计算它们之间的距离。


该查询将为您完成工作,并以km为单位得出距离。它使用球余弦定律公式。


请注意,您将表格与其自身相连,因此可以检索两个坐标对以进行计算。


SELECT a.city AS from_city, b.city AS to_city, 

   111.111 *

    DEGREES(ACOS(LEAST(1.0, COS(RADIANS(a.Latitude))

         * COS(RADIANS(b.Latitude))

         * COS(RADIANS(a.Longitude - b.Longitude))

         + SIN(RADIANS(a.Latitude))

         * SIN(RADIANS(b.Latitude))))) AS distance_in_km

  FROM city AS a

  JOIN city AS b ON a.id <> b.id

 WHERE a.city = 3 AND b.city = 7

请注意,常数111.1111是每米纬度的公里数,它是根据米的旧的拿破仑式定义,即从赤道到极点的距离的千分之一。该定义对于位置查找器工作足够接近。


如果要确定英里数而不是公里数,请69.0改用。


http://sqlfiddle.com/#!2/abcc8/4/0


如果您正在寻找附近的地点,则可能会想使用类似以下的子句:


   HAVING distance_in_km < 10.0    /* slow ! */

    ORDER BY distance_in_km DESC

那就是(正如我们在美国马萨诸塞州波士顿附近所说的)邪恶的缓慢。


在这种情况下,您需要使用边界框计算。请参阅此文章以了解有关操作方法。 http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/


该公式包含一个LEAST()函数。为什么?因为如果ACOS()函数的参数甚至稍微大于1,该函数就会引发错误。当所讨论的两个点非常靠近时,由于浮点epsilon(不精确,带有COS()和SIN()计算的表达式有时可能会产生大于1的值)。)。该呼叫与问题对应。LEAST(1.0, dirty-great-expression)


有一个更好的办法,一个公式通过撒迪厄斯·文森。它使用ATAN2()而不是ACOS()这样,因此不易受到epsilon问题的影响。


查看完整回答
反对 回复 2019-11-14
?
呼啦一阵风

这是MySQL查询和函数,用于获取两个纬度和经度之间的距离,距离将以KM返回。


MySQL查询:-


SELECT (6371 * acos( 

                cos( radians(lat2) ) 

              * cos( radians( lat1 ) ) 

              * cos( radians( lng1 ) - radians(lng2) ) 

              + sin( radians(lat2) ) 

              * sin( radians( lat1 ) )

                ) ) as distance from your_table

Mysql功能:-


DELIMITER $$

CREATE FUNCTION `getDistance`(`lat1` VARCHAR(200), `lng1` VARCHAR(200), `lat2` VARCHAR(200), `lng2` VARCHAR(200)) RETURNS varchar(10) CHARSET utf8

begin

declare distance varchar(10);


set distance = (select (6371 * acos( 

                cos( radians(lat2) ) 

              * cos( radians( lat1 ) ) 

              * cos( radians( lng1 ) - radians(lng2) ) 

              + sin( radians(lat2) ) 

              * sin( radians( lat1 ) )

                ) ) as distance); 


if(distance is null)

then

 return '';

else 

return distance;

end if;

end$$

DELIMITER ;

如何在您的PHP代码中使用


SELECT getDistance(lat1,lng1,$lat2,$lng2) as distance 

FROM your_table.


查看完整回答
反对 回复 2019-11-14
?
梵蒂冈之花

这是一个MySQL函数,它将采用两个纬度/经度对,并为您提供两点之间的距离(以度为单位)。它使用Haversine公式计算距离。由于地球不是一个完美的球体,因此在两极和赤道附近会出现一些误差。


要转换为英里,请乘以3961。

要转换为公里,请乘6373。

要转换为米,请乘以6373000。

要转换为英尺,请乘以(3961 * 5280)20914080。

DELIMITER $$


CREATE FUNCTION \`haversine\`(


        lat1 FLOAT, lon1 FLOAT,

        lat2 FLOAT, lon2 FLOAT

     ) RETURNS float

    NO SQL

    DETERMINISTIC

    COMMENT 'Returns the distance in degrees on the Earth between two known points of latitude and longitude. To get miles, multiply by 3961, and km by 6373'


BEGIN


    RETURN DEGREES(ACOS(

              COS(RADIANS(lat1)) *

              COS(RADIANS(lat2)) *

              COS(RADIANS(lon2) - RADIANS(lon1)) +

              SIN(RADIANS(lat1)) * SIN(RADIANS(lat2))

            ));


END;


DELIMITER;


查看完整回答
反对 回复 2019-11-14

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信