本篇會寫兩個用google maps api會遇到的狀況,就是目前使用者的所在位置,以及所在位置到目的地的距離。
本篇大綱
目前所在位置
抓使用者目前所在位置,用的是瀏覽器本身的geolocation。
在使用navigator.geolocation時,有2個步驟:
- 確認使用者的裝置支援navigator.geolocation
- 跟使用者要索取目前位置的權限
確認支援geolocation
程式碼如下:
if(navigator.geolocation) {
// 執行要權限的function
} else {
alert('Sorry, 你的裝置不支援地理位置功能。')
}
跟使用者要位置的權限
基本上所在位置是隱私的一部份,所以要拿使用者所在位置時,各瀏覽器一定會在使用者允許的狀態下才執行。
會跟使用者要權限的狀況,我們一般在操作google map的頁面或APP時就會看到,像這樣:

要注意的是,要位置資訊權限的部份,只能在https下執行,如果網址是http就無法。
要位置權限的code在MDN:地理位置定位 (Geolocation)這邊就寫的很完整了,本篇這段就做個簡單的整理:
當使用者允許後,回傳的資料如下:

latitude、longitude,這2個值就是經緯度。
計算到各點距離 Distance Matrix Service
計算一個點到其它點的距離,在Google Maps API上的功能就叫Distance Matrix Service。
這是廣告,點擊一下可以幫本站多個一點點的廣告收入,謝謝
要使用Distance Matrix Service,必須先到GCP上開啟API的權限。
開啟權限
進到 Google Cloud Platform Console 的頁面,接著選取要開通Distance Matrix API權限的專案,就會看見後台介面的上面有一個「啟用API和服務」,點下去後會進到Google API的頁面:


在搜尋框中搜尋 Distance Matrix API,就會看見有一項結果:

按下後,進到Distance Matrix API的介紹頁面,再按下「啟用」:

啟用後,就可以使用Distance Matrix API了。
Distance Matrix API限制
Google Maps API每月有200美金的額度,超過後就會收費,用多少算多少。
一些限制在官方文件中有提到,比較要注意的是這點:
Maximum of 25 origins and 25 destinations per server-side request
Pricing and policies
根據本人實際使用的經驗,這句白話就是,每call一次API去計算一個點到其它點的距離時,最多就是計算25個點的距離,超過25個點就會失敗。
使用Distance Matrix API
以下官方文件上的範例:
這是廣告,點擊一下可以幫本站多個一點點的廣告收入,謝謝
這邊說明一下參數的意思,下一段會示範從使用者所在地,去計算與其它點的距離當實際範例。
origins
就是起點,原始點,用起點去抓與destinations那些點的距離,下一段的範例中就會是使用者的所在地點。
destinations
要計算距離的點,下一段的範例中會先設好市政府附近的5個點,然後抓與所在地的距離。
travelMode
交通方式,不同的交通方式會回傳不同的所需時間,有以下4個值:
- DRIVING 開車,預設值
- BICYCLING 自行車
- TRANSIT 大眾運輸
- WALKING 走路
unitSystem
計算距離的單位,有以下2個值:
- METRIC 公里,預設值
- IMPERIAL 哩
avoidHighways、avoidTolls
是否避開高速公路、是否避開收費路線
API回傳的值
Distance Matrix API在callback會回傳的資料如下:

rows是一個陣列,origins裡有幾個值,rows就會有幾個。API會把origins裡的地點一個個去跟destinations陣列裡的每一個地點去計算距離。
跟每一個地點的距離,會回傳距離、到達所需時間。還很貼心的分成數值跟文字,這樣在排列的時候,就可以用距離/時間去排列。
實際應用:所在地與其它地點的距離
本篇接下來會寫一個範例,就是跟使用者要完所在地的經緯度後,呼API去計算市府附近5個地點的距離,最後會附上原始碼的網址。
跟使用者要所在地的經緯度,前面幾段就寫好了,這邊接著寫要完經緯度後做的事。
首先,就是把所在地經緯度設成origins:
let originPosition = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
接著,把設定好的5個地點,他們的經緯度push進destinations裡:
// 5個地點的資料在features裡
let destinations = [];
Array.prototype.forEach.call(features, f => {
destinations.push(new google.maps.LatLng(f.geometry.coordinates[0], f.geometry.coordinates[1]));
});
API的callback,就是把收回來的資料,依序塞進5個點的資料中:
function callback(response, status) {
for(let i = 0, len = features.length; i < len; i++) {
features[i].properties.distance = response.rows[0].elements[i].distance.value;
features[i].properties.distance_text = response.rows[0].elements[i].distance.text;
features[i].properties.distance_time = response.rows[0].elements[i].duration.text;
}
}
最後把features的5個地點資料,再按照距離排序就行了:
features = features.sort((a, b) => {
return a.properties.distance > b.properties.distance ? 1 : -1;
});
本篇配合Vue.js,加上Bootstrap的UI,完成後看到的截圖如下:

範例的原始碼也放在Github上了,歡迎取用:
https://github.com/letswritetw/letswrite-google-map-api-5
Google Maps API學習筆記系列

