php根据经纬度排序,根据经纬度筛选距离段

SQL 语句:select location.* from (select *,round(6378.138*2*asin(sqrt(pow(sin( (36.668530*pi()/180-px_lat*pi()/180)/2),2)+cos(36.668530*pi()/180)*cos(px_lat*pi()/180)* pow(sin( (117.020359*pi()/180-px_lon*pi()/180)/2),2)))*1000)  as distance from bsx_training where (px_state = 1) and (type_id != ‘‘) and (((px_lat >= 27.683290277922) and (px_lat <= 45.653769722078)) and ((px_lon >= 105.81826766053) and (px_lon <= 128.22245033947))) order by  distance limit 0,10) location  where (1=1) and (location.distance <= 500)先忽略上面这条SQL语句。一一解释根据SQL排序的SQl语句
// lon1当前用户经度 lat1当前用户纬度,lon2 sql的经度字段 lat sql的纬度字段function distance_sql($lon1,$lat1,$lon2,$lat2)
{
    $sql = "round(6378.138*2*asin(sqrt(pow(sin( ({$lat1}*pi()/180-{$lat2}*pi()/180)/2),2)+cos({$lat1}*pi()/180)*cos({$lat2}*pi()/180)* pow(sin( ({$lon1}*pi()/180-{$lon2}*pi()/180)/2),2)))*1000) ";
     return $sql;
}

这是一个生成根据SQL排序函数代码

接下来下面是设置经纬度范围内的数据

if(I("post.location")){
            // 用户经纬度
            $location = explode(",",I("post.location"));
            $userLon = $location[0];
            $userLat = $location[1];
            // 经纬度筛选
            $location = getAround($userLat,$userLon,1000000);
            $wheres1.=" and (((px_lat >= {$location["minLat"]}) and (px_lat <= {$location[‘maxLat‘]})) and ((px_lon >= {$location[‘minLng‘]}) and (px_lon <= {$location[‘maxLng‘]})))";
             // 经纬度距离筛选
            if(I("post.distance_sort")){
                $distanceSql = ",".distance_sql($userLon,$userLat,"px_lon","px_lat")." as distance";
                $orderBy = " distance";
            }
            if(I("post.km")){
                $kmStr = htmlspecialchars_decode(I("post.km"));
                if(strpos($kmStr,"<") !== false){
                    $km = explode("<",$kmStr);
                    $wheres2 .= " and (location.distance <= {$km[1]})";
                }else if(strpos($kmStr,"-") !== false){
                    $km = explode("-",$kmStr);
                    $wheres2 .= " and ((location.distance >= {$km[0]}) and (location.distance <= {$km[1]}))";
                 }else if(strpos($kmStr,">") !== false){
                    $km = explode(">",$kmStr);
                    $wheres2 .= " and (location.distance >= {$km[1]})";
                }
            }
        }

下面算出经纬度范围内的数据控制函数

/**
 *
 * @param  $latitude    纬度
 * @param  $longitude    经度
 * @param  $raidus        半径范围(单位:米)
 * @return multitype:number
 */
function getAround($latitude,$longitude,$raidus)
{
    $PI = 3.14159265;
    $degree = (24901*1609)/360.0;
    $dpmLat = 1/$degree;
    $radiusLat = $dpmLat*$raidus;
    $minLat = $latitude - $radiusLat;
    $maxLat = $latitude + $radiusLat;
    $mpdLng = $degree*cos($latitude * ($PI/180));
    $dpmLng = 1 / $mpdLng;
    $radiusLng = $dpmLng*$raidus;
    $minLng = $longitude - $radiusLng;
    $maxLng = $longitude + $radiusLng;
    return array (minLat=>$minLat, maxLat=>$maxLat, minLng=>$minLng, maxLng=>$maxLng);
}

要实现根据经纬度排序

就直接调用distance_sql(lon1,lat1,lon2,lat2)传入参数 并且as 一个别名例如 as distance, 然后sql语句中 order by 排序 根据 distance排序

如果筛选距离段 1000米-2000米的数据

那就sql语句嵌套sql

select *.loation from (select *,round(6378.138*2*asin(sqrt(pow(sin( (36.668530*pi()/180-px_lat*pi()/180)/2),2)+cos(36.668530*pi()/180)*cos(px_lat*pi()/180)* pow(sin( (117.020359*pi()/180-px_lon*pi()/180)/2),2)))*1000) as distance) from table  location where (location.distance >= 1000) and (location.distance <= 2000))

如果实现根据最近位置排序sql

select *,round(6378.138*2*asin(sqrt(pow(sin( (36.668530*pi()/180-px_lat*pi()/180)/2),2)+cos(36.668530*pi()/180)*cos(px_lat*pi()/180)* pow(sin( (117.020359*pi()/180-px_lon*pi()/180)/2),2)))*1000) as distance order by distance

 public function training_list()
    {
        $wheres1 = "(px_state = 1)";
        $wheres2 = " where (1=1)";

        $orderBy = " px_id desc";
        if(I("post.location")){
            // 用户经纬度
            $location = explode(",",I("post.location"));
            $userLon = $location[0];
            $userLat = $location[1];
            // 经纬度筛选
            $location = getAround($userLat,$userLon,1000000);
            $wheres1.=" and (((px_lat >= {$location["minLat"]}) and (px_lat <= {$location[‘maxLat‘]})) and ((px_lon >= {$location[‘minLng‘]}) and (px_lon <= {$location[‘maxLng‘]})))";
             // 经纬度距离筛选
            if(I("post.distance_sort")){
                $distanceSql = ",".distance_sql($userLon,$userLat,"px_lon","px_lat")." as distance";
                $orderBy = " distance";
            }
            if(I("post.km")){
                $kmStr = htmlspecialchars_decode(I("post.km"));
                if(strpos($kmStr,"<") !== false){
                    $km = explode("<",$kmStr);
                    $wheres2 .= " and (location.distance <= {$km[1]})";
                }else if(strpos($kmStr,"-") !== false){
                    $km = explode("-",$kmStr);
                    $wheres2 .= " and ((location.distance >= {$km[0]}) and (location.distance <= {$km[1]}))";
                 }else if(strpos($kmStr,">") !== false){
                    $km = explode(">",$kmStr);
                    $wheres2 .= " and (location.distance >= {$km[1]})";
                }
            }
        }

      $showNum = 10;
        if(I("post.page")){
            $page = I("post.page");
        }else{
            $page = 1;
        }
        $n = ($page-1)*$showNum;
        $field = "*{$distanceSql}";
        $sql = "select location.* from (select {$field} from bsx_training where {$wheres1} order by {$orderBy} limit {$n},{$showNum}) location {$wheres2}";
        $training = M()->query($sql);

        dump(M()->getlastsql());die;

    }

原文地址:https://www.cnblogs.com/liuxinruif0/p/9264343.html

时间: 2024-10-29 10:05:06

php根据经纬度排序,根据经纬度筛选距离段的相关文章

java------4.根据经纬度排序,并计算距离。。。。。。。。根据地址计算出经纬度

1 String sql = "select xm.*,xs.*,xs.id as shopId,sqrt ( ( (( " + customerLongitude 2 + "-xs.longitude)*PI()*12656*COS(((" + customerLatitude 3 + "+xs.latitude)/2)*PI()/180)/180)" + "*" + "(( " 4 + customer

根据经纬度计算两点间的距离

地球是一个近乎标准的椭球体,它的赤道半径为6378.140千米,极半径为 6356.755千米,平均半径6371.004千米.如果我们假设地球是一个完美的球体,那么它的半径就是地球的平均半径,记为R.如果以0度经线为基 准,那么根据地球表面任意两点的经纬度就可以计算出这两点间的地表距离(这里忽略地球表面地形对计算带来的误差,仅仅是理论上的估算值).设第一点A的经 纬度为(LonA, LatA),第二点B的经纬度为(LonB, LatB),按照0度经线的基准,东经取经度的正值(Longitude)

sql server2008根据经纬度计算两点之间的距离

--通过经纬度计算两点之间的距离 create FUNCTION [dbo].[fnGetDistanceNew] --LatBegin 开始经度 --LngBegin 开始维度 --29.490295,106.486654,29.615467, 106.581515 (@LatBegin1 varchar(128), @LngBegin1 varchar(128),@location varchar(128)) Returns real AS BEGIN --转换location字段,防止字段

获取经纬度之间两点间真实距离(适用于GoogleMap,BaiduMap,Amap等)

如何获取经纬度之间两点间真实距离(适用于GoogleMap,BaiduMap,Amap等) 目标:使用百度定位sdk开发实时移动距离计算功能,根据经纬度的定位,计算行驶公里数并实时刷新界面显示.大家都知道定位有三种方式:GPS .Wifi . 基站 .误差方面的话,使用GPS误差在10左右,Wifi则在20 - 300左右 ,而使用基站则误差在100 - 300左右的样子,因为在室内GPS是定位不到的,必须在室外,而我们项目的需求正好需要使用GPS定位,所以我们这里设置GPS优先.车,不可能在室

经纬度互换、换算成米、两点的经纬度计算两点间的距离

GPS坐标和经纬度的算法和概率不太一样,但是我们可能会将他们互通起来用,下面先贴上转换工具:http://map.yanue.net/gps.html.里面实现了gps到谷歌地图百度地图经纬度的转换.不含糊,下面将他们之间的联系. GPS坐标系我本身不太了解它跟谷歌地图经纬度有多大区别,于是搜了一下,看看他们的区别: 地形图坐标系:我国的地形图采用高斯-克吕格平面直角坐标系.在该坐标系中,横轴:赤道,用Y表示:纵轴:中央经线,用X表示:坐标原点:中央经线与赤道的交点,用0表示.赤道以南为负,以北

ios系统经纬度转百度经纬度及经纬度转地址

正在进行的项目中有这样的需求:定位获得当前经纬度,再用百度Place API使用经纬度查询周边信息.这里不需要显示地图,只需要定位.看似思路很顺畅,做起来却不容易. iPhone的GPS定位(CLLocationManager)获得的经纬坐标是基于WGS-84坐标系(世界标准),Google地图使用的是GCJ-02坐标系(中国特色的火星坐标系),这就是为什么获得的经纬坐标在google地图上会发生偏移.我项目需求是使用百度Place API,百度的经纬坐标在GCJ-02的基础上再做了次加密,就是

sql 排序 分组 层级 筛选 - God聚会啊

前言: 以前做过2种列表,1是有排序,有筛选功能,但是没有层级和分组,2是有树形结构的层级和分组,但是数据是一下全部加载出来,虽然有点落后,没有用到分页加载,但是也是受制于大环境. 今天有1个需求是 分组 排序 筛选 层级, 一开始没有想到好办法,后来才知道可以order by 按组排序. 核心思想: 表中有2个字段,层级level, id, parentid,这里就是先把过滤好的数据的id和parentid形成1个集合,在原有的数据表中查找这个集合对应的数据,再额外多做2个字段(本次需求是这样

百度经纬度和google经纬度互转

百度地图的坐标转换,由于百度地图在GCJ02协议的基础上又做了一次处理,变为 BD09协议的坐标,以下是坐标的转化方式,可以方便和其他平台转化 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 private const double x_pi = 3.14159265358979324 * 3000.0 / 180.0; /// <summary> /// 中国正常坐标系GCJ02协议的坐标,转

订餐系统之按距离[根据经纬度]排序、搜索

上周六,写了第一篇博客<订餐系统之权限设计>,在此感谢那些鼓励.关注我的园友们,更要感谢那些提出宝贵建议的朋友们.看了你们的评论,才真切的感受到:朋友们的评论往往会让文章更有看点.上篇文章中 郑明.人生就是赌 等几个园友的留言让我对我们系统的权限优化有了方向.当然,这样的优化肯定不是一天两天的事,做技术的朋友应该都知道:一个难题经常啃啃,某天也许就有了好的方案了(近段时间啃掉了几个2.3年前未处理好的的问题,才想起初中数学老师让我们经常啃一些竞赛题的良苦用心),今天的文章说的就是一个从2010