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;
}}
推荐阅读
- thinkphp|thinkphp 3.2 如何调用第三方类库
- CGI,FastCGI,PHP-CGI与PHP-FPM
- PHP开发-Mac搭建ThinkPHP5.0
- 依赖注入模块
- thinkphp3.2下实现阿里云视频点播实例(客户端JavaScript上传)
- php异常处理
- Arcgis根据经纬度批量提取属性值
- mac|mac php5.6+mongdb+Apache环境配置
- PHP简易规则引擎
- PHP|PHP 扩展开发检测清单(扩展开发必读)