Geocoding API 第 4 版推出多項新方法,取代第 3 版 API 的功能。本指南說明如何遷移應用程式,改用新的 v4 方法。
您可以在新的 v4 方法中使用現有的 API 金鑰。不過,如果您已要求提升 API 第 3 版的配額,則必須要求提升新版第 4 版 API 的配額。
從 v3 正向地理編碼遷移
如果您使用 v3 地理編碼服務對地址進行地理編碼,請遷移至 v4 的「對地址進行地理編碼」方法,該方法會接受 GET 要求。
v4 版 API 變更了多個參數的名稱、結構和支援項目。強烈建議您使用欄位遮罩,指定要在回應中傳回的欄位。
要求參數變更
| v3 參數 | v4 參數 | 附註 |
|---|---|---|
address、components |
address |
非結構化地址 (v3 address) 現在會透過網址路徑傳遞。結構化地址元件 (第 3 版 components) 可以做為 address.* 查詢參數傳遞。請參閱「重現 v3 元件篩選器」。 |
bounds |
locationBias.rectangle |
已重新命名,結構已變更為物件。 |
language |
languageCode |
已重新命名。 |
region |
regionCode |
已重新命名。 |
extra_computations |
已移除 | 已由 SearchDestinations 方法取代。 |
回應欄位變更
| v3 欄位 | 第 4 版欄位 | 附註 |
|---|---|---|
status、error_message |
已移除 | 第 4 版使用 HTTP 狀態碼和錯誤主體。 |
results.address_components.long_name/results.address_components.short_name |
results.addressComponents.longText/results.addressComponents.shortText |
已重新命名。 |
results.geometry.location_type |
results.granularity |
已重新命名。 |
results.geometry.location |
results.location |
欄位名稱:lat/lng -> latitude/longitude。 |
results.geometry.viewport |
results.viewport |
欄位名稱:northeast/southwest -> high/low。 |
results.postcode_localities |
results.postalCodeLocalities |
已重新命名。現在會針對一或多個地區傳回 (需要 v3 > 1)。 |
results.partial_match |
已移除 | |
| 新功能 | results.addressComponents.languageCode |
特定地址元件的語言。 |
| 新功能 | results.bounds |
使用 high/low 明確設定界線。 |
| 新功能 | results.place |
地點的資源名稱。 |
| 新功能 | results.postalAddress |
結構化 PostalAddress 物件。 |
重現 v3 元件篩選器
地理編碼第 3 版的「正向地理編碼」包含 components 參數,可針對特定元件 (例如 components=country:US) 進行嚴格篩選。第 4 版的「正向地理編碼」不支援在要求參數中進行這類嚴格篩選。在第 4 版中,您可以提供地址資訊,方法是在路徑中以單一非結構化字串的形式提供,或是以結構化查詢參數的形式提供,例如 address.addressLines、address.locality、address.administrativeArea、address.postalCode 和 address.regionCode。結構化參數不會做為硬性篩選器。而是會將所有提供的元件合併,形成 API 嘗試進行地理編碼的完整地址。API 會在所有元件中搜尋與指定完整地址最相符的結果。以結構化方式提供元件,有助於 API 瞭解意圖,特別是從個別表單欄位收集地址資訊時。由於每個欄位的資訊類型都很明確,因此有助於 API 處理各個元件中的微小錯字或模稜兩可之處。
如要達到類似於第 3 版硬式元件篩選器的行為,您必須根據回應中的 postalAddress 和 addressComponents 物件,在第 4 版 API 傳回的 results 陣列上實作用戶端篩選。
下表列出第 3 版 components 篩選器與第 4 版 postalAddress 欄位的最佳對應關係:
| v3 元件篩選器 | v4 回應欄位 |
|---|---|
country |
postalAddress.regionCode |
postal_code |
postalAddress.postalCode |
administrative_area |
postalAddress.administrativeArea 或 addressComponents |
用戶端篩選範例
下列範例說明如何篩選結果,以針對支援的欄位 (國家/地區、行政區和郵遞區號) 達成類似於 v3 元件篩選的行為。不建議依其他欄位篩選,因為沒有可靠的篩選條件。
依國家/地區篩選
將要求中的 address.regionCode 與每個結果中的 postalAddress.regionCode 進行比對。請注意,雖然 API 會接受要求中的小寫區域代碼,但一律會在回應中傳回大寫代碼,因此您必須先將輸入內容正規化為大寫,才能進行比較。
Python 程式碼範例
def filter_by_country(results, region_code): return [ res for res in results if res.get('postalAddress', {}).get('regionCode') == region_code.upper() ] # Example usage: # v4_response = ... # API call response # filtered = filter_by_country(v4_response.get('results', []), 'US')
Node.js 程式碼範例
function filterByCountry(results, regionCode) { return results.filter(res => res.postalAddress?.regionCode === regionCode.toUpperCase()); } // Example usage: // const v4Response = ... # API call response // const filtered = filterByCountry(v4Response.results, 'US');
依管理區域篩選
將要求中的 address.administrativeArea 與每個結果中的 postalAddress.administrativeArea 進行比對。與國家/地區代碼類似,您應先將輸入內容正規化為大寫,再進行比較。只有在要求中的 administrativeArea 提供標準的 2 個字母縮寫時,這項資訊才可靠。回應中的 postalAddress.administrativeArea 可能不會直接對應至 ISO 3166-2 代碼後置字元,原因如下:首先,在部分地區,對應 ISO 3166-2 代碼的細分區域並非郵遞地址的標準表示方式。舉例來說,在西班牙,addressComponents 可能包含第 1 級行政區 (例如加那利群島的「CN」),但 postalAddress.administrativeArea 可能包含第 2 級行政區 (例如「聖克魯斯德特內里費」)。其次,在某些地區,子區域的縮寫並不常用,而是以較長的名稱表示 (基於類似原因,對應子區域的地址元件 addressComponents.shortText 可能與子區域的 ISO 3166-2 代碼後置字串不符)。postalAddress.administrativeArea此外,在某些情況下,子區域可能會以 administrative_area_level_n 的地址元件表示,其中 n 大於 1。
如要取得最完整的結果,您應該檢查 postalAddress.administrativeArea 和任何具有 administrative_area_level_n 類型 (例如 administrative_area_level_1) 的 addressComponents 是否相符。
Python 程式碼範例
def filter_by_admin_area(results, admin_area): target = admin_area.upper() filtered = [] for res in results: # Check postalAddress pa_aa = res.get('postalAddress', {}).get('administrativeArea', '') if pa_aa == target: filtered.append(res) continue # Check all administrative area levels in addressComponents for comp in res.get('addressComponents', []): is_admin_level = any(t.startswith('administrative_area_level_') for t in comp.get('types', [])) if is_admin_level: short = comp.get('shortText', '') if short == target: filtered.append(res) break return filtered # Example usage: # filtered = filter_by_admin_area(v4_response.get('results', []), 'CA')
Node.js 程式碼範例
function filterByAdminArea(results, adminArea) { const target = adminArea.toUpperCase(); return results.filter(res => { // Check postalAddress.administrativeArea if (res.postalAddress?.administrativeArea === target) { return true; } // Check addressComponents for any administrative area level return res.addressComponents?.some(c => { const isAdmin = c.types?.some(t => t.startsWith('administrative_area_level_')); return isAdmin && c.shortText === target; }); }); } // Example usage: // const filtered = filterByAdminArea(v4Response.results, 'CA');
依郵遞區號篩選
將要求中的 address.postalCode 與每個結果中的 postalAddress.postalCode 進行比對。比較前,您必須先將輸入和結果郵遞區號標準化。標準化邏輯會因地區而異。基本做法是移除空格和連字號,並轉換為一致的大小寫。
如要處理郵遞區號前置碼 (例如英國的「L2」) 或後置碼 (例如美國郵遞區號的「+4」),可能需要更進階的正規化。具體所需的標準化邏輯會因國家/地區和郵遞區號格式而異。您可能需要調整提供的正規化函式,或為指定區域實作更複雜的邏輯。
提供的範例會處理美國郵遞區號,即使提供或傳回的是 5+4 碼的郵遞區號,也能比對前 5 碼。
Python 程式碼範例 (以美國郵遞區號為重點)
import re def normalize_postal_code_us(pc): # Basic normalization for US: uppercase, alphanumeric only if not pc: return "" normalized = re.sub(r'[^A-Z0-9]', '', pc.upper()) # Return only the first 5 digits for US ZIP codes return normalized[:5] def filter_by_postal_code_us(results, postal_code): normalized_input = normalize_postal_code_us(postal_code) if not normalized_input: return [] filtered_results = [] for res in results: pa_pc = res.get('postalAddress', {}).get('postalCode', '') if normalize_postal_code_us(pa_pc) == normalized_input: filtered_results.append(res) return filtered_results # Example usage: # Matches '94043', '94043-1351', '940431351' # filtered = filter_by_postal_code_us(v4_response.get('results', []), '94043') # filtered = filter_by_postal_code_us(v4_response.get('results', []), '94043-1234')
Node.js 程式碼範例 (以美國郵遞區號為重點)
function normalizePostalCodeUs(pc) { // Basic normalization for US: uppercase, alphanumeric only const normalized = (pc || '').toUpperCase().replace(/[^A-Z0-9]/g, ''); // Return only the first 5 digits for US ZIP codes return normalized.substring(0, 5); } function filterByPostalCodeUs(results, postalCode) { const normalizedInput = normalizePostalCodeUs(postalCode); if (!normalizedInput) { return []; } return results.filter(res => { const paPc = res.postalAddress?.postalCode || ''; return normalizePostalCodeUs(paPc) === normalizedInput; }); } // Example usage: // Matches '94043', '94043-1351', '940431351' // const filtered = filterByPostalCodeUs(v4Response.results, '94043'); // const filtered = filterByPostalCodeUs(v4Response.results, '94043-1234');
從 v3 反向地理編碼遷移
如果您使用 v3 反向地理編碼將座標轉換為地址,請改用 v4 的「反向地理編碼位置」方法,該方法接受 GET 要求。
v4 版 API 變更了多個參數的名稱、結構和支援項目。強烈建議您使用欄位遮罩,指定要在回應中傳回的欄位。
要求參數變更
| v3 參數 | v4 參數 | 附註 |
|---|---|---|
language |
languageCode |
已重新命名。 |
region |
regionCode |
已重新命名。 |
result_type |
types |
已重新命名,使用重複的查詢參數。 |
location_type |
granularity |
已重新命名,使用重複的查詢參數。 |
extra_computations |
已移除 | 已由 SearchDestinations 方法取代。 |
回應欄位變更
| v3 欄位 | 第 4 版欄位 | 附註 |
|---|---|---|
status、error_message |
已移除 | 第 4 版使用 HTTP 狀態碼和錯誤主體。 |
results.address_components.long_name/results.address_components.short_name |
results.addressComponents.longText/results.addressComponents.shortText |
已重新命名。 |
results.geometry.location_type |
results.granularity |
已重新命名。 |
results.geometry.location |
results.location |
欄位名稱:lat/lng -> latitude/longitude。 |
results.geometry.viewport |
results.viewport |
欄位名稱:northeast/southwest -> high/low。 |
| 新功能 | results.addressComponents.languageCode |
特定地址元件的語言。 |
| 新功能 | results.bounds |
使用 high/low 明確設定界線。 |
| 新功能 | results.place |
地點的資源名稱。 |
| 新功能 | results.postalAddress |
結構化 PostalAddress 物件。 |
從第 3 版地址描述元遷移
如果您使用 address_descriptor 透過 Geocoding v3 取得地點的額外資訊,請改用SearchDestinationsResponse 的 landmarks 欄位。
從 v3 Place 地理編碼遷移
如果您使用 place_id 透過 Geocoding v3 取得特定地點 ID 的地址,請遷移至 v4 Place Geocoding 方法,該方法接受 GET 要求。
v4 版 API 變更了多個參數的名稱、結構和支援項目。強烈建議您使用欄位遮罩,指定要在回應中傳回的欄位。
要求參數變更
| v3 參數 | v4 參數 | 附註 |
|---|---|---|
place_id |
要求 proto 中的 place 欄位 |
地點 ID 現在會以路徑參數 places/{place} 的形式提供,例如:https://geocode.googleapis.com/v4/geocode/places/ChIJj61dQgK6j4AR4GeTYWZsKWw。這會對應至基礎要求的地點欄位。 |
language |
languageCode |
已重新命名。 |
region |
regionCode |
已重新命名。 |
回應欄位變更
| v3 欄位 | 第 4 版欄位 | 附註 |
|---|---|---|
status、error_message |
已移除 | 第 4 版使用 HTTP 狀態碼和錯誤主體。 |
results |
(根目錄) | 第 4 版會傳回單一結果物件,而非 results 陣列。 |
results.address_components.long_name/results.address_components.short_name |
addressComponents.longText/addressComponents.shortText |
已重新命名。 |
results.geometry.location_type |
granularity |
已重新命名。 |
results.geometry.location |
location |
欄位名稱:lat/lng -> latitude/longitude。 |
results.geometry.viewport |
viewport |
欄位名稱:northeast/southwest -> high/low。 |
results.postcode_localities |
postalCodeLocalities |
已重新命名。現在會針對一或多個地區傳回 (需要 v3 > 1)。 |
| 新功能 | addressComponents.languageCode |
特定地址元件的語言。 |
| 新功能 | bounds |
使用 high/low 明確設定界線。 |
| 新功能 | place |
地點的資源名稱。 |
| 新功能 | postalAddress |
結構化 PostalAddress 物件。 |
從 Geocoding Hyperlocal Data 遷移至目的地
Geocoding API v4 的 SearchDestinations 方法將取代 Geocoding API v3 的下列功能:
- 進入
- 導航點
- 建築物外框
- 園區
如果您是使用 Geocoding API v3 取得上述功能,請參閱這份文件,瞭解如何改用 SearchDestinations 方法取得這些功能。本文說明如何在 SearchDestinations 回應中找到這些功能,以及 Geocoding API v3 和 Geocoding API v4 的 SearchDestinations 方法在 API 回應中呈現這些功能時的差異。
進入
如要取得與 destination 相關聯的入口,請使用 destination.entrances 欄位。
請注意,entrance 的格式與 Geocoding API v3 中的入口格式略有不同。destination.entrances 中的每個入口都包含下列欄位:
displayName:這是新的選用欄位,可讓使用者瞭解入口名稱,例如「B 閘門」。location- 這是LatLng類型的地點,與 Geocoding API v3 中使用的格式不同。tags:這與 Geocoding API v3 中入口的tags欄位相同。place- 類似於 Geocoding API v3 中入口的buildingPlaceId欄位。不過,這個欄位中的地點 ID 可以是任何類型的地點,不一定只是建築物。
導航點
如要取得與 destination 相關聯的導覽點,請使用 destination.navigationPoints 欄位。
請注意,navigationPoint 的格式與 Geocoding API v3 中的導航點格式略有不同。destination.navigationPoints 中的每個導覽點都包含下列欄位:
displayName:這是新的選填欄位,可為導航點提供使用者可理解的名稱,例如「5th Ave」。location- 這是LatLng類型的地點,與 Geocoding API v3 中使用的格式不同。travelModes- 這與 Geocoding API v3 中導航點的restrictedTravelModes欄位類似。可能的列舉值相同,唯一差別在於這個欄位現在代表導航點可接受的交通方式,而非受限的交通方式。usage:這是新欄位,內含導覽點支援的用途。請注意,大多數導覽點都會有UNKNOWN用法,但這不一定表示導覽點的用法受到任何限制。
建築物外框
如要取得與 destination 相關聯的建築物外框,請使用 destination 中代表建築物的 placeView 物件的 displayPolygon 欄位。您可以透過 placeView 欄位,檢查每個 placeView 是否為建築物。placeView.structureType如果結構類型為 BUILDING,您可以從 placeView.displayPolygon 欄位取得大綱。placeView 也會提供 Geocoding API 第 3 版沒有的建築物額外欄位。
destination 可在下列欄位中包含代表建築物的 placeView 物件:
destination.primary- 這是目的地主要位置。destination.containingPlaces- 這個重複欄位可容納「包含」主要地點的較大地點。舉例來說,如果主要地點是subpremise,containingPlaces通常會保留代表建築物的placeView。destination.subDestinations- 這個重複欄位可保留主要地點的子目的地。例如建築物中的個別公寓單位。這個欄位通常不會有代表建築物的placeView。
請注意,placeView.displayPolygon 的格式符合 Geocoding API 第 3 版中的建築物外框格式,也就是使用 RFC 7946 格式的 GeoJSON 格式。
園區
與建構大綱類似,如要取得與 destination 相關聯的根據,您應使用 destination 中代表根據的 placeView 物件的 displayPolygon 欄位。destination您可以透過 placeView.structureType 欄位,檢查每個 placeView 是否為理由。如果結構類型為 GROUNDS,您可以從 placeView.displayPolygon 欄位取得大綱。placeView 也會提供其他欄位,說明 Geocoding API 第 3 版未提供的理由。
destination 可以有 placeView 物件,代表下列欄位中的理由:
destination.primarydestination.containingPlacesdestination.subDestinations
請注意,placeView.displayPolygon 的格式與 Geocoding API v3 中的地表輪廓格式相同,也就是使用 RFC 7946 格式的 GeoJSON 格式。
結果精確度
在 Geocoding API v3 中,回應幾何圖形中的 location_type 欄位會指出結果的精確度,部分用戶端會根據這些值 (ROOFTOP、RANGE_INTERPOLATED、GEOMETRIC_CENTER 和 APPROXIMATE) 排序或篩選結果。在標準 Geocoding API v4 遷移作業中,這個欄位會重新命名為 granularity。
在 Destinations API (v4 SearchDestinations) 中,沒有 location_type
欄位。而是以不同方式處理空間資訊:
- 不需要手動篩選用戶端:標準地理編碼服務會提供不同精細程度的多個結果,但
SearchDestinations方法會盡可能解析為單一最佳目的地,減少模糊不清的情況。這樣一來,用戶就不必依位置類型篩選,即可判斷哪個結果最合適。 - 以結構類型和顯示多邊形表示的空間資訊:
空間幾何和結構會以以下方式表示:
displayPolygon(適用於精確幾何圖形)。placeView物件中的structureType欄位。
- 結構類型對應:
structureType、POINT、BUILDING或SECTION一般會對應到先前稱為ROOFTOP的項目。structureType的GROUNDS通常會對應至GEOMETRIC_CENTER。
使用欄位遮罩要求這些功能
如「選擇要傳回的欄位」一文所述,SearchDestinations 方法需要欄位遮罩。您可以將欄位遮罩設為 *,傳回所有欄位,也可以設為要接收的特定欄位。舉例來說,下列 API 要求會設定欄位遮罩,以接收取得目的地入口、導覽點、建築物外框和地面所需的所有欄位:
curl -X POST -d '{"place": "places/ChIJG3kh4hq6j4AR_XuFQnV0_t8"}' \
-H "X-Goog-Api-Key: API_KEY" \
-H "Content-Type: application/json" \
-H "X-Goog-FieldMask: destinations.entrances,destinations.navigationPoints,destinations.primary,destinations.containingPlaces,destinations.subDestinations" \
https://geocode.googleapis.com/v4/geocode/destinations
安全性考量
Geocoding API 第 4 版是設計為伺服器對伺服器 API。JavaScript 使用者無法直接從第 3 版遷移至第 4 版。使用 API 金鑰直接從用戶端 JavaScript (例如瀏覽器) 呼叫 v4 方法,會導致 API 金鑰遭竊和濫用的風險大幅提高。
HTTP 參照網址限制雖然實用,但對於網路服務端點來說,保護力仍不足,因為攻擊者可以輕易略過這項限制,在要求中偽造 Referer 標頭。
建議做法
建議您透過自己的後端伺服器使用 Geocoding API 第 4 版。您的用戶端應用程式應向這個中介伺服器提出要求,然後中介伺服器會使用受保護的 API 金鑰 (例如儲存在環境變數或密鑰管理工具中的金鑰),安全地呼叫 Google API。確保 API 金鑰絕不會在前端程式碼中曝光。
用戶端需求替代方案
如果您有用戶端需求,需要進行地理編碼,請考慮使用現有的用戶端解決方案:
- Maps JavaScript API 中的地理編碼服務:地理編碼服務會繼續使用 v3 後端,且專為瀏覽器環境設計。
- Places UI Kit:使用 Places UI Kit,包括地點自動完成元素,取得地址相關使用者介面元素。