1. 程式人生 > >根據地圖座標查詢範圍內的商家資訊,查詢有1公里左右的誤差。

根據地圖座標查詢範圍內的商家資訊,查詢有1公里左右的誤差。

/**
     * 查詢當前定位位置5公里範圍內的商家資訊
     */
    public function findShop()
    {
            
        $point = $this -> returnSquarePoint($param['lng'], $param['lat'], 4);//計算經緯度的周圍某段距離的正方形的四個點
        #查詢條件組合
        $where = $this->queryParam($point);
        $query_params = [];
        $query_params
['_complex'] = $where; $query_params['closed'] = 0;//開啟的店鋪 $shop_list = D('Shop') -> field('shop_id,shop_name,addr,photo,lat,lng,tel,user_id,sign') -> where($query_params) -> select(); #高德地圖 $map = new Map(); $amap_config
= C('sdk.amap'); if(!$shop_list && $param['keyword']){ Log::write("未找到資訊,進入地區搜素"); #獲取當前定位的城市 $address = $map->findAddressByPoint($param['lng'].','.$param['lat'], $amap_config['key']); $address = json_decode($address,true
); $city = ''; if($address['status'] == 1){ $city = $address['regeocode']['addressComponent']['city']; } Log::write("獲得城市:".$city); #獲取地區的經緯度資訊 $ret = $map->findAddressByStr($param['keyword'], $amap_config['key'],$city); $ret = json_decode($ret,true); $geocodes = $ret['geocodes']; if(count($geocodes) < 1){ #未找到當前所在城市的地區資訊 -查全國 Log::write("搜尋全國****"); $ret = $map->findAddressByStr($param['keyword'], $amap_config['key'],''); $ret = json_decode($ret,true); $geocodes = $ret['geocodes']; if(count($geocodes) < 1){ $this -> response([]); } } $location = $geocodes[0]['location']; if(!empty($location)){ Log::write("獲得獲得搜尋的地區經緯度資訊:".$location); $ret_arr = explode(',', $location); $point1 = returnSquarePoint($ret_arr[0], $ret_arr[1], 4);//計算經緯度的周圍某段距離的正方形的四個點 4 #查詢條件組合 $where = []; $where = $this->queryParam($point1); $query_params = []; $query_params['_complex'] = $where; $query_params['closed'] = 0;//開啟的店鋪 $shop_list = D('Shop') -> field('shop_id,shop_name,addr,photo,lat,lng,tel,user_id,sign') -> where($query_params) -> select(); Log::write('最後的查詢:'.D('Shop')->getLastSql()); } } if(count($shop_list) > 0){ #計算距離 #主播狀態 $origin = $param['lng'].','.$param['lat']; foreach ($shop_list as $k => $v){ $shop_list[$k]['distance'] = getDistance($param['lat'],$param['lng'],$v['lat'],$v['lng']); } } $this -> response($shop_list); } /** * 拼接查詢條件 * @param $point array 地圖座標範圍陣列 */ public function queryParam($point){ $right_bottom_lat = $point['right_bottom']['lat']; //右下緯度 $right_bottom_lng = $point['right_bottom']['lng']; //右下經度 $right_top_lat = $point['right_top']['lat']; //右上緯度 $right_top_lng = $point['right_top']['lng']; //右上經度 $left_top_lat = $point['left_top']['lat']; //左上緯度 $left_top_lng = $point['left_top']['lng']; //左上經度 $left_bottom_lat = $point['left_bottom']['lat']; //左下緯度 $left_bottom_lng = $point['left_bottom']['lng']; //左下經度 #右下 大於經度小於緯度 $param[1]['lat'] = array('egt',$right_bottom_lat); $param[1]['lng'] = array('elt',$right_bottom_lng); #左上 大於緯度小於經度 $param[2]['lat'] = array('elt',$left_top_lat); $param[2]['lng'] = array('egt',$left_top_lng); #右上 小於經度小於緯度 $param[3]['lat'] = array('elt',$right_top_lat); $param[3]['lng'] = array('elt',$right_top_lng); #左下 大於經度大於緯度 $param[4]['lat'] = array('egt',$left_bottom_lat); $param[4]['lng'] = array('egt',$left_bottom_lng); return $param; } /** *@param lng float 經度 *@param lat float 緯度 *@param distance float 該點所在圓的半徑,該圓與此正方形內切,預設值為0.5千米 *@return array 正方形的四個點的經緯度座標 */ function returnSquarePoint($lng, $lat,$distance = 10) { $earthdata=6371;//地球半徑,平均半徑為6371km $dlng = 2 * asin(sin($distance / (2 * $earthdata)) / cos(deg2rad($lat))); $dlng = rad2deg($dlng); $dlat = $distance/$earthdata; $dlat = rad2deg($dlat); $arr=array( 'left_top'=>array('lat'=>$lat + $dlat,'lng'=>$lng-$dlng), 'right_top'=>array('lat'=>$lat + $dlat, 'lng'=>$lng + $dlng), 'left_bottom'=>array('lat'=>$lat - $dlat, 'lng'=>$lng - $dlng), 'right_bottom'=>array('lat'=>$lat - $dlat, 'lng'=>$lng + $dlng) ); return $arr; }