本文章地址:https://wutong.me/2018/07/08/lbs-nea-sort.html 转载请注明出处

在开发中可能会遇到根据经纬度来检索附近的XX情况,范围检索可以直接算出上下左右的边界并进行检索,如果要按照远近程度进行排序,则需要进行换算。

解决方式

创建自定义函数,排序的时候根据自定义函数算出的距离来进行升降排序

创建函数

执行如下SQL来创建一个获取距离的自定义函数。

DROP FUNCTION IF EXISTS point_distance;
DELIMITER //
CREATE FUNCTION `point_distance`(
    `lng1` float(9,6) ,
    `lat1` float(9,6),
    `lng2` float(9,6) ,
    `lat2` float(9,6)
) RETURNS MEDIUMINT
    COMMENT '计算两个坐标点之间的距离'
BEGIN
    declare distance MEDIUMINT;
    declare radius MEDIUMINT;
    -- 地球半径
    set radius = 6370856;
    -- 距离(米)
    set distance = (2*ATAN2(SQRT(SIN((lat1-lat2)*PI()/180/2)
        *SIN((lat1-lat2)*PI()/180/2)+
        COS(lat2*PI()/180)*COS(lat1*PI()/180)
        *SIN((lng1-lng2)*PI()/180/2)
        *SIN((lng1-lng2)*PI()/180/2)),
        SQRT(1-SIN((lat1-lat2)*PI()/180/2)
        *SIN((lat1-lat2)*PI()/180/2)
        +COS(lat2*PI()/180)*COS(lat1*PI()/180)
        *SIN((lng1-lng2)*PI()/180/2)
        *SIN((lng1-lng2)*PI()/180/2))))*radius;
    return distance;
END//
DELIMITER ;

业务实现

查找门店并按照离我的位置由近到远排列

SELECT 
    `name`,point_distance(当前经度,当前纬度,表里的经度,表里的纬度) AS distance
FROM shop ORDER BY  distance ASC;

结果:

+----+------------+-----------+-----------------+----------+
| id | longitude  | latitude  | name            | distance |
+----+------------+-----------+-----------------+----------+
|  1 | 120.275731 | 31.548376 | 体育中心店      |      795 |
|  2 | 120.292145 | 31.567969 | 开源大桥        |     2315 |
|  3 | 120.373998 | 31.507401 | 创新园          |     9656 |
+----+------------+-----------+-----------------+----------+