距离计算与MySQL在存经纬度的数据库查询最近距离的应用

应用:前端页面由百度或腾讯api获取当前地理位置坐标,传到服务器,获取距离当前位置最近的店铺或楼盘(店铺或楼盘地理坐标后台已添加存入数据库);
/**
 * 计算两点地理坐标之间的距离
 * @param  Decimal $longitude1 起点经度
 * @param  Decimal $latitude1  起点纬度
 * @param  Decimal $longitude2 终点经度 
 * @param  Decimal $latitude2  终点纬度
 * @param  Int     $unit       单位 1:米 2:公里
 * @param  Int     $decimal    精度 保留小数位数
 * @return Decimal
 */
function getDistance($longitude1, $latitude1, $longitude2, $latitude2, $unit=2, $decimal=2){

    $EARTH_RADIUS = 6370.996; // 地球半径系数
    $PI = 3.1415926;

    $radLat1 = $latitude1 * $PI / 180.0;
    $radLat2 = $latitude2 * $PI / 180.0;

    $radLng1 = $longitude1 * $PI / 180.0;
    $radLng2 = $longitude2 * $PI /180.0;

    $a = $radLat1 - $radLat2;
    $b = $radLng1 - $radLng2;

    $distance = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2),2)));
    $distance = $distance * $EARTH_RADIUS * 1000;

    if($unit==2){
        $distance = $distance / 1000;
    }

    return round($distance, $decimal);
}

//mysql:
//MySQL在存经纬度的数据库查询最近距离的应用

/**
*根据距离查询
*sql语句查询经纬度范围
*longitude为数据表经度字段 
*latitude为数据表纬度字段
*对于经度和纬度大于或小于该用户1度(111公里)范围内的用户进行距离计算
*公式:r*arccos[cos(y1)*cos(y2)*cos(x1-x2)+sin(y1)*sin(y2)],  r是地球半径6370km,x是经度,y是纬度
*$sql='select * from users_location where latitude > '.$lat.'-1 and latitude < '.$lat.'+1 and longitude > '.$lon.'-1 and longitude < '.$lon.'+1 order by ACOS(SIN(('.$lat.' * 3.1415) / 180 ) *SIN((latitude * 3.1415) / 180 ) +COS(('.$lat.' * 3.1415) / 180 ) * COS((latitude * 3.1415) / 180 ) *COS(('.$lon.'* 3.1415) / 180 - (longitude * 3.1415) / 180 ) ) * 6380 asc limit 10';
*/
    public function destence($lng,$lat,$filter){
        
        $where = $this->where($filter);
        $sql='select * from '. $this->table($this->_table).' where  '.$where.'and lat > '.$lat.'-1 and lat < '.$lat.'+1 and lng > '.$lng.'-1 and lng < '.$lng.'+1 order by ACOS(SIN(('.$lat.' * 3.1415) / 180 ) *SIN((lat * 3.1415) / 180 ) +COS(('.$lat.' * 3.1415) / 180 ) * COS((lat * 3.1415) / 180 ) *COS(('.$lng.'* 3.1415) / 180 - (lng * 3.1415) / 180 ) ) * 6380 asc limit 4'; 
        $rs = $this->db->query($sql);
        if($rs = $this->db->query($sql)){
            while($row = $rs->fetch()){
                $items[] = $row;
            }
            
        }
        // error_log(date('Y-m-d H:i:s',time()).PHP_EOL.json_encode($sql).PHP_EOL.$sql.PHP_EOL,3,'sql.log');
        return $items;

    } 

/**
*ajax上传坐标到后台,查询出结果,返回前台,更新结果
*后台ajax查询echo $json ;exit;------一定记得加断点!!!
*前台
    ,通过id更新显示结果 **/ $.ajax({ type:"post", url:"<{link ctl='mobile/index:ajax'}>", async:true, dataType:"json",//结果返回json data:{"pointX":r.point.lng,"pointY":r.point.lat}, success:function(result){    var site = eval(result);//解析json var html=''; $("#it").empty(); for(var i=0;i' >

    "+site[i].title+"

    "; } $("#it").append(html); }, error:function(){ alert("获取定位失败"); } }) /** *ajax上传后获取到数据。但是返回时走error:function(){}; *原因 ****1、datatype不对应;---修改datatype类型 ****2、报错:XMLHttpRequest cannot load http://myezhu.com/mobile/index-ajax.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://meiyijia.244.edong1000.com' is therefore not allowed access.--- (1)在请求控制器加上header("Access-Control-Allow-Origin: *"); (2)被请求页面加上下面代码,最好content填写域名,; (3)var url='http://localhost:8080/WorkGroupManagment/open/getGroupById" +"?id=1&callback=?'; $.ajax({ url:url, dataType:'jsonp', processData: false, type:'get', success:function(data){ alert(data.name); }, error:function(XMLHttpRequest, textStatus, errorThrown) { alert(XMLHttpRequest.status); alert(XMLHttpRequest.readyState); alert(textStatus); }}); (4)var url="http://localhost:8080/WorkGroupManagment/open/getGroupById" +"?id=1&callback=?"; $.jsonp({ "url": url, "success": function(data) { $("#current-group").text("当前工作组:"+data.result.name); }, "error": function(d,msg) { alert("Could not find user "+msg); } }); **/

    你可能感兴趣的:(php)