js 根据经纬度算距离及查询范围内的数据

日期: 2018-07-30         浏览量: 2808

项目需求,要根据用户经纬度计算之间距离整理:


1. sql 查询  2000米之内的宝贝信息



let sql = `SELECT b.user_id, c.id as cowry_id, c.type, c.latitude, c.longitude, u.nickname, u.avatar, u.uuid,    
    (    
        convert(
            6371 * acos (    
                cos ( radians(:latitude) )    
                * cos( radians( c.latitude ) )    
                * cos( radians( c.longitude ) - radians(:longitude) )    
                + sin ( radians(:latitude) )    
                * sin( radians( c.latitude ) )    
            ), decimal(10,2)
        )
    ) AS distance    
    FROM cowry as c
    left join cowryBuryUser as b on c.id = b.cowry_id   
    left join user as u on b.user_id = u.id
    WHERE c.type = :type
    AND c.status = 0
    HAVING distance < 2    //小于 2000 米 内的数据
    ORDER BY distance   
    LIMIT 0 , 20;`
    let res = await Sequelize.query(sql, {
        replacements: {
            latitude: latitude,
            longitude: longitude,
            user_id: user_id,
            type: type
        },
        type: Sequelize.QueryTypes.SELECT
    })



2. 计算两个经纬度之间的距离 



exports.getDistance = function (lat1, lng1, lat2, lng2) {
    if (isNaN(lat1) || isNaN(lng1) || isNaN(lat2) || isNaN(lng2) || lat1 == null || lng1 == null || lat2 == null || lng2 == null) {
       return '未知'
    }
    let EARTH_RADIUS = 6378.137
    let radLat1 = lat1 * Math.PI / 180.0  // 角度转弧度
    let radLat2 = lat2 * Math.PI / 180.0
    let latDistance = radLat1 - radLat2
    let lngDistance = (lng1 * Math.PI / 180.0) - (lng2 * Math.PI / 180.0)
    // 反正弦+余弦
    let distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(latDistance / 2), 2) +
        Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(lngDistance / 2), 2)))
    distance = distance * EARTH_RADIUS
    distance = Math.round(distance * 1000)  //米
    return distance
}


3. 根据某一个经纬度获取范围内的最大最小经纬度范围




/***  
* 根据当前经纬度获取一定范围内的两个经纬度值 经纬度最大或最小  
* @param meter     范围 千米  
* @param lng       经度  
* @param lat       纬度  
* @returns {{maxLat: string, minLat: string, maxLng: string, minLng: string}}  
*/
exports.getLaLon = function (meter, lng, lat) {
    let EARTH_RADIUS = 6378.137
    let range = 180 / Math.PI * meter / EARTH_RADIUS  //这里计算出来是千米
    let lngR = range / Math.cos(lat * Math.PI / 180)
    let maxLat = parseFloat(lat) + range; //最大纬度
    let minLat = parseFloat(lat) - range;  //最小纬度
    let maxLng = parseFloat(lng) + lngR;   //最大经度
    let minLng = parseFloat(lng) - lngR;   //最小经度
    return {
        maxLat: maxLat.toFixed(7),
        minLat: minLat.toFixed(7),
        maxLng: maxLng.toFixed(7),
        minLng: minLng.toFixed(7)
    }
}