Geocoding API v4에는 API v3의 기능을 대체하는 몇 가지 새로운 메서드가 도입되었습니다. 이 가이드에서는 새로운 v4 메서드를 사용하도록 앱을 이전하는 방법을 보여줍니다.
새로운 v4 메서드에 기존 API 키를 사용할 수 있습니다. 하지만 API v3에서 할당량 상향을 요청한 경우 새 v4 API에서 상향을 요청해야 합니다.
v3 정방향 지오코딩에서 이전
v3 Geocoding을 사용하여 주소를 지오코딩하는 경우 GET 요청을 허용하는 v4 주소 지오코딩 메서드로 마이그레이션해야 합니다.
v4 API는 여러 매개변수의 이름, 구조, 지원을 변경합니다. 응답에서 반환할 필드를 지정하려면 필드 마스크를 사용하는 것이 좋습니다.
요청 매개변수 변경사항
| v3 매개변수 | v4 매개변수 | 참고 |
|---|---|---|
address, components |
address |
이제 비정형 주소 (v3 address)가 URL 경로에 전달됩니다. 구조화된 주소 구성요소 (v3 components)는 address.* 쿼리 매개변수로 전달할 수 있습니다. v3 구성요소 필터 재현을 참고하세요. |
bounds |
locationBias.rectangle |
이름이 변경되었습니다. 구조가 객체로 변경되었습니다. |
language |
languageCode |
이름이 변경되었습니다. 생략하면 v3은 Accept-Language 헤더를 사용하거나 기본적으로 en를 사용하지만 v4는 기본적으로 위치의 현지 언어와 스크립트를 사용합니다. |
region |
regionCode |
이름이 변경되었습니다. 생략하면 v3은 기본적으로 us로 설정되지만 v4에는 기본값이 없습니다. |
extra_computations |
삭제됨 | SearchDestinations 메서드로 대체되었습니다. |
응답 필드 변경사항
| v3 필드 | v4 필드 | 참고 |
|---|---|---|
status, error_message |
삭제됨 | v4는 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 구성요소 필터 재현
Geocoding v3의 정방향 지오코딩에는 특정 구성요소 (예: components=country:US)의 결과를 하드 필터링할 수 있는 components 매개변수가 포함되어 있습니다. v4의 정방향 지오코딩은 요청 매개변수에서 이러한 유형의 하드 필터링을 지원하지 않습니다. v4에서는 주소 정보를 경로의 단일 비정형 문자열로 제공하거나 address.addressLines, address.locality, address.administrativeArea, address.postalCode, address.regionCode와 같은 정형 쿼리 매개변수로 제공할 수 있습니다.
구조화된 파라미터는 엄격한 필터로 작동하지 않습니다. 대신 제공된 모든 구성요소가 결합되어 API가 지오코딩을 시도할 전체 주소를 형성합니다. API는 모든 구성요소에서 지정된 전체 주소와 가장 일치하는 항목을 검색합니다. 구조화된 방식으로 구성요소를 제공하면 특히 주소 정보가 별도의 양식 필드에서 수집되는 경우 API가 의도를 더 잘 이해하는 데 도움이 될 수 있습니다. 이렇게 하면 각 필드의 정보 유형이 명확하므로 API가 각 구성요소 내의 사소한 오타나 모호성을 처리하는 데 도움이 될 수 있습니다.
v3의 하드 구성요소 필터와 유사한 동작을 구현하려면 응답의 postalAddress 및 addressComponents 객체를 기반으로 v4 API에서 반환한 results 배열에 클라이언트 측 필터링을 구현해야 합니다.
다음 표에서는 v3 components 필터와 v4 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 코드에 해당하는 하위 구역이 우편 주소의 표준 표현에 포함되지 않습니다. 예를 들어 스페인에서는 행정 구역 수준 1 (예: 카나리아 제도의 경우 'CN')이 addressComponents에 있을 수 있지만 postalAddress.administrativeArea에는 수준 2 구역 (예: '산타크루스데테네리페')이 포함될 수 있습니다. 둘째, 일부 지역에서는 하위 구역의 약어가 흔히 사용되지 않으며 postalAddress.administrativeArea에서 더 긴 이름으로 표시됩니다. 비슷한 이유로 하위 구역에 해당하는 주소 구성요소의 addressComponents.shortText가 하위 구역의 ISO 3166-2 코드 서픽스와 일치하지 않을 수 있습니다. 또한 경우에 따라 n이 1보다 큰 administrative_area_level_n의 주소 구성요소에 하위 행정 구역이 표시될 수 있습니다.
가장 포괄적인 결과를 얻으려면 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')를 처리하려면 더 고급 정규화가 필요할 수 있습니다. 필요한 구체적인 정규화 로직은 국가 및 관련 우편번호 형식에 따라 다릅니다. 타겟팅하는 지역에 맞게 제공된 정규화 함수를 조정하거나 더 정교한 로직을 구현해야 할 수도 있습니다.
제공된 예시는 미국 우편번호를 처리하며 ZIP+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 역 지오코딩을 사용하여 좌표를 주소로 변환하는 경우 GET 요청을 허용하는 v4 위치 역 지오코딩 메서드로 마이그레이션해야 합니다.
v4 API는 여러 매개변수의 이름, 구조, 지원을 변경합니다. 응답에서 반환할 필드를 지정하려면 필드 마스크를 사용하는 것이 좋습니다.
요청 매개변수 변경사항
| v3 매개변수 | v4 매개변수 | 참고 |
|---|---|---|
language |
languageCode |
이름이 변경되었습니다. 생략하면 v3은 Accept-Language 헤더를 사용하거나 기본적으로 en를 사용하지만 v4는 기본적으로 위치의 현지 언어와 스크립트를 사용합니다. |
region |
regionCode |
이름이 변경되었습니다. 생략하면 v3은 기본적으로 us로 설정되지만 v4에는 기본값이 없습니다. |
result_type |
types |
이름이 변경되었습니다. 반복되는 쿼리 매개변수를 사용합니다. |
location_type |
granularity |
이름이 변경되었습니다. 반복되는 쿼리 매개변수를 사용합니다. |
extra_computations |
삭제됨 | SearchDestinations 메서드로 대체되었습니다. |
응답 필드 변경사항
| v3 필드 | v4 필드 | 참고 |
|---|---|---|
status, error_message |
삭제됨 | v4는 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 객체. |
v3 주소 설명자에서 이전
Geocoding API v3에서 extra_computations=ADDRESS_DESCRIPTORS를 전달하면 landmarks[] 및 areas[]가 포함된 address_descriptor 객체가 반환되었습니다. Geocoding API v4에서는 이 기능이 SearchDestinations 메서드 (POST /v4/geocode/destinations)로 대체되며, 이 메서드는 각 Destination 객체 내에서 직접 풍부한 공간 컨텍스트를 반환합니다.
다음 표에서는 기존 v3 address_descriptor 필드를 상응하는 v4 SearchDestinations 필드에 매핑합니다.
v3 address_descriptor 필드 |
v4 SearchDestinations 필드 |
이전 참고사항 |
|---|---|---|
landmarks[] |
destinations[].landmarks[] |
X-Goog-FieldMask에서 destinations.landmarks을 요청합니다. |
landmarks[].place_id |
landmarks[].place.placeId |
place (PlaceView) 객체 내에 래핑됩니다. |
landmarks[].display_name |
landmarks[].place.displayName |
현지화된 텍스트 (text 및 languageCode) |
landmarks[].types |
landmarks[].place.types |
장소 유형 문자열의 배열입니다. |
landmarks[].spatial_relationship |
landmarks[].relationalDescription |
v4는 원시 enum (ACROSS_THE_ROAD, AROUND_THE_CORNER) 대신 현지화되고 인간이 읽을 수 있는 문구 (예: "Across from Central Park")를 반환합니다. |
landmarks[].straight_line_distance_meters |
landmarks[].straightLineDistanceMeters |
lower camelCase로 이름이 변경되었습니다. |
landmarks[].travel_distance_meters |
landmarks[].travelDistanceMeters |
lower camelCase로 이름이 변경되었습니다. |
areas[] (containment enum) |
destinations[].containingPlaces[] 및 subDestinations[] |
구조적 계층 구조에 가장 가까운 상응 항목: 둘러싸는 복합단지, 캠퍼스, 쇼핑몰, 건물이 containingPlaces[] 및 subDestinations[]에서 구조화된 PlaceView 객체로 반환됩니다(structureType가 GROUNDS 또는 BUILDING로 설정되고 선택적 displayPolygon 윤곽선이 있음). 근처/구역 근접 지역 또는 v3 containment enum (NEAR, WITHIN, OUTSKIRTS)을 직접 1:1로 대체할 수 없습니다. |
v3 장소 지오코딩에서 이전
place_id를 사용하여 Geocoding v3로 특정 장소 ID의 주소를 가져오는 경우 GET 요청을 허용하는 v4 장소 지오코딩 메서드로 이전해야 합니다.
v4 API는 여러 매개변수의 이름, 구조, 지원을 변경합니다. 응답에서 반환할 필드를 지정하려면 필드 마스크를 사용하는 것이 좋습니다.
요청 매개변수 변경사항
| v3 매개변수 | v4 매개변수 | 참고 |
|---|---|---|
place_id |
요청 proto의 place 필드 |
이제 장소 ID가 경로 매개변수 places/{place}로 제공됩니다(예: https://geocode.googleapis.com/v4/geocode/places/ChIJj61dQgK6j4AR4GeTYWZsKWw). 이는 기본 요청의 장소 필드에 매핑됩니다. |
language |
languageCode |
이름이 변경되었습니다. 생략하면 v3은 Accept-Language 헤더를 사용하거나 기본적으로 en를 사용하지만 v4는 기본적으로 위치의 현지 언어와 스크립트를 사용합니다. |
region |
regionCode |
이름이 변경되었습니다. 생략하면 v3은 기본적으로 us로 설정되지만 v4에는 기본값이 없습니다. |
응답 필드 변경사항
| v3 필드 | v4 필드 | 참고 |
|---|---|---|
status, error_message |
삭제됨 | v4는 HTTP 상태 코드와 오류 본문을 사용합니다. |
results |
(root) | v4는 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에서 Destinations로 이전하기
Geocoding API v3의 다음 기능은 Geocoding API v4의 SearchDestinations 메서드로 대체됩니다.
- 진입수
- 탐색 지점
- 건물 윤곽선
- 입장권
위의 기능에 Geocoding API v3를 사용하고 있었다면 이 문서를 참고하여 SearchDestinations 메서드를 대신 사용하여 이러한 기능을 가져오세요.
이 문서에서는 SearchDestinations 응답에서 이러한 기능을 찾을 수 있는 위치와 Geocoding API v3와 Geocoding API v4의 SearchDestinations 메서드 간에 API 응답에서 이러한 기능이 표시되는 방식의 차이점을 설명합니다.
진입수
destination와 연결된 입구를 가져오려면 destination.entrances 필드를 사용합니다.
destination.entrances의 각 entrance에는 다음 필드가 있습니다 (기존 v3 buildings.entrances 스키마 대체).
displayName- 사람이 읽을 수 있는 입구 이름이 포함된 새로운 선택적 필드입니다(예:"Gate B").location-latitude및longitude를 사용하는LatLng유형의 위치입니다(v3lat/lng대체).tags- Geocoding API v3 항목 (예:PREFERRED)의tags필드와 동일합니다.place- 장소의 리소스 이름 (예:places/ChIJ...)으로, Geocoding API v3의building_place_id필드를 대체합니다. v4에서 이 장소는 건물뿐만 아니라 모든 목적지 구조 (건물, 캠퍼스 또는 공원)를 나타낼 수 있습니다.
탐색 지점
destination와 연결된 탐색 지점을 가져오려면 destination.navigationPoints 필드를 사용합니다.
destination.navigationPoints의 각 navigationPoint에는 다음 필드가 있습니다 (기존 v3 navigation_points 스키마 대체).
navigationPointToken- Routes APIComputeRoutes메서드 (Waypoint.navigationPointToken)에서 이 특정 내비게이션 지점으로 경로를 지정하는 데 사용되는 암호화된 토큰 문자열입니다. 내비게이션 지점 토큰을 사용하여 경로 지정을 참고하세요.displayName- 사람이 읽을 수 있는 내비게이션 지점 이름(예:"5th Ave")이 포함된 새로운 선택적 필드입니다.location-latitude및longitude를 사용하는LatLng유형의 위치입니다.travelModes- Geocoding API v3의restricted_travel_modes필드와 유사하지만 v4에서는 제한된 이동 수단이 아닌 허용되는 이동 수단 (DRIVE,WALK)을 지정합니다.usage- 탐색 지점에 지원되는 도착 사용 사례 (예:PICKUP,DROPOFF,PARKING)를 지정하는 새 필드입니다.
건물 윤곽선
destination와 연결된 건물 윤곽선을 가져오려면 건물을 나타내는 destination에 있는 placeView 객체의 displayPolygon 필드를 사용합니다 (기존 v3 buildings.building_outlines 배열 대체). 각 placeView에 대해 placeView.structureType 필드가 있는 건물인지 확인합니다. 구조 유형이 BUILDING인 경우 placeView.displayPolygon 필드에서 개요를 가져올 수 있습니다. placeView에는 Geocoding API v3에 없었던 건물에 대한 추가 필드도 있습니다.
destination에는 다음 필드에 건물을 나타내는 placeView 객체가 있을 수 있습니다.
destination.primary- 목적지의 기본 장소입니다.destination.containingPlaces- 기본 장소를 '포함'하는 더 큰 장소를 보유하는 반복되는 입력란입니다. 예를 들어 기본 장소가subpremise인 경우containingPlaces는 일반적으로 건물을 나타내는placeView를 보유합니다.destination.subDestinations- 기본 장소의 하위 목적지 (예: 건물 내 개별 아파트 단위 또는 스위트룸)를 보유하는 반복되는 입력란입니다.
placeView.displayPolygon의 형식은 RFC 7946 형식을 사용하는 GeoJSON 형식인 Geocoding API v3의 건물 윤곽선 형식과 일치합니다.
입장권
건물 윤곽선과 마찬가지로 destination와 연결된 부지를 가져오려면 부지를 나타내는 destination에 있는 placeView 객체의 displayPolygon 필드를 사용합니다 (기존 v3 grounds 배열 대체). 각 placeView에 대해 placeView.structureType 필드가 있는 지면 다각형인지 확인합니다. 구조 유형이 GROUNDS인 경우 placeView.displayPolygon 필드에서 윤곽선을 가져올 수 있습니다. placeView에는 Geocoding API v3에 없었던 부지에 대한 추가 필드도 있습니다.
destination에는 다음 필드에 부지를 나타내는 placeView 객체가 있을 수 있습니다.
destination.primarydestination.containingPlacesdestination.subDestinations
placeView.displayPolygon의 형식은 RFC 7946 형식을 사용하는 GeoJSON 형식인 Geocoding API v3의 부지 윤곽선 형식과 일치합니다.
결과의 정밀도
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필드입니다.
- 구조 유형 매핑:
POINT,BUILDING또는SECTION의structureType는 일반적으로 이전에ROOFTOP라고 불렸던 것에 해당합니다.GROUNDS의structureType은 일반적으로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 v3 또는 Geocoding++에서 SearchDestinations로 복잡한 워크플로를 마이그레이션할 때는 다음 코드 레시피를 사용하여 일반적인 공간 및 주소 구조를 추출하세요.
최적의 건물 다각형 추출
위치 또는 목적지의 건물 윤곽선을 렌더링하려면 다음 단계를 따르세요.
primary장소에structureType === 'BUILDING'이 있고displayPolygon가 포함되어 있는지 확인합니다.- 그렇지 않은 경우
containingPlaces를 검사하여 둘러싸는 건물을 찾습니다 (기본 목적지가 더 큰 건물의 하위 목적지인 경우 유용함). - 둘러싸는 건물이 없으면
subDestinations를 확인하여 개별 건물이 나열되어 있는지 확인합니다.
Python 코드 예시
def get_best_building_polygon(destination): primary = destination.get('primary', {}) if primary.get('structureType') == 'BUILDING' and 'displayPolygon' in primary: return primary['displayPolygon'] # Check containing places for the parent building for place in destination.get('containingPlaces', []): if place.get('structureType') == 'BUILDING' and 'displayPolygon' in place: return place['displayPolygon'] # Fallback to sub-destinations if available for place in destination.get('subDestinations', []): if place.get('structureType') == 'BUILDING' and 'displayPolygon' in place: return place['displayPolygon'] return None
Node.js 코드 예시
function getBestBuildingPolygon(destination) { const { primary = {}, containingPlaces = [], subDestinations = [] } = destination; if (primary.structureType === 'BUILDING' && primary.displayPolygon) { return primary.displayPolygon; } const parentBuilding = containingPlaces.find( p => p.structureType === 'BUILDING' && p.displayPolygon ); if (parentBuilding) { return parentBuilding.displayPolygon; } const subBuilding = subDestinations.find( p => p.structureType === 'BUILDING' && p.displayPolygon ); return subBuilding?.displayPolygon || null; }
근거 개요 추출
아파트 단지, 기업 캠퍼스, 쇼핑센터 또는 공원의 경계가 필요한 경우:
primary장소가 전체 단지 (structureType === 'GROUNDS')를 나타내는 경우primary.displayPolygon를 사용합니다.primary장소가 대형 단지 내에 있는 건물 또는 입구인 경우containingPlaces에서 둘러싸고 있는 부지를 찾습니다.
Python 코드 예시
def get_grounds_polygon(destination): primary = destination.get('primary', {}) if primary.get('structureType') == 'GROUNDS' and 'displayPolygon' in primary: return primary['displayPolygon'] for place in destination.get('containingPlaces', []): if place.get('structureType') == 'GROUNDS' and 'displayPolygon' in place: return place['displayPolygon'] return None
Node.js 코드 예시
function getGroundsPolygon(destination) { const { primary = {}, containingPlaces = [] } = destination; if (primary.structureType === 'GROUNDS' && primary.displayPolygon) { return primary.displayPolygon; } const groundsPlace = containingPlaces.find( p => p.structureType === 'GROUNDS' && p.displayPolygon ); return groundsPlace?.displayPolygon || null; }
주소 표시와 최종 목적지 도착을 위한 명소 선택
Geocoding v3 address_descriptor에서 spatial_relationship enum (WITHIN, BESIDE, BEHIND, NEAR, ACROSS_THE_ROAD, AROUND_THE_CORNER)을 반환했습니다. SearchDestinations:
- 원시 관계 enum이 없습니다. 대신
relationalDescription.text를 직접 사용하세요. 여기에는"Across from Central Park"또는"Behind the convention center"와 같이 현지화되어 바로 표시할 수 있는 문구가 포함됩니다."Near "를 수동으로 앞에 추가하지 마세요. tags를 사용하여 사용 사례에 적합한 랜드마크를 선택합니다.ARRIVAL: 목적지와 바로 인접해 있거나, 마주 보고 있거나, 길 건너편에 있는 세부 지역의 랜드마크입니다 (일반적으로 50~100m 이내). 실시간 운전자 도착, 택배 배송 확인 또는 인앱 도착 카드에 적합합니다.ADDRESS: 주변 지역 (일반적으로 100~500미터 이내)에서 현지에서 유명한 랜드마크입니다. 고객 대상 결제, 주문 검토 또는 이동 전 목적지 모호성 해소에 가장 적합합니다.- 명소에
ADDRESS및ARRIVAL태그가 모두 있는 경우 해당 명소는 주변에서 잘 알려져 있고 목적지와 바로 인접해 있습니다.
Python 코드 예시
def get_best_relational_landmark(destination, is_last_mile=True): """Select the best landmark based on user context. Args: destination: Destination object from SearchDestinations. is_last_mile: True for arrival and delivery guidance (prefers ARRIVAL tags). False for address display and disambiguation (prefers ADDRESS tags). Returns: Dict with landmark description, distances, tags, and placeId, or None. """ landmarks = destination.get('landmarks', []) if not landmarks: return None target_tag = 'ARRIVAL' if is_last_mile else 'ADDRESS' # Landmarks are ranked by relevance and proximity. Select the first candidate matching the target tag. for lm in landmarks: tags = lm.get('tags', []) if target_tag in tags or ('ARRIVAL' in tags and 'ADDRESS' in tags): description = lm.get('relationalDescription', {}).get('text') if description: return { 'description': description, 'travelDistanceMeters': lm.get('travelDistanceMeters'), 'straightLineDistanceMeters': lm.get('straightLineDistanceMeters'), 'tags': tags, 'placeId': lm.get('place', {}).get('placeId') } # Fallback to the first available landmark with a relational description if no tagged match is found for lm in landmarks: description = lm.get('relationalDescription', {}).get('text') if description: return { 'description': description, 'travelDistanceMeters': lm.get('travelDistanceMeters'), 'straightLineDistanceMeters': lm.get('straightLineDistanceMeters'), 'tags': lm.get('tags', []), 'placeId': lm.get('place', {}).get('placeId') } return None
Node.js 코드 예시
/** * Select the best landmark based on user context. * * @param {Object} destination Destination object from SearchDestinations. * @param {boolean} [isLastMile=true] True for arrival and delivery guidance * (prefers ARRIVAL tags). False for address display and disambiguation * (prefers ADDRESS tags). * @return {Object|null} */ function getBestRelationalLandmark(destination, isLastMile = true) { const landmarks = destination.landmarks || []; if (!landmarks.length) return null; const targetTag = isLastMile ? 'ARRIVAL' : 'ADDRESS'; // Landmarks are ranked by relevance and proximity. Select the first candidate matching the target tag. const match = landmarks.find((lm) => { const tags = lm.tags || []; return (tags.includes(targetTag) || (tags.includes('ARRIVAL') && tags.includes('ADDRESS'))) && lm.relationalDescription?.text; }) || landmarks.find((lm) => lm.relationalDescription?.text); if (match) { return { description: match.relationalDescription.text, travelDistanceMeters: match.travelDistanceMeters, straightLineDistanceMeters: match.straightLineDistanceMeters, tags: match.tags || [], placeId: match.place?.placeId || null, }; } return null; }
차량 내비게이션 지점 및 선호하는 입구로 가는 경로
라스트 마일 배송 및 도착 워크플로는 상호 보완적인 두 가지 유형의 공간 액세스 포인트를 결합합니다.
- 세부 경로 안내:
navigationPoints를 사용하여 차량을 지정된 도로 하차 지점으로 안내합니다. 탐색 지점은 근접성과 관련성에 따라 미리 순위가 매겨지므로 원하는 이동 수단 (예:'DRIVE')과 사용 태그 (예:'DROPOFF'또는'PICKUP')가 있는 첫 번째 후보가 최적의 차량 경유지를 제공합니다.navigationPointToken를 Routes APIComputeRoutes메서드 (Waypoint.navigationPointToken) 또는 Navigation SDK로 전송합니다. 도로에 스냅된 운전 지점이 없으면 건물 입구 또는 기본 중심점으로 대체합니다. - 실제 출입구 액세스:
destinations.entrances를 사용하여 도보 배송 기사 또는 승객을 건물 입구로 안내합니다.'PREFERRED'의tags를 확인하여 직접적인 물리적 액세스를 제공할 가능성이 높은 입구를 찾습니다. 입구 데이터를 사용할 수 없는 경우 보행자 내비게이션 지점 ('WALK'를 포함한travelModes) 또는 기본 중심점으로 대체합니다.
Python 코드 예시
def get_routing_and_arrival_points(destination, usage_tag=None): navigation_points = destination.get('navigationPoints', []) entrances = destination.get('entrances', []) primary_location = destination.get('primary', {}).get('location') # 1. Doorstep / Physical Entrance # Prefer PREFERRED entrance -> any entrance -> WALK nav point -> primary location preferred_entrance = None for ent in entrances: if 'PREFERRED' in ent.get('tags', []): preferred_entrance = ent break if not preferred_entrance and entrances: preferred_entrance = entrances[0] walk_nav_point = None for np in navigation_points: if 'WALK' in np.get('travelModes', []): walk_nav_point = np break if preferred_entrance: doorstep_location = preferred_entrance.get('location') elif walk_nav_point: doorstep_location = walk_nav_point.get('location') else: doorstep_location = primary_location # 2. Vehicle Routing Waypoint # Find a driving navigation point. If usage_tag (such as 'DROPOFF' or 'PICKUP') # is specified, prioritize a candidate with that usage tag; otherwise fall back # to the first available driving point. drive_nav_point = None fallback_drive_point = None for np in navigation_points: if 'DRIVE' in np.get('travelModes', []): if usage_tag and usage_tag in np.get('usages', []): drive_nav_point = np break # Exact match for desired usage tag elif fallback_drive_point is None: fallback_drive_point = np # First driving point as fallback if not drive_nav_point: drive_nav_point = fallback_drive_point if drive_nav_point: vehicle_location = drive_nav_point.get('location') nav_token = drive_nav_point.get('navigationPointToken') elif preferred_entrance: vehicle_location = preferred_entrance.get('location') nav_token = None else: vehicle_location = primary_location nav_token = None return { 'vehicleRoutingWaypoint': { 'navigationPointToken': nav_token, 'location': vehicle_location, }, 'doorstepLocation': doorstep_location, }
Node.js 코드 예시
function getRoutingAndArrivalPoints(destination, usageTag = null) { const navigationPoints = destination.navigationPoints || []; const entrances = destination.entrances || []; const primaryLocation = destination.primary?.location || null; // 1. Doorstep / Physical Entrance const preferredEntrance = entrances.find(ent => ent.tags?.includes('PREFERRED')) || entrances[0] || null; const walkNavPoint = navigationPoints.find(np => np.travelModes?.includes('WALK')) || null; const doorstepLocation = preferredEntrance?.location || walkNavPoint?.location || primaryLocation; // 2. Vehicle Routing Waypoint // Find a driving navigation point. If usageTag (such as 'DROPOFF' or 'PICKUP') // is specified, prioritize a candidate with that usage tag; otherwise fall back // to the first available driving point. const driveNavPoint = (usageTag && navigationPoints.find(np => np.travelModes?.includes('DRIVE') && np.usages?.includes(usageTag))) || navigationPoints.find(np => np.travelModes?.includes('DRIVE')) || null; let vehicleLocation = primaryLocation; let navToken = null; if (driveNavPoint) { vehicleLocation = driveNavPoint.location; navToken = driveNavPoint.navigationPointToken; } else if (preferredEntrance) { vehicleLocation = preferredEntrance.location; } return { vehicleRoutingWaypoint: { navigationPointToken: navToken, location: vehicleLocation, }, doorstepLocation: doorstepLocation, }; }
보안 고려사항
Geocoding API v4는 서버 간 API로 설계되었습니다. JavaScript 사용자를 위한 v3에서 v4로의 직접 마이그레이션 경로는 없습니다. API 키를 사용하여 클라이언트 측 JavaScript (예: 브라우저)에서 직접 v4 메서드를 호출하면 API 키가 도난 및 오용될 위험이 높습니다.
HTTP 리퍼러 제한은 유용하지만 요청에서 Referer 헤더를 위조하는 공격자가 쉽게 우회할 수 있으므로 웹 서비스 엔드포인트를 충분히 보호하지 못합니다.
권장 방법
Geocoding API v4를 사용하는 권장 방법은 자체 백엔드 서버를 사용하는 것입니다. 클라이언트 애플리케이션은 이 중개 서버에 요청을 보내야 하며, 그러면 중개 서버는 보호된 API 키 (예: 환경 변수 또는 Secret Manager에 저장된 키)를 사용하여 Google API를 안전하게 호출합니다. 이렇게 하면 API 키가 프런트엔드 코드에 노출되지 않습니다.
클라이언트 측 요구사항의 대안
지오코딩이 필요한 클라이언트 측 요구사항이 있는 경우 기존 클라이언트 측 솔루션 중 하나를 사용하는 것이 좋습니다.
- Maps JavaScript API의 지오코딩 서비스: 지오코딩 서비스는 계속해서 v3 백엔드를 사용하며 브라우저 환경에서 사용하도록 설계되었습니다.
- 장소 UI 키트: 주소 관련 사용자 인터페이스 요소에 Place Autocomplete 요소를 포함한 장소 UI 키트를 사용합니다.