Geocoding v3'ten v4'e geçiş

Avrupa Ekonomik Alanı'ndaki (AEA) geliştiriciler

Geocoding API v4, API'nin v3 sürümündeki işlevlerin yerini alan birkaç yeni yöntem sunar. Bu kılavuzda, uygulamanızı yeni v4 yöntemlerini kullanacak şekilde nasıl taşıyacağınız gösterilmektedir.

Mevcut API anahtarlarınızı yeni v4 yöntemleriyle kullanabilirsiniz. Ancak API'nin 3. sürümünde kota artışı talep ettiyseniz yeni 4. sürüm API'lerde de artış talep etmeniz gerekir.

V3 ileriye doğru coğrafi kodlamadan taşıma

Adresleri coğrafi olarak kodlamak için v3 Geocoding'i kullanıyorsanız GET isteğini kabul eden v4 Geocode an address yöntemine geçmeniz gerekir.

v4 API, çeşitli parametrelerin adlarını, yapısını ve desteğini değiştirir. Yanıtta döndürülmesini istediğiniz alanları belirtmek için alan maskesi kullanmanızı önemle tavsiye ederiz.

İstek parametresi değişiklikleri

v3 Parametresi v4 parametresi Notlar
address, components address Yapılandırılmamış adres (v3 address) artık URL yolunda iletilir. Yapılandırılmış adres bileşenleri (v3 components), address.* sorgu parametreleri olarak iletilebilir. 3. sürüm bileşen filtrelerini yeniden oluşturma bölümüne bakın.
bounds locationBias.rectangle Yeniden adlandırıldı; yapı, nesne olarak değiştirildi.
language languageCode Yeniden adlandırıldı. Atlandığında, v3 Accept-Language başlığını kullanır veya varsayılan olarak en değerini kullanır. v4 ise varsayılan olarak konumun yerel dilini ve alfabesini kullanır.
region regionCode Yeniden adlandırıldı. Atlandığında, v3 varsayılan olarak us değerini alır, v4'ün ise varsayılan değeri yoktur.
extra_computations Kaldırıldı SearchDestinations yöntemiyle değiştirildi.

Yanıt alanı değişiklikleri

v3 Alanı v4 Alanı Notlar
status, error_message Kaldırıldı v4, HTTP durum kodlarını ve hata gövdelerini kullanır.
results.address_components.long_name/results.address_components.short_name results.addressComponents.longText/results.addressComponents.shortText Yeniden adlandırıldı.
results.geometry.location_type results.granularity Yeniden adlandırıldı.
results.geometry.location results.location Alan adları: lat/lng -> latitude/longitude.
results.geometry.viewport results.viewport Alan adları: northeast/southwest -> high/low.
results.postcode_localities results.postalCodeLocalities Yeniden adlandırıldı. Artık bir veya daha fazla yerleşim yeri için döndürülüyor (v3 için >1 gerekir).
results.partial_match Kaldırıldı
Yeni results.addressComponents.languageCode Belirli adres bileşeninin dili.
Yeni results.bounds high/low kullanan açık sınırlar.
Yeni results.place Yerin kaynak adı.
Yeni results.postalAddress Yapılandırılmış PostalAddress nesnesi.

3. sürüm bileşen filtrelerini yeniden oluşturma

Geocoding v3'teki ileriye doğru coğrafi kodlama, belirli bileşenler (ör. components=country:US) için sonuçların katı bir şekilde filtrelenmesini sağlayan bir components parametresi içeriyordu. v4'teki ileriye doğru coğrafi kodlama, istek parametrelerinde bu tür katı filtrelemeyi desteklemez. 4. sürümde, adres bilgilerini yolda tek bir yapılandırılmamış dize olarak veya address.addressLines, address.locality, address.administrativeArea, address.postalCode ve address.regionCode gibi yapılandırılmış sorgu parametreleri olarak sağlayabilirsiniz. Yapılandırılmış parametreler, katı filtreler olarak işlev görmez. Bunun yerine, sağlanan tüm bileşenler birleştirilerek API'nin coğrafi kodlamaya çalışacağı tam adres oluşturulur. API, tüm bileşenlerde belirtilen adresin tamamı için en iyi eşleşmeyi arar. Bileşenleri yapılandırılmış bir şekilde sağlamak, özellikle adres bilgileri ayrı form alanlarından toplandığında API'nin amacı daha iyi anlamasına yardımcı olabilir. Bu, her alandaki bilgi türü net olduğundan API'nin her bileşendeki küçük yazım hatalarını veya belirsizlikleri işlemesine yardımcı olabilir.

v3'ün katı bileşen filtrelerine benzer bir davranış elde etmek için yanıttaki postalAddress ve addressComponents nesnelerine göre v4 API tarafından döndürülen results dizisinde istemci tarafı filtreleme uygulamanız gerekir.

Aşağıdaki tabloda, v3 components filtreleri ile v4 postalAddress alanları arasındaki en iyi eşleşme gösterilmektedir:

v3 bileşen filtresi v4 yanıt alanı
country postalAddress.regionCode
postal_code postalAddress.postalCode
administrative_area postalAddress.administrativeArea veya addressComponents

İstemci tarafı filtreleme örnekleri

Aşağıdaki örneklerde, desteklenen alanlar (ülke, bağlı olduğu yer ve posta kodu) için v3 bileşen filtrelemeye benzer bir davranış elde etmek amacıyla sonuçların nasıl filtreleneceği gösterilmektedir. Güvenilir filtreleme ölçütleri bulunmadığından diğer alanlara filtre uygulanması önerilmez.

Ülkeye göre filtrele

İsteğinizdeki address.regionCode ile her sonuçtaki postalAddress.regionCode eşleşmelidir. API, istekte küçük harfli bölge kodlarını kabul etse de yanıtta her zaman büyük harfle döndürür. Bu nedenle, karşılaştırmadan önce girişinizi büyük harfe normalleştirmeniz gerekir.

Python Kodu Örneği
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 Kod Örneği
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');
Bağlı olduğu yere göre filtreleme

İsteğinizdeki address.administrativeArea ile her sonuçtaki postalAddress.administrativeArea eşleşmelidir. Ülke kodlarına benzer şekilde, karşılaştırmadan önce girişinizi büyük harfe normalleştirmeniz gerekir. Bu, yalnızca isteğinizdeki administrativeArea standart 2 harfli bir kısaltmayla sağlandığında güvenilirdir. Yanıttaki postalAddress.administrativeArea, çeşitli nedenlerle ISO 3166-2 kod son ekleriyle doğrudan eşleşmeyebilir. İlk olarak, bazı bölgelerde ISO 3166-2 koduna karşılık gelen alt bölüm, posta adreslerinin standart temsilinin bir parçası değildir. Örneğin, İspanya'da 1.düzey bağlı olduğu yer (ör. Kanarya Adaları için "CN") addressComponents içinde bulunabilir ancak postalAddress.administrativeArea, 2.düzey bağlı olduğu yeri (ör. "Santa Cruz de Tenerife") içerebilir. İkinci olarak, bazı bölgelerde alt bölümün kısaltması en çok tercih edilen değildir ve postalAddress.administrativeArea içinde daha uzun bir adla temsil edilir (benzer nedenlerle, alt bölüme karşılık gelen adres bileşeni için addressComponents.shortText, alt bölümün ISO 3166-2 kod son ekiyle eşleşmeyebilir). Ayrıca, bazı durumlarda alt bölüm, 1'den büyük n için administrative_area_level_n adres bileşeninde temsil edilebilir. En kapsamlı sonuçlar için hem postalAddress.administrativeArea hem de administrative_area_level_n türünde (ör. administrative_area_level_1) addressComponents ile eşleşme olup olmadığını kontrol etmeniz gerekir.

Python Kodu Örneği
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 Kod Örneği
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');
Posta koduna göre filtreleme

İsteğinizdeki address.postalCode ile her sonuçtaki postalAddress.postalCode eşleşmelidir. Karşılaştırmadan önce hem giriş hem de sonuç posta kodlarını normalleştirmeniz gerekir. Normalleştirme mantığı büyük ölçüde bölgeye bağlıdır. Temel bir yaklaşım, boşlukları ve kısa çizgileri kaldırmayı ve tutarlı bir büyük/küçük harf düzenine dönüştürmeyi içerir.

Posta kodu öneklerini (ör. Birleşik Krallık'ta "L2") veya soneklerini (ör. ABD posta kodlarında "+4") işlemek için daha gelişmiş normalleştirme gerekebilir. Gerekli olan normalleştirme mantığı, ülkeye ve ilgili posta kodlarının biçimlerine göre değişir. Sağlanan normalleştirme işlevlerini uyarlamanız veya hedeflediğiniz bölgeler için daha karmaşık bir mantık uygulamanız gerekebilir.

Verilen örnek, ABD posta kodlarını işler ve ZIP+4 sağlanmış veya döndürülmüş olsa bile 5 haneli tabanda eşleşmeye izin verir.

Python Kodu Örneği (ABD posta kodu odaklı)
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 Kod Örneği (ABD Posta Koduna Odaklı)
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 Tersine Coğrafi Kodlama'dan taşıma

Koordinatları adreslere dönüştürmek için v3 Tersine Coğrafi Kodlama'yı kullanıyorsanız GET isteğini kabul eden v4 Bir konumun tersine coğrafi kodlamasını yapma yöntemine geçmeniz gerekir.

v4 API, çeşitli parametrelerin adlarını, yapısını ve desteğini değiştirir. Yanıtta döndürülmesini istediğiniz alanları belirtmek için alan maskesi kullanmanızı önemle tavsiye ederiz.

İstek parametresi değişiklikleri

v3 Parametresi v4 parametresi Notlar
language languageCode Yeniden adlandırıldı. Atlandığında, v3 Accept-Language başlığını kullanır veya varsayılan olarak en değerini kullanır. v4 ise varsayılan olarak konumun yerel dilini ve alfabesini kullanır.
region regionCode Yeniden adlandırıldı. Atlandığında, v3 varsayılan olarak us değerini alır, v4'ün ise varsayılan değeri yoktur.
result_type types Yeniden adlandırıldı; yinelenen sorgu parametreleri kullanıyor.
location_type granularity Yeniden adlandırıldı; yinelenen sorgu parametreleri kullanıyor.
extra_computations Kaldırıldı SearchDestinations yöntemiyle değiştirildi.

Yanıt alanı değişiklikleri

v3 Alanı v4 Alanı Notlar
status, error_message Kaldırıldı v4, HTTP durum kodlarını ve hata gövdelerini kullanır.
results.address_components.long_name/results.address_components.short_name results.addressComponents.longText/results.addressComponents.shortText Yeniden adlandırıldı.
results.geometry.location_type results.granularity Yeniden adlandırıldı.
results.geometry.location results.location Alan adları: lat/lng -> latitude/longitude.
results.geometry.viewport results.viewport Alan adları: northeast/southwest -> high/low.
Yeni results.addressComponents.languageCode Belirli adres bileşeninin dili.
Yeni results.bounds high/low kullanan açık sınırlar.
Yeni results.place Yerin kaynak adı.
Yeni results.postalAddress Yapılandırılmış PostalAddress nesnesi.

v3 adres tanımlayıcılarından taşıma

Geocoding API v3'te extra_computations=ADDRESS_DESCRIPTORS parametresi, landmarks[] ve areas[] içeren bir address_descriptor nesnesi döndürüyordu. Geocoding API v4'te bu özelliğin yerini, her Destination nesnesinde doğrudan zengin mekansal bağlam döndüren SearchDestinations yöntemi (POST /v4/geocode/destinations) alır.

Aşağıdaki tabloda, eski v3 address_descriptor alanları v4 SearchDestinations eşdeğerleriyle eşleştirilmektedir:

v3 address_descriptor Alanı v4 SearchDestinations alanı Taşıma Notları
landmarks[] destinations[].landmarks[] X-Goog-FieldMask uygulamanızda destinations.landmarks isteyin.
landmarks[].place_id landmarks[].place.placeId place (PlaceView) nesnesinin içine sarmalanmış.
landmarks[].display_name landmarks[].place.displayName Yerelleştirilmiş metin (text ve languageCode).
landmarks[].types landmarks[].place.types Yer türü dizeleri dizisi.
landmarks[].spatial_relationship landmarks[].relationalDescription V4, ham enum (ACROSS_THE_ROAD, AROUND_THE_CORNER) yerine yerelleştirilmiş, okunabilir bir ifade (ör. "Across from Central Park") döndürür.
landmarks[].straight_line_distance_meters landmarks[].straightLineDistanceMeters Küçük harfle başlayan camelCase olarak yeniden adlandırıldı.
landmarks[].travel_distance_meters landmarks[].travelDistanceMeters Küçük harfle başlayan camelCase olarak yeniden adlandırıldı.
areas[] (containment enum) destinations[].containingPlaces[] ve subDestinations[] Yapısal hiyerarşi için mevcut en yakın eşdeğer: Çevreleyen kompleksler, kampüsler, alışveriş merkezleri ve binalar, containingPlaces[] ve subDestinations[] içinde yapılandırılmış PlaceView nesneleri olarak döndürülür (structureType, GROUNDS veya BUILDING olarak ayarlanır ve isteğe bağlı displayPolygon ana hatları kullanılır). Mahalle/ilçe yakınlık alanları veya v3 containment enum (NEAR, WITHIN, OUTSKIRTS) için doğrudan 1:1 değişim olmadığını unutmayın.

v3 Yerler coğrafi kodlamadan geçiş yapma

Geocoding v3 ile belirli bir yer kimliğinin adresini almak için place_id kullanıyorsanız GET isteği kabul eden v4 Place Geocoding yöntemine geçmeniz gerekir.

v4 API, çeşitli parametrelerin adlarını, yapısını ve desteğini değiştirir. Yanıtta döndürülmesini istediğiniz alanları belirtmek için alan maskesi kullanmanızı önemle tavsiye ederiz.

İstek parametresi değişiklikleri

v3 Parametresi v4 parametresi Notlar
place_id İstek protosundaki place alanı Yer kimliği artık yol parametresi places/{place} olarak sağlanır (ör. https://geocode.googleapis.com/v4/geocode/places/ChIJj61dQgK6j4AR4GeTYWZsKWw). Bu, temel istekteki yer alanıyla eşlenir.
language languageCode Yeniden adlandırıldı. Atlandığında, v3 Accept-Language başlığını kullanır veya varsayılan olarak en değerini kullanır. v4 ise varsayılan olarak konumun yerel dilini ve alfabesini kullanır.
region regionCode Yeniden adlandırıldı. Atlandığında, v3 varsayılan olarak us değerini alır, v4'ün ise varsayılan değeri yoktur.

Yanıt alanı değişiklikleri

v3 Alanı v4 Alanı Notlar
status, error_message Kaldırıldı v4, HTTP durum kodlarını ve hata gövdelerini kullanır.
results (root) v4, results dizisi değil, tek bir sonuç nesnesi döndürür.
results.address_components.long_name/results.address_components.short_name addressComponents.longText/addressComponents.shortText Yeniden adlandırıldı.
results.geometry.location_type granularity Yeniden adlandırıldı.
results.geometry.location location Alan adları: lat/lng -> latitude/longitude.
results.geometry.viewport viewport Alan adları: northeast/southwest -> high/low.
results.postcode_localities postalCodeLocalities Yeniden adlandırıldı. Artık bir veya daha fazla yerleşim yeri için döndürülüyor (v3 için >1 gerekir).
Yeni addressComponents.languageCode Belirli adres bileşeninin dili.
Yeni bounds high/low kullanan açık sınırlar.
Yeni place Yerin kaynak adı.
Yeni postalAddress Yapılandırılmış PostalAddress nesnesi.

Geocoding Hyperlocal Data'dan Destinations'a geçiş

Geocoding API v3'teki aşağıdaki özellikler, Geocoding API v4'ün SearchDestinations yöntemiyle değiştiriliyor:

  • Giriş sayısı
  • Gezinme noktaları
  • Bina ana hatları
  • Saha

Yukarıdaki özellikler için Geocoding API v3'ü kullanıyorsanız bu özellikleri elde etmek için SearchDestinations yöntemini kullanmanıza yardımcı olması amacıyla bu dokümandan yararlanın. Bu belgede, SearchDestinations yanıtında bu özelliklerin nerede bulunacağı ve bu özelliklerin Geocoding API v3 ile Geocoding API v4'ün SearchDestinations yöntemi arasındaki API yanıtlarında nasıl temsil edildiğiyle ilgili farklar açıklanmaktadır.

Giriş sayısı

Bir destination ile ilişkili girişleri almak için destination.entrances alanını kullanın.

destination.entrances içindeki her entrance, aşağıdaki alanlara sahiptir (eski v3 buildings.entrances şemasının yerine geçer):

  • displayName: Giriş için kullanıcı tarafından okunabilir bir ad (ör. "Gate B") içeren yeni ve isteğe bağlı bir alan.
  • location: latitude ve longitude kullanılarak LatLng türünde bir konum (v3 lat/lng yerine geçer).
  • tags: Geocoding API v3 girişlerindeki (ör. PREFERRED) tags alanıyla aynıdır.
  • place: Geocoding API v3'teki building_place_id alanının yerini alan, yerin kaynak adı (ör. places/ChIJ...). 4. sürümde bu yer, yalnızca bir binayı değil, herhangi bir hedef yapıyı (bina, kampüs veya park) temsil edebilir.

destination ile ilişkili navigasyon noktalarını almak için destination.navigationPoints alanını kullanın.

destination.navigationPoints içindeki her navigationPoint, aşağıdaki alanlara sahiptir (eski v3 navigation_points şemasının yerine geçer):

  • navigationPointToken: Routes API ComputeRoutes yönteminde (Waypoint.navigationPointToken) bu belirli navigasyon noktasına yönlendirmek için kullanılan şifrelenmiş bir jeton dizesi. Navigasyon noktası jetonlarını kullanarak rota oluşturma başlıklı makaleyi inceleyin.
  • displayName: Navigasyon noktasının okunabilir adını (ör. "5th Ave") içeren yeni ve isteğe bağlı bir alan.
  • location - latitude ve longitude kullanarak LatLng türünde bir konum.
  • travelModes: Geocoding API v3'teki restricted_travel_modes alanına benzer. Ancak v4, kısıtlanmış seyahat modları yerine kabul edilebilir seyahat modlarını (DRIVE, WALK) belirtir.
  • usage: Navigasyon noktası için desteklenen varış kullanım alanlarını (ör. PICKUP, DROPOFF veya PARKING) belirten yeni bir alan.

Bina ana hatları

Bir destination ile ilişkili bina ana hatlarını almak için destination içindeki binaları temsil eden placeView nesnelerinin displayPolygon alanını kullanın (eski v3 buildings.building_outlines dizisinin yerine geçer). Her placeView için placeView.structureType alanına sahip bir bina olup olmadığını kontrol edin. Yapı türü BUILDING ise ana hatları placeView.displayPolygon alanından alabilirsiniz. placeView, Geocoding API v3'te bulunmayan bina ile ilgili ek alanlar da içerir.

destination, aşağıdaki alanlarda bir binayı temsil eden bir placeView nesnesi içerebilir:

  • destination.primary: Hedefin birincil yeri.
  • destination.containingPlaces: Birincil yeri "içeren" daha büyük yerleri barındıran yinelenen bir alan. Örneğin, birincil yer bir subpremise ise containingPlaces genellikle binayı temsil eden placeView değerini içerir.
  • destination.subDestinations: Birincil yerin alt varış noktalarını (ör. bir binadaki bağımsız apartman daireleri veya süitler) içeren yinelenen bir alan.

placeView.displayPolygon biçiminin, RFC 7946 biçimini kullanan GeoJSON biçimi olan Geocoding API v3'teki bina ana hattı biçimiyle eşleştiğini unutmayın.

Saha

Bina ana hatlarına benzer şekilde, bir destination ile ilişkili alanları almak için destination içindeki alanları temsil eden placeView nesnelerinin displayPolygon alanını kullanın (eski v3 grounds dizisinin yerine geçer). Her placeView için placeView.structureType alanına sahip bir zemin poligonu olup olmadığını kontrol edin. Yapı türü GROUNDS ise ana hatları placeView.displayPolygon alanından alabilirsiniz. placeView, Geocoding API v3'te bulunmayan alanlar için ek alanlar da içerir.

destination, aşağıdaki alanlarda bir gerekçeyi temsil eden bir placeView nesnesi içerebilir:

  • destination.primary
  • destination.containingPlaces
  • destination.subDestinations

placeView.displayPolygon biçiminin, RFC 7946 biçimini kullanan GeoJSON biçimi olan Geocoding API v3'teki tesis ana hat biçimiyle eşleştiğini unutmayın.

Sonuçların kesinliği

Geocoding API v3'te, yanıt geometrisindeki location_type alanı sonuçların hassasiyetini gösteriyordu ve bazı istemciler sonuçları bu değerlere (ROOFTOP, RANGE_INTERPOLATED, GEOMETRIC_CENTER ve APPROXIMATE) göre sıralıyor veya filtreliyordu. Standart Geocoding API v4 geçişlerinde bu alan granularity olarak yeniden adlandırılır.

Destinations API'de (v4 SearchDestinations), location_type alanı yoktur. Bunun yerine, uzamsal bilgiler farklı şekilde işlenir:

  • Manuel istemci tarafı filtreleme gerekmez: Standart Geocoding API, farklı ayrıntı düzeylerinde birden fazla sonuç sağlarken SearchDestinations yöntemi, mümkün olduğunda tek bir optimize edilmiş varış noktasına çözümlenerek belirsizliği en aza indirir. Bu sayede müşterilerin, en iyi sonucu belirlemek için konum türüne göre filtreleme yapmasına gerek kalmaz.
  • Yapı türü ve görüntü poligonlarıyla temsil edilen mekansal bilgiler: Mekansal geometri ve yapı şunlarla gösterilir:
    • displayPolygon (tam geometri için).
    • placeView nesnesindeki structureType alanı.
  • Yapı türü eşleme:
    • POINT, BUILDING veya SECTION structureType, genellikle daha önce ROOFTOP olarak adlandırılan şeye karşılık gelir.
    • GROUNDS için structureType genellikle GEOMETRIC_CENTER değerine karşılık gelir.

Bu özellikleri istemek için alan maskesi kullanma

SearchDestinations yöntemi, Döndürülecek alanları seçme bölümünde açıklandığı gibi bir alan maskesi gerektirir. Alan maskesi, tüm alanları döndürmek için * olarak ayarlanabilir veya almak istediğiniz belirli alanlara ayarlayabilirsiniz. Örneğin, aşağıdaki API isteği, bir hedefin girişlerini, navigasyon noktalarını, bina ana hatlarını ve alanlarını almak için gereken tüm alanları almak üzere alan maskesini ayarlar:

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

Sık Kullanılan Taşıma Yöntemleri ve Kod Kalıpları

Karmaşık iş akışlarını Geocoding v3 veya Geocoding++'tan SearchDestinations'ya taşırken yaygın mekansal ve adres yapılarını ayıklamak için aşağıdaki kod tariflerini kullanın.

En iyi bina poligonunu ayıklama

Bir konum veya varış noktası için bina yerleşim planını oluşturmak istiyorsanız:

  1. primary yerinde structureType === 'BUILDING' olup olmadığını ve displayPolygon içerip içermediğini kontrol edin.
  2. Aksi takdirde, kapsayıcı binayı bulmak için containingPlaces öğesini inceleyin (birincil varış noktası daha büyük bir binanın alt varış noktası olduğunda kullanışlıdır).
  3. Kapsayıcı bina bulunamazsa tek tek binaların listelenip listelenmediğini görmek için subDestinations öğesini kontrol edin.
Python Kodu Örneği
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 Kod Örneği
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;
}

Zemin ana hattını çıkarma

Bir apartman kompleksi, kurumsal kampüs, alışveriş merkezi veya parkın sınırına ihtiyacınız varsa:

  1. primary yeri tüm kompleksi (structureType === 'GROUNDS') temsil ediyorsa primary.displayPolygon kullanın.
  2. primary yeri, daha büyük bir kompleksin içindeki bir bina veya girişse containingPlaces içinde çevreleyen alanı bulun.
Python Kodu Örneği
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 Kod Örneği
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;
}

Adres gösterimi ve son aşama varış için önemli noktaları seçme

Geocoding v3 address_descriptor, bir spatial_relationship enum (WITHIN, BESIDE, BEHIND, NEAR, ACROSS_THE_ROAD, AROUND_THE_CORNER) döndürdü. SearchDestinations içinde:

  • Ham ilişki enum'u yok. Bunun yerine doğrudan relationalDescription.text kullanın. "Across from Central Park" veya "Behind the convention center" gibi yerelleştirilmiş, gösterime hazır ifadeler içerir. "Near " ifadesini manuel olarak eklemeyin.
  • Kullanım alanınıza uygun referans noktası seçmek için tags kullanın:
    • ARRIVAL: Hedefin hemen bitişiğinde, karşısında veya sokağın karşısında bulunan yakın çevreye özel önemli noktalar (genellikle 50-100 metre mesafede). Sürücünün varış zamanını anlık olarak gösterme, kurye teslimat onayı veya uygulama içi varış kartları için idealdir.
    • ADDRESS: Çevredeki mahallede yerel olarak öne çıkan önemli noktalar (genellikle 100-500 metre içinde). Müşteriye yönelik ödeme, sipariş incelemesi veya seyahat öncesi varış noktası anlam belirsizliğini giderme için idealdir.
    • Bir önemli noktada hem ADDRESS hem de ARRIVAL etiketleri varsa bu nokta hem mahallede iyi bilinir hem de hedefin hemen yanındadır.
Python Kodu Örneği
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 Kod Örneği
/**
 * 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;
}

Araç navigasyon noktalarına ve tercih edilen girişlere giden rota

Son aşama sevkiyat ve varış iş akışları, iki tamamlayıcı mekansal erişim noktası türünü birleştirir:

  • Adım adım arabayla yol tarifi: navigationPoints kullanarak araçları belirlenen yol bırakma noktalarına yönlendirin. Navigasyon noktaları, yakınlık ve alaka düzeyine göre önceden sıralanır. Bu nedenle, istediğiniz seyahat moduna (ör. 'DRIVE') ve kullanım etiketine (ör. 'DROPOFF' veya 'PICKUP') sahip ilk aday, en uygun araç yol noktasını sağlar. navigationPointToken değerini Routes API ComputeRoutes yöntemine (Waypoint.navigationPointToken) veya Navigation SDK'ya gönderin. Yola sabitlenmiş sürüş noktası yoksa bina girişine veya birincil ağırlık merkezine geri dönün.
  • Fiziksel kapı girişi: destinations.entrances kullanarak kuryeyi veya yolcuyu bina girişine yönlendirin. Doğrudan fiziksel erişim sağlama olasılığı yüksek olan girişleri bulmak için 'PREFERRED' için tags adresini kontrol edin. Giriş verisi yoksa yaya navigasyon noktasına (travelModes, 'WALK' dahil) veya birincil merkez noktasına geri dönün.
Python Kodu Örneği
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 Kod Örneği
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,
    };
}

Güvenlikle ilgili olarak göz önünde bulundurulması gerekenler

Geocoding API v4, sunucudan sunucuya API olarak tasarlanmıştır. JavaScript kullanıcıları için v3'ten v4'e doğrudan geçiş yolu yoktur. API anahtarı kullanarak v4 yöntemlerini doğrudan istemci tarafı JavaScript'ten (ör. tarayıcıda) çağırmak, API anahtarınızın çalınma ve kötüye kullanılma riskini artırır.

HTTP yönlendiren kısıtlamaları faydalı olsa da web hizmeti uç noktaları için yeterli koruma sağlamaz. Saldırganlar, isteklerinde Referer başlığını taklit ederek bu kısıtlamaları kolayca atlatabilir.

Geocoding API v4'ü kendi arka uç sunucunuzdan kullanmanız önerilir. İstemci uygulamanız bu aracı sunucuya istek göndermelidir. Aracı sunucu, korumalı bir API anahtarı (ör. bir ortam değişkeninde veya Secret Manager'da depolanan anahtar) kullanarak Google API'yi güvenli bir şekilde çağırır. Bu sayede API anahtarınız hiçbir zaman ön uç kodunda görünmez.

İstemci tarafı ihtiyaçları için alternatifler

Coğrafi kodlama gerektiren istemci tarafı ihtiyaçlarınız varsa mevcut istemci tarafı çözümlerinden birini kullanabilirsiniz: