使用Google Map API(Directions Service)獲取及顯示最佳路徑

文章推薦指數: 80 %
投票人數:10人

之前文章有介紹過如何使用Google Map API(Geocoding API, Distance Matrix Service)去取得點位縣市鄉鎮資訊或是兩點之間的距離及移動所需時間資訊(有興趣可以看這兩篇: ... GetunlimitedaccessOpeninappHomeNotificationsListsStoriesWrite使用GoogleMapAPI(DirectionsService)獲取及顯示最佳路徑之前文章有介紹過如何使用GoogleMapAPI(GeocodingAPI,DistanceMatrixService)去取得點位縣市鄉鎮資訊或是兩點之間的距離及移動所需時間資訊(有興趣可以看這兩篇:GeocodingAPI,DistanceMatrixService),這邊接著要介紹如何運用GoogleMapAPI取得兩點之間移動的最佳路徑資訊,並且把路徑顯示在地圖上,強大的GoogleMap目前提供了GoogleMapJavascriptAPI:DirectionsService讓我們可以獲取兩點之間的最佳路徑資訊,以下會依序說明如何使用DirectionsService以及如何將結果繪製在地圖上。

基本設定首先,跟使用其他的GoogleMapJavascriptAPI一樣,我們要先有GoogleMap的APIkey才可以使用相關服務,APIkey的申請流程Google的線上說明文件GetanAPIKey有很詳細的說明,基本上流程就是使用google帳號直接到GoogleCloudPlatform上面去創立一個專案,然後選擇要開啟的GoogleMapAPI,要使用DirectionsService,就要開啟DirectionsAPI,創立專案的時候,Google也會產生一組APIkey,這個key就是我們之後需要用到的。

拿到APIkey並啟用DirectionsAPI之後,就可以將DirectionsService載入到程式中,載入方式為將下方程式碼放入放入html的body中接著就可以在程式中使用DirectionsService送出request了,程式碼大概會像下面這樣,要注意的是,DirectionsService是使用route()這個方法來傳入request的參數及callback的functionletdirectionsService=newgoogle.maps.DirectionsService();letrequest={origin:haight,destination:oceanBeach,travelMode:'WALKING'};directionsService.route(request,function(response){if(status=='OK'){console.log(response);}});傳送參數request可以傳送的參數有以下這些,以下一一簡單說明{origin:LatLng|String|google.maps.Place,destination:LatLng|String|google.maps.Place,travelMode:TravelMode,transitOptions:TransitOptions,drivingOptions:DrivingOptions,unitSystem:UnitSystem,waypoints[]:DirectionsWaypoint,optimizeWaypoints:Boolean,provideRouteAlternatives:Boolean,avoidFerries:Boolean,avoidHighways:Boolean,avoidTolls:Boolean,region:String}origin(必傳):起點資訊,傳的格式可以用經緯度、地址或者google.maps.Place的資訊,例如也可以傳龍山寺。

destination(必傳):終點資訊,傳的格式可以用經緯度、地址或者google.maps.Place的資訊。

travelMode(必傳):從起點到終點移動的方式,包括:BICYCLING(腳踏車)、DRIVING(開車)、TRANSIT(轉運)、WALKING(走路)等四種,如果設定是DRIVING的話,可以另外傳送drivingOptions,設定交通時間計算模式,後面會再介紹drivingOptions,另外比較特別的是TRANSIT,如果傳送這個設定,表示起點跟終點間是有轉運點的,像搭飛機會在某個地方轉機那樣,不會直接抵達終點,所以如果設定TRANSIT的話,還會需要另外傳送transitOptions參數,下面會介紹transitOptions。

transitOptions(選填):travelMode是TRANSIT時才需要傳送,可填的選項包括arrivalTime(抵達時間)、departureTime(出發時間)、modes(中繼點,有像是RAIL、SUBWAY、TRAIN等選項)、routingPreference(路徑偏好,可以設定FEWER_TRANSFERS、LESS_WALKING這種轉運方式的偏好)。

drivingOptions(選填):travelMode是DRIVING時才需要傳送,可傳送的參數有departureTime(出發時間)及trafficModel(交通時間計算模式,有bestguess(最佳模式)、pessimistic(悲觀模式)、optimistic(樂觀模式)等三個模式來計算到達終點所需時間,預設值為bestguess,bestguess是用最貼近實際交通狀況來估計時間,pessimistic是用最糟的情況來預估時間而optimistic適用最好的情況來預估,所以一般情況,得到的時間長度應該是:pessimistic>bestguess>optimistic)unitSystem(選填):距離單位,有google.maps.UnitSystem.METRIC及google.maps.UnitSystem.IMPERIAL兩個選項,沒有傳送unitSystem參數的話,預設為METRIC,也就是公制,得到的距離單位會是公尺、公里,如果設定是IMPERIAL,回傳值的距離單位就會是英尺、英里。

waypoints(選填):路徑中間是否有經過哪些特定的地點,可以傳送多個地點,每個地點要傳送的參數包括location(點位資訊,傳的格式可以用經緯度、地址或者google.maps.Place的資訊)及stopover(是否停留,傳送格式為Boolean,若為TRUE,則回傳的路徑會被此點為切分為兩條路徑)。

optimizeWaypoints(選填):若有傳送waypoints資訊,則可傳送TRUEorFALSE來設定是否讓DirectionsService決定路徑中的waypoints的最佳順序。

provideRouteAlternatives(選填):是否提供多個路徑的資訊,可傳送TRUEorFALSE,若傳送TRUE,則DirectionsService會回傳多個建議的路徑資訊,不會只回傳一個最佳路徑資訊。

avoidFerries(選填):是否避開渡輪,可傳送TRUEorFALSE,要求DirectionsService回傳的結果是否要避開使用渡輪的路徑。

avoidHighways(選填):是否避開高速公路,可傳送TRUEorFALSE,要求DirectionsService回傳的結果是否要避開高速公路的路徑。

avoidTolls(選填):是否避開收費站,可傳送TRUEorFALSE,要求DirectionsService回傳的結果是否要避開收費站的路徑。

region(選填):限定回傳結果是要特定區域顯示的資訊,可傳送像是GB,US這樣的地區代碼,因為GoogleMap在不同地區顯示的結果可能會有些微不同,例如在https://maps.google.com/(theUnitedStates)跟在http://maps.google.es/(Spain)搜尋”SanFrancisco”結果可能會不一樣,要查詢各地區應該傳送的代碼可參考這邊。

回傳結果看完以上可傳送參數說明,可以知道能根據不同的需求去傳送特定的參數給DirectionsService得到特定情況下的路徑資訊,這邊簡單示範傳送的參數及得到的回傳結果:以下圖為例,設定所在位置為起點,咖啡廳為終點,移動方式為走路傳送的request參數如下,地址的部份因為太長就以…省略{travelMode:'WALKING',origin:{lat:25.0388994,lng:121.5018781},destination:"No.32,Lane96,Section2,....,Taiwan108"}而得到的response像下面這樣,可以看到DirectionsService回傳了不少資訊,主要包含了四個部分:geocoded_waypoint,routes,status,request{geocoded_waypoints:[{geocoder_status:"OK",place_id:"ChIJF7o8ZaipQjQRfptaql_xRbA",types:["street_address"]},{geocoder_status:"OK",place_id:"ChIJf_uO2aepQjQR0g_GxilqXC4",types:["street_address"]}]routes:[{bounds:{Va:{i:121.50185,j:121.50307},Za:{i:25.03873,j:25.03894}},copyrights:"Mapdata©2020Google",legs:[{distance:{text:"0.1km",value:138}duration:{text:"1min",value:46}end_address:"No.32,....,Taiwan108"end_location:_.I{lat:ƒ,lng:ƒ}start_address:"No.131,....,Taiwan108"start_location:_.I{lat:ƒ,lng:ƒ}steps:(2)[{…},{…}]traffic_speed_entry:[]via_waypoint:[]via_waypoints:[]}],overview_path:(4)[_.I,_.I,_.I,_.I],overview_polyline:"qlywCyyqdVd@wEDO]I",summary:"永福街",warnings:["Walkingdirectionsareinbeta.Usecaution–Thisroutemaybemissingsidewalksorpedestrianpaths."],waypoint_order:[]}]status:"OK"request{...}}以下大致說明一下得到回傳的結果:geocoded_waypoint:傳送的起點跟終點的地理定位資訊,主要回傳有沒有定到起點跟終點的位置,然後這兩個點位的一些補充資訊,像是點位的類別是屬於什麼,以上範例,起點跟終點的位置都是屬於門牌地址,所以都是street_address,有興趣深入了解geocoded_waypoint還有哪一些類別,可以參考這邊。

routes:主要是起點到終點要行經的路徑資訊,包括路徑中的最大跟最小經緯度是多少(記錄在bounds中)、路徑的一些基本資訊像是多長要花多久時間到終點(記錄在legs中,若一開始傳送多個waypoint,則response的legs就會是記錄有多個hash的array,沒有waypoint就是回傳只有一個hash的資訊),還有比較特別的是可能會有警告訊息回傳,提醒使用者要注意,像上面範例是使用走路做為移動的方法,在response的結果,routes這邊warning的參數就紀錄了這段文字Walkingdirectionsareinbeta.Usecaution—Thisroutemaybemissingsidewalksorpedestrianpaths.status:這次request的結果是不是成功,或是有什麼錯誤,一般來說成功會回傳OK,如果有一些特殊狀況像是地點找不到就可能會回傳NOT_FOUND,詳細的回傳結果類型可以看這邊。

request:基本上就是把一開始傳送的request參數再回傳回來。

顯示路徑根據上面的範例及說明,已經可以使用DirectionsService並且得到reponse結果了,接著就是想辦法把結果呈現在地圖上,這樣才可以一目瞭然GoogleMap幫我們找的最佳路線是長什麼樣,GoogleMap這邊提供了一個方法叫DirectionsRenderer(),可以把路徑畫到地圖上,接下來就直接看一下使用的方法(如下方程式碼),基本上,只要把得到的response結果帶入directions這個參數,然後帶入要畫的地圖object給map參數,在整包hash傳給DirectionsRenderer()就可以把路徑畫出來了letdirectionsService=newgoogle.maps.DirectionsService();letrequest={origin:haight,destination:oceanBeach,travelMode:'WALKING'};directionsService.route(request,function(response){if(status=='OK'){letdirectionsDisplay=newgoogle.maps.DirectionsRenderer({map:map,directions:response,});}});畫出來的結果像下面這樣,可以看到DirectionsRenderer()預設會把路徑的起點跟終點用紅色圖釘然後顯示A點跟B點標示出來,路徑的顏色預設會是藍色路徑預設樣式若想要調整預設的設定,DirectionsRenderer()也提供了不少參數讓我們傳送來客製化顯示的路徑樣式,以下簡單加上一些設定做示範:調整路徑線條樣式:DirectionsRenderer()可以傳送polylineOptions參數來對路徑的樣式做一些調整,像是線條的顏色、透明度及寬度等,詳細的燦數設定可以參考這裡。

letdirectionsDisplay=newgoogle.maps.DirectionsRenderer({map:map,directions:response,polylineOptions:{strokeColor:'yellow'}});調整路徑線條樣式隱藏終點和起點圖釘標示:想要隱藏終點和起點的圖釘,可以傳送suppressMarkers這個參數。

letdirectionsDisplay=newgoogle.maps.DirectionsRenderer({map:map,directions:response,polylineOptions:{strokeColor:'yellow'}suppressMarkers:true});隱藏終點和起點圖釘標示設定路徑可拖拉:如果想手動拖拉路徑,則可以加上draggable這個參數。

letdirectionsDisplay=newgoogle.maps.DirectionsRenderer({map:map,directions:response,polylineOptions:{strokeColor:'yellow'}suppressMarkers:true,draggable:true});手動拖拉路徑以上主要簡單展示幾個繪製路徑時可以做的調整設定,DirectionsRenderer()還有提供很多設定參數做顯示路徑客製化的調整,有興趣可以參考這邊。

最後這邊做一個小分享,給大家看同樣的起點終點但移動的方式如果不同的話,其實路徑還是會有些微的差別,這邊就以移動模式為走路(WALKING)跟開車(DRIVING)來做比較,兩種模式的路徑如下面兩張圖走路模式開車模式從圖上可以看到,走路模式的路徑,是真的沿著人行道在走的,然後開車模式,路徑都是在道路正中間,Google連這麼細節的部分都有呈現,真的是很令人佩服,看得出來他們相當認真的要呈現出符合現實的結果。

以上介紹的DirectionsService以及前兩篇文章介紹的DistanceMatrixService及GeocodingAPI,若有興趣參考更多使用的範例及程式碼,可以參考我的github專案coffee_project。

參考資料:GoogleMapPlatform—DirectionsServiceUdacity線上課程—GoogleMapAPIMorefromicelandchengFollowProgrammingSkilllearnerandSharer|RubyonRails💎Vue.js🌐WebMapAPILovepodcastsoraudiobooks?Learnonthegowithournewapp.TryKnowableAboutHelpTermsPrivacyGettheMediumappGetstartedicelandcheng64FollowersProgrammingSkilllearnerandSharer|RubyonRails💎Vue.js🌐WebMapAPIFollowHelpStatusWritersBlogCareersPrivacyTermsAboutKnowable



請為這篇文章評分?