Google Maps API 學習筆記 – 5:抓目前位置、計算到各點距離

/

本篇會寫兩個用 Google Maps API 會遇到的狀況,就是目前使用者的所在位置,以及所在位置到目的地的距離。


目前所在位置

抓使用者目前所在位置,用的是瀏覽器本身的 geolocation

在使用 navigator.geolocation 時,有 2 個步驟:

  1. 確認使用者的裝置支援 navigator.geolocation
  2. 跟使用者要索取目前位置的權限

確認支援 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 的頁面:

點擊 啟用API和服務
點擊 啟用 API 和服務
Google API頁面
Google API 頁面

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

搜尋 Distance Matrix 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

根據本人實際使用的經驗,這句白話就是,每調用一次 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 會回傳的資料如下:

Distance Matrix API回傳的資料
Distance Matrix API 回傳的資料

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,完成後看到的截圖如下:

串完Distance Matrix API的範例截圖
串完 Distance Matrix API 的範例截圖

範例的原始碼也放在 GitHub上了,歡迎取用:

https://github.com/letswritetw/letswrite-google-map-api-5


Google Maps API 學習筆記系列

  1. 地圖、標記、客製樣式
  2. 在地圖上畫個日本結界
  3. 用熱圖(Heat Map)製作全台 12 小時雨量分佈圖
  4. Place API 自動完成地址、地點評論摘要
  5. 抓目前位置、計算到各點距離
  6. 畫新冠肺炎分佈圖
Summary
Google Maps API 學習筆記 - 5:抓目前位置、計算到各點距離
Article Name
Google Maps API 學習筆記 - 5:抓目前位置、計算到各點距離
Description
本篇大綱:目前所在位置、確認支援 geolocation、跟使用者要位置的權限、計算到各點距離 Distance Matrix Service、開啟權限、Distance Matrix API限制、使用 Distance Matrix API、API 回傳的值、實際應用。
Augustus
Let's Write
Let's Write
https://letswrite.tw/wp-content/uploads/2020/08/logo_512.jpg

隨選筆記文

Bot Slack

Slack 通知功能 可互動

Vue

用 VuePress 製作說明文件頁面 – 1:安裝

Front-End

SpeechSynthesisUtterance 讓瀏覽器說話

Front-End

TestCafe 學習筆記 – 1:自動化測試會員登入

Front-End

Auth0 Universal Login,做一個自己的會員註冊、登入功能

Front-End

第 100 篇:起點、轉折、then()

API

如何用 Postman Mock Server 快速建立 API Server

Firebase Google

Firebase Authentication 第三方登入 – Google、FB

API

GitHub API:建立 Issue、Comment – API、Personal access tokens

Front-End

不會寫程式,也能自己架一個免費網站:Publii + GitHub Pages

以下是留言,但關於留言的部份必需先讓你們知道:

本站的文章都是 August 因為覺得有趣,才會實作並整理成筆記文而後進行發表。

如果留言是希望把 Demo 改成「你想要」的樣子,或是把功能改成「符合你需求」的樣子,

Sorry~ 除非那修改是 August 也有興趣的,不然不會幫你們寫程式去面對工作或是交作業。

未來這類的留言不會再主動回覆。😎

另外,公開信箱是為了讓金流驗證用,

因為之前遇過幾次回信協助解決問題後,對方卻一聲謝謝也沒有,就這樣拿去幫工作交差。

因此決定不再回覆信件,有疑問就利用留言功能囉。