運用Google Map API(Distance Matrix Service)取得旅程時間及距離

icelandcheng
13 min readMar 12, 2020

--

有在使用Google map的人想必很常會用來預先參考要去的地方大概要花多久時間到達,或是尋找自己鄰近的餐廳或咖啡廳等等,Google map提供的搜尋最短路徑或是旅程預估等功能,真的超級好用,Google也提供了這些功能的API — Google Map Javascript API : Distance Matrix Service,只要利用Distance Matrix Service,就可以簡單地得到地點之間移動所需的旅程時間及距離,以下就簡單的說明Distance Matrix Service的使用。

首先,要使用Google Map Javascript API的服務必須先申請Google Map的API key,詳細流程可以點進去API key這個連結去查看,主要的申請方式其實就是有google 帳號可以直接到Google Cloud Platform上面去創立一個專案,點選至google 地圖頁面,選擇要開啟的Google Map API,我們要使用Distance Matrix Service的話,就要開啟Distance Matrix API,設定的頁面如下圖

在上方頁面設定要使用的API的同時,Google也會產生一組API key,這個key就是我們之後要用到的。

再來就是開始在我們的網頁程式中使用Distance Matrix Service了!先把剛剛拿到的API key 載入程式中, 載入方式為把下面這行程式碼放入html程式碼的body中,key=後面記得貼上自己的API key,library=後面要寫place,如果有要使用定位或是繪圖功能就還要再加上drawing或geometry,主要還是看需求決定要不要加

<script async defer 
src=”https://maps.googleapis.com/maps/api/js?key=Your API key&libraries=places,drawing,geometry&v=3&callback=initMap">
</script>

接下來組出發送要給DistanceMatrixService運算的參數,這邊先以兩地點步行的距離及時間舉例,就以下圖紅點作為起始位置,計算到藍點咖啡廳的結果做測試

起始點的坐標為(25.038935, 121.5018988),作為終點的咖啡廳坐標為(25.04081, 121.506566),所以在javascript程式碼中,要寫的程式碼大概如下

let service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [{lat: 25.038935, lng: 121.5018988}],
destinations: [{lat: 25.04081, lng: 121.506566}],
travelMode:
google.maps.TravelMode[WALKING],
unitSystem:
google.maps.UnitSystem.METRIC,
}, function(response, status) {
if (status !== google.maps.DistanceMatrixStatus.OK) {
window.alert('Error was' + status);
} else {
console.log(response);
}
});

第一行先new google.maps.DistanceMatrixService(),這樣後面才可以使用DistanceMatrixService(),再來就是組出我們要發送的參數,這邊我們主要傳了四個參數:origins、destinations、travelMode、unitSystem,參數的說明大致如下

origins(必傳):起點資訊,可以傳入一個地點或多個地點,傳的格式可以用經緯度、地址或者google.maps.Place的資訊,例如也可以傳 龍山寺。

destinations(必傳):終點資訊,跟起點依樣,可以傳入一個地點或多個地點,傳的格式可以用經緯度、地址或者google.maps.Place的資訊。

travelMode(選填):移動方式,除了傳送必填的起點、終點資訊,也可以設定移動的方式,包括:BICYCLING(腳踏車)、DRIVING(開車)、TRANSIT(轉運)、WALKING(走路)等四種,如果不傳送travelMode的話,DistanceMatrixService()就會預設是用DRIVING(開車)的方式移動,這邊比較特別的是TRANSIT,如果傳送這個設定,表示起點跟終點間是有轉運點的,像搭飛機會在某個地方轉機那樣,不會直接抵達終點,所以如果設定TRANSIT的話,還會需要另外傳送transitOptions參數,裡面可能包括:arrivalTime(抵達時間)、departureTime(出發時間)、modes(中繼點,有像是RAIL、SUBWAY、TRAIN等選項)、routingPreference(路徑偏好,可以設定FEWER_TRANSFERS、LESS_WALKING這種轉運方式的偏好),如果travelMode設定為DRIVINGDistanceMatrixService()提供使用者另外設定drivingOptions,使用者可以傳送departureTime(出發時間)及trafficModel(交通時間計算模式,有bestguess(最佳模式)、pessimistic(悲觀模式)、optimistic(樂觀模式)等三個模式來計算到達終點所需時間,預設值為bestguess,bestguess是用最貼近實際交通狀況來估計時間,pessimistic是用最糟的情況來預估時間而optimistic適用最好的情況來預估,所以一般情況,得到的時間長度應該是:pessimistic > bestguess > optimistic)。

unitSystem(選填):距離單位,有google.maps.UnitSystem.METRIC及google.maps.UnitSystem.IMPERIAL兩個選項,沒有傳送unitSystem參數的話,預設為METRIC,也就是公制,得到的距離單位會是公尺、公里,如果設定是IMPERIAL,回傳值的距離單位就會是英尺、英里。

除了上面這些範例中有用到參數,其實還有像是avoidHighways(避開高速公路)avoidTolls(避開收費站)等選項可以設定,如果行經的路徑可能會有經過高速公路或是收費站,就可以考路傳送這兩個參數設定。接下來是一些範例。

單一起點步行到達單一目的地

傳送的參數

{
origins: [{lat: 25.038935, lng: 121.5018988}],
destinations: [{lat: 25.04081, lng: 121.506566}],
travelMode: google.maps.TravelMode[WALKING],
unitSystem: google.maps.UnitSystem.METRIC,
}

得到的結果如下

{
destinationAddresses:
["No 205, Hanzhong Street,Wanhua District,TaipeiCity,Taiwan 108"],
originAddresses:
["No 131, Yongfu Street,Wanhua District,Taipei City,Taiwan 108"],
rows: [{
elements: [{
distance: {text: “0.6 km”, value: 636},
duration: {text: “8 mins”, value: 502},
status: “OK”,
}]
}]
}

可以看到會回傳有destinationAddresses(終點地址)、originAddresses(起點地址),然後比較重要的資訊會包在rows裡面,裡面會再包一層elements,然後才是我們想要的distance(距離)、duration(所需時間)等資訊,會有rows層然後裡面又包一層elements層,主要是為了多起點跟多終點的回傳值而設定,後面會舉例多起點多終點的例子做說明,從回傳值很清楚的看到,步行到終點所需的時間是8分鐘,距離大約是0.6公里,回傳值除了有傳送text: “0.6 km”這樣淺顯易懂的內容之外,還有回傳一個value: 636,value這邊都是原始值,distance的value單位就是公尺,而duration的單位就是秒。

單一起點步行到多個目的地

傳送參數像下面這樣

{
origins: [{lat: 25.038935, lng: 121.5018988}],
destinations:
[
{lat: 25.04081, lng: 121.506566},
{lat: 25.0418973, lng: 121.5047744}
],
travelMode: google.maps.TravelMode[WALKING],
unitSystem: google.maps.UnitSystem.METRIC,
}

得到的回傳結果如下

{
destinationAddresses:
[
"No. 205, Hanzhong Street,Wanhua District,TaipeiCity,Taiwan 108",
"No. 85, Guangzhou Street,Wanhua District,Taipei City,Taiwan 108" ],
originAddresses:
["No 131, Yongfu Street,Wanhua District,Taipei City,Taiwan 108"],
rows: [{
elements: [
{
distance: {text: “0.6 km”, value: 636},
duration: {text: “8 mins”, value: 502},

status: “OK”,
},
{
distance: {text: “0.4 km”, value: 447},
duration: {text: “6 mins”, value: 348},
status: “OK”,
}]
}]
}

可以看到,如果一開始傳送ㄧ個起點跟多個目的地,一個elements裡面就會包含多個回傳時間及距離的資訊,分別表示起點到各個目的地所需的時間及距離,所以從回傳值可以簡單的得知到兩個終點分別所需的時間跟距離,顯然第二個目的地比較快可以到達,而回傳的destinationAddresses(終點地址)也會將所有當初傳送的地點地址回傳。

多起點步行到多個目的地

傳送參數如下

{
origins: [
{lat: 25.038935, lng: 121.5018988},
{lat: 25.042325, lng: 121.505769}
],
destinations:
[
{lat: 25.04081, lng: 121.506566},
{lat: 25.0418973, lng: 121.5047744}
],
travelMode: google.maps.TravelMode[WALKING],
unitSystem: google.maps.UnitSystem.METRIC,
}

得到的回傳結果

{
destinationAddresses:
["No. 205, Hanzhong Street,Wanhua District,TaipeiCity,Taiwan 108",
"No. 85, Guangzhou Street,Wanhua District,Taipei City,Taiwan 108" ],
originAddresses:
["No 131, Yongfu Street,Wanhua District,Taipei City,Taiwan 108",
"No. 2, Lane 82,Xining South Road,Wanhua District,Taipei City, Taiwan 108"
],
rows: [{
elements: [
{
distance: {text: “0.6 km”, value: 636},
duration: {text: “8 mins”, value: 502},

status: “OK”,
},
{
distance: {text: “0.4 km”, value: 447},
duration: {text: “6 mins”, value: 348},
status: “OK”,
}],
elements: [
{
distance: {text: “0.3 km”, value: 266},
duration: {text: “4 mins”, value: 211},

status: “OK”,
},
{
distance: {text: “0.8 km”, value: 776},
duration: {text: “10 mins”, value: 619},
status: “OK”,
}]
}]
}

如果一開始傳送多個起點跟多個目的地,那rows裡面就會包含多個elements,一個elements裡面的回傳值表示特定起點到每個終點的回傳資訊,這樣除了比較一個起點到每個目的地的時間及距離外,也可以同時看到不同起點到同樣的目的地所需的時間及距離多遠。

整體來說,Distance Matrix Service真的提供了多元又簡單明瞭的傳送參數,來協助我們得到基本的旅程時間及距離資訊,可以做很多的運用,像是我本身剛好手邊有全台灣的咖啡廳地點資訊,就拿來實作了尋找鄰近咖啡廳的功能,而且利用了回傳資訊有到達目的地所需時間的資訊,還可以用時間作為篩選條件,找出鄰近五分鐘、十分鐘或十五分鐘內的咖啡廳(成果如下圖),真的是相當實用的service。

這篇文章介紹的內容,主要參考了Distance Matrix Service的線上API文件,Google寫得十分詳細,想做更深入的應用可以仔細閱讀,另外Google在Udacity有提供免費的Google Map API課程,內容有趣又有許多實際範例,上完真的可以運用Google Map API玩出很多很厲害的功能,有興趣的人可以參考看看。

參考資料:

Google Map Platform — Distance Matrix Service

Udacity 線上課程 — Google Map API

--

--

icelandcheng

Programming Skill learner and Sharer | Ruby on Rails | Golang | Vue.js | Web Map API