這個功能應用的場合似乎不多,但之前幫某客戶做網站時,正好需要計算兩個地點的距離用來計算車資,至於要如何實現這個功能呢?

嗯...老實說一剛開始挺苦惱的,好在有萬能的Google。深入搜索後,得知要計算兩點之間的距離可以透過兩點的經緯度做計算。(學到了一課)


得知這個資訊後,接著下來就是想辦法獲取地址的經緯度與利用經緯度計算距離了。


獲取地址經緯度

這個部份我們利用google map 的 api 來實現,基本上很簡單只須向google map發起簡單的請求就可以得到了,連API KEY都不用申請。

更新內容(2019.05.02):

目前google map api 已經強制要求要API KEY,新版的使用方式,請參閱

google map api 地址轉換為經緯度(使用PHP)


<?php
/* 
 * 獲取地址經緯度 - 從google map
 */  
function getAddressLatLng($addr='')
{ 
   //向google map請求
   $geocode=file_get_contents('http://maps.google.com/maps/api/geocode/json?address='.$addr.'&sensor=false'); 
   
   $output= json_decode($geocode);
   
   //經度
   $longitude = $output->results[0]->geometry->location->lng;
   //緯度
   $latitude = $output->results[0]->geometry->location->lat;
   //返回資料
   return array('lng'=>$longitude,'lat'=>$latitude);
}

#使用方式
$data = getAddressLatLng('地址');

經緯度計算距離

使用上面的函數我們便可以知道兩點的地址分別的經緯度座標,接著下來我們在用計算公式去計算出兩點的距離。

下面的函式是從網路上蒐來的至於公式的原理我也不清楚,實際測試過是有效的,但與google map的距離還是有誤差,我想應該是這個公式算出來的是直線距離吧。

<?php
/** 
 * 計算兩點間的距離 
 * $lng1 第一組地址的經度
 * $lat1 第一組地址的緯度
 * $lng2 第二組地址的經度
 * $lat2 第二組地址的緯度
 */  
 function getdistance($lng1,$lat1,$lng2,$lat2){
   //將角度轉為弧度 
   $radLat1=deg2rad($lat1);  
   $radLat2=deg2rad($lat2); 
   $radLng1=deg2rad($lng1); 
   $radLng2=deg2rad($lng2); 
   $tmp1=$radLat1-$radLat2; 
   $tmp2=$radLng1-$radLng2;
   //計算公式 
   $d=2*asin(sqrt(pow(sin($tmp1/2),2)+cos($radLat1)*cos($radLat2)*pow(sin($tmp2/2),2)))*6378.137*1000; 
   //單位公尺
   return intval($d);
 }


利用這兩個函數,便能實現計算兩點間的距離了。 是不是很簡單,真的很簡單。(最近一直被這句洗腦...)


計算兩點距離實際範例

讓我們來實際試試看到底有沒有用吧!這邊簡單的示範台北市政府到台北101的距離。

<?php
   //台北市政府的地址
   $addr1 = "台北市信義區市府路1號";
   //台北101的地址
   $addr2 = "台北市信義路五段7號";
   
   //獲取台北市政府經緯度
   $geo1 = getAddressLatLng($addr1);
   //獲取台北101經緯度
   $geo2 = getAddressLatLng($addr2);   
   
   $lng1 = $geo1['lng'];
   $lat1 = $geo1['lat'];
   $lng2 = $geo2['lng'];
   $lat2 = $geo2['lat'];
   //計算距離
   $distance = getdistance($lng1,$lat1,$lng2,$lat2);
   //輸出結果 (單位公尺)
   echo $distance; //399m

  我們這邊算出來的距離是399m(直線距離),但實際上用google map 算出來是600m(步行距離),看來準確度真的是僅供參考=.=


注意事項

在使用 getAddressLatLng() 這個函數要特別注意到一點,因為它是向google map 請求的,所以請求頻率太高有時會被拒絕,因此建議將獲取到的經緯度資訊保存在資料庫。



文章轉載或引用,請先告知並保留原文出處與連結!!(單純分享或非營利的只需保留原文出處,不用告知)

原文連結:
https://blog.aidec.tw/post/calculate-address-distance-use-google-map-and-php