使用 Street View Static API 的最佳做法

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

Google 地圖平台靜態網路 API 是 Google 服務的一系列 HTTP 介面,可產生直接嵌入網頁的圖片。

Google 地圖平台網路服務是 Google 服務的一組 HTTP 介面,可為地圖應用程式提供地理資料。

本指南將說明設定圖片的幾個實用做法,以及設定網路服務和處理服務回應。如需 Street View Static API 的完整說明文件,請參閱開發人員指南

Street View Static API 的運作方式與靜態網路 API 類似,而中繼資料服務可以視為網路服務。如要進一步瞭解中繼資料服務,請參閱街景服務圖片中繼資料

什麼是 Static Web API?

Google 地圖平台靜態網路 API 可讓您在網頁中嵌入 Google 地圖圖片,完全不必使用 JavaScript 或任何動態網頁載入作業。API 會根據透過標準 HTTP 要求傳送的網址參數建立映像檔,方便您在網頁中顯示結果。

一般 Street View Static API 要求的一般格式如下:

https://maps.googleapis.com/maps/api/streetview?parameters

什麼是網路服務?

Google 地圖平台網路服務是一個介面,可從外部服務要求 Maps API 資料,以及使用地圖應用程式中的資料。根據《Google 地圖平台服務條款》的授權限制,這些服務的設計是與地圖搭配使用。

Maps API 網路服務會使用 HTTP(S) 要求傳送至特定網址,並將網址參數和/或 JSON 格式 POST 資料傳遞給服務。一般來說,這些服務會將 HTTP(S) 要求中的資料傳回 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 地圖平台網路服務和靜態網路 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&timestamp=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 中的輸出內容。已採用 JavaScript 物件形式的 JSON 回應,可在用戶端的 JavaScript 本身中處理。