Geocoding API v4에는 API v3의 기능을 대체하는 몇 가지 새로운 메서드가 도입되었습니다. 이 가이드에서는 새로운 v4 메서드를 사용하도록 앱을 이전하는 방법을 보여줍니다.
새 v4 메서드와 함께 기존 API 키를 사용할 수 있습니다. 하지만 API v3에서 할당량 상향 조정을 요청한 경우 새 v4 API에서 상향 조정을 요청해야 합니다.
v3 정방향 지오코딩에서 이전
v3 지오코딩을 사용하여 주소를 지오코딩하는 경우 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 주소 설명자에서 이전
address_descriptor를 사용하여 Geocoding v3로 위치에 대한 추가 정보를 가져오는 경우 SearchDestinationsResponse의 landmarks 필드를 사용하도록 이전해야 합니다.
v3 장소 지오코딩에서 이전
지오코딩 v3으로 특정 장소 ID의 주소를 가져오기 위해 place_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 |
(루트) | 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 필드를 사용합니다.
entrance의 형식은 Geocoding API v3의 진입 형식과 약간 다릅니다. destination.entrances의 각 입구에는 다음 필드가 있습니다.
displayName- 출입구의 사람이 읽을 수 있는 이름(예: 'Gate B')이 포함된 새로운 선택적 필드입니다.location- Geocoding API v3에서 사용되는 형식과 다른LatLng유형의 위치입니다.tags- Geocoding API v3의 입구tags필드와 동일합니다.place- Geocoding API v3의 입구buildingPlaceId필드와 유사합니다. 하지만 이 필드의 장소 ID는 건물뿐만 아니라 모든 유형의 장소에 대한 것일 수 있습니다.
탐색 지점
destination와 연결된 탐색 포인트를 가져오려면 destination.navigationPoints 필드를 사용하세요.
navigationPoint의 형식은 Geocoding API v3의 탐색 지점 형식과 약간 다릅니다. destination.navigationPoints의 각 탐색 지점에는 다음 필드가 있습니다.
displayName- 탐색 지점의 사람이 읽을 수 있는 이름(예: '5th Ave')이 포함된 새로운 선택적 필드입니다.location- Geocoding API v3에서 사용되는 형식과 다른LatLng유형의 위치입니다.travelModes- Geocoding API v3의 탐색 지점의restrictedTravelModes필드와 유사합니다. 가능한 enum 값은 동일하며, 유일한 차이점은 이 필드가 이제 제한된 이동 수단이 아닌 내비게이션 지점에 허용되는 이동 수단을 나타낸다는 것입니다.usage- 탐색 지점에서 지원하는 사용 사례가 포함된 새 필드입니다.
건물 윤곽선
destination와 연결된 건물 윤곽선을 가져오려면 건물을 나타내는 destination에 있는 placeView 객체의 displayPolygon 필드를 사용해야 합니다. 각 placeView에 대해 placeView.structureType 필드를 사용하여 건물인지 확인할 수 있습니다. 구조 유형이 BUILDING인 경우 placeView.displayPolygon 필드에서 개요를 가져올 수 있습니다. placeView에는 Geocoding API v3에 없었던 건물에 대한 추가 필드도 있습니다.
destination에는 다음 필드에 건물을 나타내는 placeView 객체가 있을 수 있습니다.
destination.primary- 대상의 기본 위치입니다.destination.containingPlaces- 기본 장소를 '포함'하는 더 큰 장소를 보유할 수 있는 반복되는 입력란입니다. 예를 들어 기본 장소가subpremise인 경우containingPlaces에는 일반적으로 건물을 나타내는placeView이 포함됩니다.destination.subDestinations- 기본 장소의 하위 목적지를 보유할 수 있는 반복되는 필드입니다. 예를 들어 건물의 개별 아파트 단위입니다. 이 필드에는 일반적으로 건물을 나타내는placeView가 없습니다.
placeView.displayPolygon의 형식은 RFC 7946 형식을 사용하는 GeoJSON 형식인 Geocoding API v3의 건물 윤곽선 형식과 일치합니다.
입장권
건물 윤곽선과 마찬가지로 destination와 연결된 부지를 가져오려면 부지를 나타내는 destination에 있는 placeView 객체의 displayPolygon 필드를 사용해야 합니다. 각 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 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 키트를 사용합니다.