PHP|店铺经纬度计算距离然后分页排序

根据经纬度计算距离,根据距离排序或者是根据店铺销量排序
【PHP|店铺经纬度计算距离然后分页排序】代码如下

['type'=>'string', 'valid'=>'', 'default'=>'', 'msg'=>'分类', 'example'=>'', 'description'=>''], 'search'=> ['type'=>'string', 'valid'=>'', 'default'=>'', 'msg'=>'', 'example'=>'', 'description'=>''], 'fans'=> ['type'=>'string', 'valid'=>'', 'default'=>'', 'msg'=>'', 'example'=>'', 'description'=>''], 'sort'=> ['type'=>'string', 'valid'=>'', 'default'=>'', 'msg'=>'', 'example'=>'', 'description'=>''], 'page_no'=> ['type'=>'string', 'valid'=>'', 'default'=>'', 'msg'=>'', 'example'=>'', 'description'=>''], 'page_size'=> ['type'=>'string', 'valid'=>'', 'default'=>'', 'msg'=>'', 'example'=>'', 'description'=>''], 'longitude'=> ['type'=>'string', 'valid'=>'required', 'default'=>'', 'msg'=>'经度必传', 'example'=>'', 'description'=>''], 'latitude'=> ['type'=>'string', 'valid'=>'required', 'default'=>'', 'msg'=>'纬度必传', 'example'=>'', 'description'=>''], ]; }public function handle($params) {//分页使用 $pageSize = $params['page_size'] ? $params['page_size'] : 10; $pageNo = $params['page_no'] ? $params['page_no'] : 1; $start =($pageNo-1) * $pageSize; ##搜索 $where = "status = 'active'"; if(!empty($params['search'])){ $where = $where . " and (shop_name like '%".$params['search']."%' or mobile like '".$params['search']."%')" ; }##分类 if($params['cat_id']){ $params['cat_id'] = intval($params['cat_id']); $setting = app::get('sysshop')->model('shop_rel_lv1cat')->getList("*",['cat_id'=>$params['cat_id']]); if(empty($setting)){ $data['shop_list'] = array(); return $data; } $select_shop = array_column($setting,'shop_id'); $ids = implode(',',$select_shop); $where = $where. " and shop_id in ($ids)"; }##排序 if($params['sort'] == 0){ ##降序 $order = 'fansnum'; $by = 'desc'; }elseif($params['sort'] == 1){ ##升序 $order = 'distance'; $by = 'asc'; }else{ $order = 'shop_id'; $by = 'desc'; }##看看是否可以在sql语句中计算距离然后排序分页,但是有一个问题 ##即,那些没有经纬度的店铺总是排序到最前面 ##待解决 数据库经纬度字段默认为0 $qb = app::get('sysshop')->database()->createQueryBuilder(); $data['shop_list'] = $qb->select("shop_id,shop_name,seller_id,shop_logo,shop_area,shop_addr,goodsnum,fansnum,longitude,latitude,is_recommend, (round(6367000 * 2 * asin(sqrt(pow(sin(((latitude * pi()) / 180 - ({$params['latitude']} * pi()) / 180) / 2), 2) + cos(({$params['latitude']} * pi()) / 180) * cos((latitude * pi()) / 180) * pow(sin(((longitude * pi()) / 180 - ({$params['longitude']} * pi()) / 180) / 2), 2))))) AS distance ") ->from('sysshop_shop') ->where("{$where}") ->setFirstResult($start)->setMaxResults($pageSize) ->orderBy($order,$by) ->execute() ->fetchAll(); foreach ($data['shop_list'] as $key=>$value){ if($value['longitude'] == 0 &&$value['latitude'] == 0){ $data['shop_list'][$key]['distance'] = ''; }}return $data; }/* * 1.纬度1,经度1,纬度2,经度2 * 2.返回结果是单位是KM。 * 3.保留一位小数 */ function getDistance($lat1,$lng1,$lat2,$lng2) { //将角度转为狐度 $radLat1 = deg2rad($lat1); //deg2rad()函数将角度转换为弧度 $radLat2 = deg2rad($lat2); $radLng1 = deg2rad($lng1); $radLng2 = deg2rad($lng2); $a = $radLat1 - $radLat2; $b = $radLng1 - $radLng2; $s = 2*asin(sqrt(pow(sin($a/2),2)+cos($radLat1)*cos($radLat2)*pow(sin($b/2),2)))*6371; return round($s,1); }##另外一种距离分页计算排序 publicfunction otherDistance($where,$params,$start,$pageSize){$qb = app::get('sysshop')->database()->createQueryBuilder(); $data['shop_list'] = $qb->select("shop_id,shop_name,seller_id,shop_logo,shop_area,shop_addr,goodsnum,fansnum,longitude,latitude,is_recommend ") ->from('sysshop_shop') ->where("{$where}") ->execute() ->fetchAll(); ##距离计算 if($params['sort'] ==1&& $params['longitude']){ foreach ($data['shop_list'] as $key=>$value){ if($value['longitude']){$data['shop_list'][$key]['distance'] = $this->getDistance($params['latitude'],$params['longitude'],$value['latitude'],$value['longitude']); }else{ ##为了没有经纬度的时候排序到最后 $data['shop_list'][$key]['distance'] = 1000000000; } } }##排序 if($params['sort'] == 0){ ##降序 $order = 'fansnum'; $key = array_column($data['shop_list'],$order); array_multisort($key,SORT_DESC,$data['shop_list']); }elseif($params['sort'] == 1){ ##升序 $order = 'distance'; $key = array_column($data['shop_list'],$order); array_multisort($key,SORT_ASC,$data['shop_list']); }##把之前的添加数据置为空 foreach ($data['shop_list'] as $key=>$value){ if($value['distance'] == 1000000000){ $data['shop_list'][$key]['distance'] = ''; } }##分页 $data['shop_list'] = array_slice($data['shop_list'], $start, $pageSize); return $data; }}

    推荐阅读