1. 程式人生 > >MySql中實現 按經緯度搜索附近的人,並按距離排序的簡單實現

MySql中實現 按經緯度搜索附近的人,並按距離排序的簡單實現

按經緯度搜索附近的人,並按距離排序的簡單實現

這是一種簡單的實現,資料量不大的情況下還是能滿足需求的,寫在這裡做一份記錄。當然也希望有其他更好的方案。

主要思路就是:先以自己的經緯度為中心,計算一定半徑內的方形經緯度邊界,然後用此方形經緯度邊界過濾使用者,並使用一個計算兩點經緯度之間距離的自定義資料庫函式計算距離,然後按計算得到的距離倒序

計算一定半徑內的方形經緯度

long raidus = 10000; //半徑10km
double lat = 23.155778; //當前緯度
double lon = 113.262744; //當前經度

Map<String, Object> param = new
HashMap<>(); param.put("lat", lat); param.put("lon", lon); private void loadGeoSquare(Map<String, Object> parm, double lat, double lon, long raidus){ Double latitude = lat; Double longitude = lon; // 赤道周長24901英里 1609是轉換成米的係數 Double degree = (24901 * 1609) / 360.0; double
raidusMile = raidus; Double dpmLat = 1 / degree; Double radiusLat = dpmLat * raidusMile; Double minLat = latitude - radiusLat; Double maxLat = latitude + radiusLat; Double mpdLng = degree * Math.cos(latitude * (Math.PI / 180)); Double dpmLng = 1 / mpdLng; Double radiusLng = dpmLng * raidusMile; Double minLng = longitude - radiusLng; Double maxLng = longitude + radiusLng; //return new double[] { minLat, minLng, maxLat, maxLng };
parm.put("minLat", minLat); parm.put("minLng", minLng); parm.put("maxLat", maxLat); parm.put("maxLng", maxLng); }

SQL計算

我用的Mybatis,當然SQL大家應該都能看懂

<select id="queryNearbyPage" resultType="AppUserNearby">
    SELECT id, avatar, nickname, sex, birthday, lovecode,
    ROUND(lat_lng_distance(#{lat}, #{lon}, lat, lon), 2) AS distance 
    FROM zan_user zuser 
    WHERE 
    <![CDATA[ AND lat > #{minLat} AND lat < #{maxLat} AND lon > #{minLng} AND lon < #{maxLng} ]]>
    ORDER BY distance ASC 
    LIMIT #{rowStart},#{rowEnd}
</select>

其中的 計算兩個經緯度之間距離的 資料庫函式,這裡也貼出來:

CREATE FUNCTION `lat_lng_distance` (lat1 FLOAT, lng1 FLOAT, lat2 FLOAT, lng2 FLOAT)
RETURNS FLOAT
DETERMINISTIC
BEGIN
    RETURN 6371 * 2 * ASIN(SQRT(
        POWER(SIN((lat1 - abs(lat2)) * pi()/180 / 2),
        2) + COS(lat1 * pi()/180 ) * COS(abs(lat2) *
        pi()/180) * POWER(SIN((lng1 - lng2) *
        pi()/180 / 2), 2) ));
END

--Returns the distance in kilometers, assuming a earth radius of 6,371 km.

總結

以上計算上的數學理論,我沒有深究,也是參看相關資料的。總感覺這種實現方式好搓。