Google 地圖平台靜態網路 API 是 Google 服務的 HTTP 介面集合,可產生圖片並直接嵌入網頁。
Google 地圖平台網路服務是 Google 服務的 HTTP 介面集合,可為地圖應用程式提供地理資料。
本指南說明一些實用的常見做法,有助您設定圖片及 網路服務要求及處理服務回應。如需 Street View Static API 的完整說明文件,請參閱開發人員指南。
Street View Static API 的運作方式與靜態網路 API 類似,而中繼資料服務可視為網路服務。如要進一步瞭解中繼資料服務,請參閱「街景服務圖片中繼資料」一文。什麼是 Static Web API?
Google 地圖平台的靜態網路 API 可讓您在網頁中嵌入 Google 地圖圖片,完全不必使用 JavaScript 或任何動態網頁載入。靜態 Web API 會根據網址參數傳送圖片,而這些參數會透過標準 HTTPS 要求傳送。一般的 Street View Static API 要求通常採用下列形式:
https://www.googleapis.com/streetview/z/x/y?parameters
什麼是網路服務?
Google 地圖平台網路服務是一種介面,可用來向外部服務要求 Maps API 資料,並在地圖應用程式中使用資料。這些服務應該依照《Google 地圖平台服務條款》的授權限制規定與地圖搭配使用。
Maps API 網路服務使用對特定網址的 HTTP(S) 要求,並將網址參數和/或 JSON 格式的 POST 資料做為服務的引數傳遞至服務。一般來說,這些服務會在回應主體中以 JSON 格式傳回資料,供應用程式剖析和/或處理。
Street View Static API 中繼資料要求的格式如下:https://maps.googleapis.com/maps/api/streetview/parameters
注意:所有 Street View Static 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 地圖平台網路服務和 Static Web API 的網址長度上限都是 16384 個半形字元。對於大部分的服務而言,很少出現接近此字元限制的情況。但請注意,某些服務的幾個參數可能會產生較長的網址。
謹慎使用 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 本身內處理。