Google 地圖平台網路服務是 Google 服務的 HTTP 介面,為地圖應用程式提供地理資料。
本指南將說明一些常用做法,協助您設定網路服務或要求服務及處理服務回應。如需 Roads API 的完整說明文件,請參閱開發人員指南。
什麼是網路服務?
Google 地圖平台網路服務可要求從外部服務要求 Maps API 資料的介面,並在 Google 地圖應用程式中使用資料。根據 Google 地圖平台服務條款的授權限制,這些服務的設計可與地圖搭配使用。
Maps API 網路服務使用 HTTP(S) 要求至特定網址,並將網址參數和/或 JSON 格式 POST 資料做為引數傳遞至服務。一般而言,這些服務會以回應內文傳回資料,採用 JSON 來剖析及/或處理應用程式。
一般的 Roads API 網路服務要求通常是以下格式:
https://roads.googleapis.com/v1/snapToRoads?parameters&key=YOUR_API_KEY
其中 snapToRoads
表示要求的特定服務。其他道路服務包括 nearestRoads
和 speedLimits
。
注意:所有 Roads API 應用程式都必須進行驗證。進一步瞭解驗證憑證。
SSL/TLS 存取權
所有使用 API 金鑰或包含使用者資料的 Google 地圖平台要求,都必須使用 HTTPS。透過 HTTP 發出含有機密資料的要求可能會遭到拒絕。
建立有效網址
您可能認為網址是否「有效」一眼就能判斷,但實際情況不然。例如,在瀏覽器的網址列內輸入的網址可能包含特殊字元 (例如 "上海+中國"
);瀏覽器必須在內部將這些字元轉譯為不同的編碼方式才能傳送。同理可證,任何產生或接受 UTF-8 輸入值的程式碼可能會將含有 UTF-8 字元的網址視為「有效網址」,但也需要先轉譯這些字元,才能將其向外傳送至網路伺服器。這個過程稱為網址編碼或百分比編碼。
特殊字元
我們必須翻譯特殊字元,因為所有網址都必須符合統一資源 ID (URI) 規格指定的語法。事實上,這表示網址必須僅包含一個特殊的 ASCII 字元子集:慣用的英數字元符號,以及用做網址內控制字元的部分預留字元。下表摘要列出這些字元:
字元集 | 字元 | 網址使用情況 |
---|---|---|
英數字元 | a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 | 文字字串、結構用途 (http )、連接埠 (8080 ) 等。 |
非預留 | - _~ | 文字字串 |
預留 | ! * ' ( ) ; : @ & = + $ , / ? % # [ ] | 控制字元和 (或) 文字字串 |
建立有效網址時,您必須確認網址僅包含「有效網址字元摘要」表格中列出的字元。網址如果使用這個字元集,通常會導致遺漏及代換兩個問題:
- 您希望處理的字元不屬於上述字元集。舉例來說,外國語言的字元 (例如
上海+中國
) 就需要使用上述字元加以編碼。依照普遍慣例,空格 (網址內不允許使用) 通常也用加號'+'
字元來表示。 - 如果是上述字元集中預留字元的字元,仍需依照字面意思使用。舉例來說,網址內會使用
?
來表示查詢字串的開頭;如果您想使用「? and the Mysterions」這個字串,就必須對'?'
字元進行編碼。
所有遵守網址編碼原則的字元都會利用 '%'
字元以及對應至其 UTF-8 字元的雙字元十六進位值編碼。舉例來說,採用 UTF-8 編碼的 上海+中國
改用網址編碼時,會成為 %E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B
。字串 ? and the Mysterians
會以網址編碼為 %3F+and+the+Mysterians
或 %3F%20and%20the%20Mysterians
。
需要編碼的常見字元
必須編碼的部分常見字元如下:
不安全的字元 | 經過編碼的值 |
---|---|
空格鍵 | %20 |
" | %22 |
< | %3C |
> | %3E |
# | %23 |
% | %25 |
| | %7C |
轉換您從使用者輸入中取得的網址,有時並不容易處理。舉例來說,使用者輸入的地址可能是「5th&Main St.」。一般來說,您應該根據各組成部分來建立網址,並將任何使用者輸入內容當成常值字元來處理。
此外,所有 Google 地圖平台網路服務和靜態網路 API 的網址長度上限都是 8,192 個字元。對於大部分的服務而言,幾乎很少接近此字元限制的長度。但請注意,某些特定的服務具備幾個可能產生長網址的參數。
短暫使用 Google API
設計不當的 API 用戶端可在網際網路和 Google 伺服器上執行不必要的負載。本節提供一些 API 用戶端的最佳做法。遵循這些最佳做法有助於避免您的應用程式遭到無謂的濫用 API 濫用。
指數型退讓
在極少數情況下,處理要求可能會發生錯誤;您可能會收到 4XX 或 5XX HTTP 回應代碼,否則 TCP 連線可能會在用戶端與 Google 伺服器之間某些位置失敗。在重新嘗試要求之前,後續嘗試重試的要求通常相當值得,不過,請勿重複向 Google 伺服器發出要求,這種循環行為會導致用戶端與 Google 之間的網路超載,進而導致許多方發生問題。
建議在每次重試之間增加延遲來重試。一般而言,每次延遲的延遲時間會增加倍數因數,這個做法稱為「指數輪詢」。
例如,假設應用程式想向 Time Zone API 發出這項要求:
https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510×tamp=1331161200&key=YOUR_API_KEY
以下 Python 範例說明如何以指數輪詢方式發出要求:
import json import time import urllib.error import urllib.parse import urllib.request # The maps_key defined below isn't a valid Google Maps API key. # You need to get your own API key. # See https://developers.google.com/maps/documentation/timezone/get-api-key API_KEY = "YOUR_KEY_HERE" TIMEZONE_BASE_URL = "https://maps.googleapis.com/maps/api/timezone/json" def timezone(lat, lng, timestamp): # Join the parts of the URL together into one string. params = urllib.parse.urlencode( {"location": f"{lat},{lng}", "timestamp": timestamp, "key": API_KEY,} ) url = f"{TIMEZONE_BASE_URL}?{params}" current_delay = 0.1 # Set the initial retry delay to 100ms. max_delay = 5 # Set the maximum retry delay to 5 seconds. while True: try: # Get the API response. response = urllib.request.urlopen(url) except urllib.error.URLError: pass # Fall through to the retry loop. else: # If we didn't get an IOError then parse the result. result = json.load(response) if result["status"] == "OK": return result["timeZoneId"] elif result["status"] != "UNKNOWN_ERROR": # Many API errors cannot be fixed by a retry, e.g. INVALID_REQUEST or # ZERO_RESULTS. There is no point retrying these requests. raise Exception(result["error_message"]) if current_delay > max_delay: raise Exception("Too many retry attempts.") print("Waiting", current_delay, "seconds before retrying.") time.sleep(current_delay) current_delay *= 2 # Increase the delay each time we retry. if __name__ == "__main__": tz = timezone(39.6034810, -119.6822510, 1331161200) print(f"Timezone: {tz}")
您也應該注意,應用程式呼叫鏈中的程式碼不會重試,因此能快速連續傳回要求。
同步要求
傳送至 Google API 的大量同步要求在 Google 基礎架構上可能會發生分散式阻斷服務 (DDoS) 攻擊,並據此進行處理。為避免這種情況,請確認 API 要求不會在用戶端之間保持同步。
舉例來說,請某個應用程式,顯示目前時區的時間。這個應用程式可能會在用戶端作業系統中,在清醒時設定鬧鐘,以便更新顯示時間。應用程式不應在與該鬧鐘相關聯的處理過程中發出任何 API 呼叫。
對固定鬧鐘發出 API 呼叫並不會產生負面影響,因為這會導致 API 呼叫在一分鐘內 (甚至是不同裝置) 同步處理,而非平均分配。設計不良的應用程式會在每分鐘開始時,正常產生六倍的正常流量。
其中一種可行的做法是將第二個鬧鐘設定為隨機選擇的時間。第二個鬧鐘觸發時,應用程式會呼叫所有必要的 API,然後儲存結果。如果應用程式在一開始啟動時更新螢幕,則會使用先前儲存的結果,而不是再次呼叫 API。使用這個方法時,API 呼叫會逐漸平均分配。此外,API 呼叫在螢幕更新時不會延遲算繪。
除了從早上開始,有些其他常見的同步處理時間需要注意,請「不要」鎖定目標的開始時間為一小時,每天開始午夜。
處理回應
本章節討論如何從網路服務回應中,以動態方式擷取這些值。
Google 地圖網路服務提供簡單易懂的回應,但並非容易使用。執行查詢時,與其顯示一組資料,您可能需要擷取一些特定的值。一般而言,建議您剖析來自網路服務的回應,並只擷取您感興趣的值。
您使用的剖析配置取決於是否以 JSON 傳回輸出內容。JSON 回應形式為 JavaScript 物件,可以在用戶端的 JavaScript 本身中處理。