一般來說 我們通常見到的經緯度計算時兩點之間的直線距離 隨着app對接地圖,公眾號小程序等對接地圖插件,直接顯示的是駕車或者騎車的曲線距離,所以兩者無法等同需要注意
一下提供兩種直線距離的寫法
調取前請先注意一下問題
經度 longitude
緯度 latitude
數據調用不出來或者距離不對 先考慮是不是經緯度寫反了喔
1 公共方法調用
1 /** 2 * 計算兩點地理坐標之間的距離 3 * @param Decimal $longitude1 起點經度 4 * @param Decimal $latitude1 起點緯度 5 * @param Decimal $longitude2 終點經度 6 * @param Decimal $latitude2 終點緯度 7 * @param Int $unit 單位 1:米 2:公里 8 * @param Int $decimal 精度 保留小數位數 9 * @return Decimal 10 */ 11 12 function getDistance($longitude1, $latitude1, $longitude2, $latitude2, $unit=1, $decimal=2){ 13 $EARTH_RADIUS = 6370.996; // 地球半徑系數 14 $PI = 3.1415926; 15 $radLat1 = $latitude1 * $PI / 180.0; 16 $radLat2 = $latitude2 * $PI / 180.0; 17 $radLng1 = $longitude1 * $PI / 180.0; 18 $radLng2 = $longitude2 * $PI /180.0; 19 $a = $radLat1 - $radLat2; 20 $b = $radLng1 - $radLng2; 21 $distance = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2),2))); 22 $distance = $distance * $EARTH_RADIUS * 1000; 23 if($unit==2){ 24 $distance = $distance / 1000; 25 } 26 return round($distance, $decimal); 27 }
公共方法調用2
1 function getdistance2($lng1,$lat1,$lng2,$lat2){ 2 //將角度轉為狐度 3 $radLat1=deg2rad($lat1);//deg2rad()函數將角度轉換為弧度 4 $radLat2=deg2rad($lat2); 5 $radLng1=deg2rad($lng1); 6 $radLng2=deg2rad($lng2); 7 $a=$radLat1-$radLat2; 8 $b=$radLng1-$radLng2; 9 $s=2*asin(sqrt(pow(sin($a/2),2)+cos($radLat1)*cos($radLat2)*pow(sin($b/2),2)))*6378.137*1000; 10 return $s; 11 }
2 分頁顯示距離遠近數據
1 public function list(){ 2 $data = $this->request->param(); 3 $page=$data['page']; 4 $where['status']= 1; 5 6 $lat=$data['lat']; 7 $lng=$data['lng']; 8 9 $order='mi asc'; 10 $list= StoreApply::field("*,ROUND(6378.138*2*ASIN(SQRT(POW(SIN(({$lat}*PI()/180-lng*PI()/180)/2),2)+COS({$lat}*PI()/180)*COS(lng*PI()/180)*POW(SIN(({$lng}*PI()/180-lat*PI()/180)/2),2)))*1000) as mi") 11 ->where($where) 12 ->order($order) 13 ->page($page,16) 14 ->select(); 15 16 $this->success('請求成功',compact('list')); 17 }
關於sql語句,如果看不懂的 也可以直接以下方sql帶入
1 ROUND(6370.996 * 2 * ASIN(SQRT(POW(SIN(($latitude * PI() / 180 - latitude * PI() / 180) / 2),2) + COS($latitude * PI() / 180) * COS(latitude * PI() / 180) * POW(SIN(($longitude * PI() / 180 - longitude * PI() / 180) / 2),2))) * 1000) AS mi
有興趣的可以直接研究下自定義的函數與上面這個sql語句的帶入關系
以上兩種形式的算法有輕微差別 大差不差
另外涉及方法
1 /* 2 * 獲取當前位置附近N范圍 3 * */ 4 5 function SquarePoint($lng, $lat,$distance = 5){ 6 $dlng = 2 * asin(sin($distance / (2 * 6371)) / cos(deg2rad($lat))); 7 $dlng = rad2deg($dlng); 8 $dlat = $distance/6371; 9 $dlat = rad2deg($dlat); 10 return array( 11 'left-top'=>array('lat'=>$lat + $dlat,'lng'=>$lng-$dlng), 12 'right-top'=>array('lat'=>$lat + $dlat, 'lng'=>$lng + $dlng), 13 'left-bottom'=>array('lat'=>$lat - $dlat, 'lng'=>$lng - $dlng), 14 'right-bottom'=>array('lat'=>$lat - $dlat, 'lng'=>$lng + $dlng) 15 ); 16 }