本文件說明如何在預定路線中找到飯店、餐廳或加油站。您將瞭解如何使用 Routes API 取得路線多邊形,並將其用於 Places API 沿路搜尋 (SAR) 要求。您也將瞭解如何設定沿路搜尋起點,例如行程開始後 2 小時,以便取得最佳結果。
Routes API
為了搜尋沿途地點,我們將使用 Routes API。來自 Routes API 回應的路線資料,是從起點到目的地的一系列 LatLong 座標。路線資料包含沿著道路網路的路段和步驟。
路線也會以已編碼的多邊形形式傳回,您可以將其做為輸入參數傳遞至 SAR 要求。折線編碼是一種有損壓縮演算法,可讓您將一系列座標儲存為單一字串。您不一定要從 Routes API 取得多邊形線。您可以自行建立資料,但為了方便說明,Routes API 是取得必要資料的快速且可靠方式。
在本教學課程中,我們使用倫敦 (-37.8167,144.9619) 到曼徹斯特 (-37.8155, 144.9663) 的路線
範例中的路線:倫敦到曼徹斯特
步驟 1:透過 Routes API 取得路線
如要透過 Routes API 取得路線,您必須提供下列資訊:
- 出發地和目的地
- 交通方式 (開車、步行等)
- 任何路徑點 (選填)
- 任何偏好設定 (避開收費路段、高速公路等)
- 交通狀況感知路線偏好設定可提供最精確的預估值,但運算量較大,因此會增加回應延遲時間。
{"origin":{
"location": {
"latLng":{
"latitude": -37.8167,
"longitude": 144.9619
}
}
},
"destination":{
"location": {
"latLng":{
"latitude":-37.8155,
"longitude": 144.9663
}
}
},
"routingPreference":"TRAFFIC_AWARE",
"travelMode":"DRIVE"
}
進行呼叫時,請務必在標頭欄位遮罩中加入「encodedPolyline」欄位。
headers = {
"Content-Type": "application/json",
"X-Goog-FieldMask": "routes.distanceMeters,routes.duration,routes.legs,routes.polyline.encodedPolyline"
}
在要求中提供這項資訊後,Routes API 就會傳回路線物件。路線物件會包含下列資訊:
- 路線的總距離
- 路線的總時間長度
- 路線的路段和步驟
- 路線、路段和步驟的編碼折線。
{
"routes": [
{
"legs": [
{
"distanceMeters": 321799,
"duration": "15401s",
"staticDuration": "14518s",
"polyline": {
"encodedPolyline": "y_kyH`_XOr@q@xKGnBBZ|AlGPj@Y^k@^MEqAfAQLK?eI … <rest of content removed for readability>"
},
"startLocation": {
"latLng": {
"latitude": 51.507334500000006,
"longitude": -0.1280107
}
},
"endLocation": {
"latLng": {
"latitude": 53.4808513,
"longitude": -2.2425864
}
},
"steps": [
{
"distanceMeters": 320,
"staticDuration": "82s",
"polyline": {
"encodedPolyline": "y_kyH`_XOr@q@xKGnBBZ|AlG"
},
"startLocation": {
"latLng": {
"latitude": 51.507334500000006,
"longitude": -0.1280107
}
},
"endLocation": {
"latLng": {
"latitude": 51.507207,
"longitude": -0.1323681
}
},
"navigationInstruction": {
"maneuver": "DEPART",
"instructions": "Head northwest on Trafalgar Sq/A4 toward Spring Gardens\nContinue to follow A4\nLeaving toll zone\nEntering toll zone\nLeaving toll zone in 210m at Haymarket"
},
"localizedValues": {
"distance": {
"text": "0.3 km"
},
"staticDuration": {
"text": "1 min"
}
},
# rest of the response removed for readability
步驟 2:搜尋沿路路線要求
Places API Text Search 提供「沿路搜尋」要求,可讓您搜尋沿路的地點。如要執行沿路搜尋要求,您必須提供下列最低限度的資訊:
- 回應中傳回的欄位欄位遮罩
- 在 Google Cloud 控制台中啟用的 API 的有效 API 金鑰
- 搜尋文字字串,指出你要尋找的地點,例如「辛辣素食餐廳」
- 從先前的 Routes API 呼叫擷取的路線編碼折線
- Places Text Search API 端點的網址
import requests
url = 'https://places.googleapis.com/v1/places:searchText'
api_key = 'YOUR_API_KEY' # Replace with your actual API key
route_polyline = 'YOUR_ROUTE_POLYLINE' # Replace with your encoded route polyline
headers = {
'Content-Type': 'application/json',
'X-Goog-Api-Key': api_key,
'X-Goog-FieldMask': 'places.displayName,places.formattedAddress,places.priceLevel'
}
data = {
"textQuery":
"Spicy Vegetarian Food",
"searchAlongRouteParameters": {
"polyline": {
"encodedPolyline": route_polyline
}
}
}
response = requests.post(url, headers=headers, json=data)
要求資料範例
「沿路搜尋」要求會傳回沿路地點的清單。以下是範例資料的一部分。您可以設定結果參數的數量上限,藉此限制回應長度,當然,增加更多欄位也會增加收到的資料量。如要進一步瞭解 Places API 回應,請參閱說明文件。
{
"places": [
{
"formattedAddress": "33 Haymarket, London SW1Y 4HA, UK",
"displayName": {
"text": "xxx",
"languageCode": "en"
}
},
{
"formattedAddress": "224 Piccadilly, London W1J 9HP, UK",
"priceLevel": "PRICE_LEVEL_MODERATE",
"displayName": {
"text": "yyy",
"languageCode": "en"
}
},
{
"formattedAddress": "63 Neal St, London WC2H 9PJ, UK",
"displayName": {
"text": "zzz",
"languageCode": "en"
}
},
回應資料範例
路線摘要和繞路時間
雖然只找到地點就很棒,但如果能加入前往這些地點所需的時間資訊,會更有幫助。Places API Text Search 中的 SAR 也可以傳回包含行程時間和距離的路線摘要欄位。路線摘要資料欄位是回應根目錄的子項,因此請勿在欄位遮罩中加入「places.」前置字串。
'X-Goog-FieldMask': 'places.displayName,places.formattedAddress,places.priceLevel,routingSummaries'
如要取得摘要,您必須為搜尋提供起點位置參數,以便用於計算。
"routingParameters": {
"origin": {
"latitude": -37.8167,
"longitude": 144.9619
}
}
收到回應時,您會看到新的「路線摘要」部分,其中包含以公尺為單位的時間長度和距離的路線。
"routingSummaries": [
{
"legs": [
{
"duration": "662s",
"distanceMeters": 3093
}
]
},
接下來,我們將說明如何定義沿路哪個位置開始搜尋。
步驟 3:取得沿途 2 小時的定位資料
請考慮一般使用情境,例如駕駛人想在路線起點以外的路段尋找餐廳。在本例中,從倫敦到曼徹斯特的車程約 4 小時。駕駛人想在路線行駛 2 小時後尋找餐廳。這項要求會取得 120 分鐘 * 60 秒 = 7200 秒的時間長度。
在 Routes API 回應中,我們有路線的每個航段和每個航段的步驟持續時間。請務必在要求的欄位遮罩中加入「legs」欄位。重複執行腿部和步驟,直到累積時間達到 2 小時或 7200 秒的限制。接著,我們找到要設為 SAR 要求來源的路段和步驟
如要加快工作速度,不妨試試 Python 適用的多邊形程式庫。您可以使用這項功能,從「polyline.endodedPolyline」資料欄位取得座標。
在環境終端機中執行下列指令。
> pip install polyline
import requests
import polyline
# We've covered getting a Routes API response earlier,
data = response.json()
# Extract the first route and its encoded polyline
route = data["routes"][0]
polyline_points = polyline.decode(route["polyline"]["encodedPolyline"])
# Calculate total duration of the route in seconds
total_duration_seconds = route["duration"]
# Calculate the desired time offset in seconds, 2h = 120 minutes * 60
desired_time_offset_seconds = time_offset_minutes * 60
# Iterate through the legs and steps to find the point at the desired time offset
elapsed_time_seconds = 0
for leg in route["legs"]:
for step in leg["steps"]:
step_duration_seconds = step["staticDuration"]
# Check if the desired time offset falls within this step, remove last "s" from string and convert to int
second_value = int(step_duration_seconds[:-1])
if elapsed_time_seconds + second_value >= desired_time_offset_seconds:
# Interpolate to find the exact point within the step
fraction_of_step = (desired_time_offset_seconds - elapsed_time_seconds) / second_value
step_polyline_points = polyline.decode(step["polyline"]["encodedPolyline"])
index = int(len(step_polyline_points) * fraction_of_step)
return step_polyline_points[index]
elapsed_time_seconds += second_value
# If the point is not found (e.g., time offset exceeds route duration)
return None
我們已在路線上找到 2 小時車程的所在位置,因此可以將該位置用於要求。只要在「origin」參數中加入經緯度即可,而該參數又是「routingParameters」參數的一部分。建議使用先前介紹的「routingSummaries」資料欄位。如有需要,您也可以新增其他參數,例如行程模式和避開收費路段的指示。
"routingParameters": {
"origin": {
"latitude": xx.xxxx,
"longitude": yy.yyyy
},
"travelMode":"DRIVE",
"routeModifiers": {
"avoidTolls": true
}
}
結果範例 (新增汽車圖示,以顯示搜尋來源)。
如圖所示,API 會傳回偏向路線終點的結果,也就是從行程中段開始的結果。搜尋功能仍會使用相同的 Google 地圖平台資料,考量地點相關性和距離等其他因素。
結語
在本教學課程中,我們學習如何結合兩個 Google 地圖平台 API (路徑和地點),規劃行程並在行程開始後 2 小時找到可用餐的地點。您必須採取的步驟包括取得已編碼的折線,其中包含路線每個步驟的經緯度座標,並設定沿路搜尋要求的來源,以便取得最佳結果。
這項功能可為 Places API 現有的文字搜尋和附近搜尋功能,新增強大的全新工具。接下來,您可以新增位置服務,以便使用駕駛員的位置做為起點,找出最佳搜尋起點。此外,這項功能還能與車內語音助理完美搭配,讓你以語音表達偏好的用餐選項。
後續行動
- 請嘗試說明文件中的範例。
- 提供意見回饋。
建議參閱以下文章:
貢獻者
本文件由 Google 維護。以下是原作者。
主要作者:Mikko Toivanen | Google 地圖平台解決方案工程師