Migrar da API Geocoding v3 para a v4

Desenvolvedores do Espaço Econômico Europeu (EEE)

A API Geocoding v4 apresenta vários métodos novos que substituem a funcionalidade na v3 da API. Este guia mostra como migrar seu app para usar os novos métodos da v4.

Você pode usar as chaves de API atuais com os novos métodos da v4. No entanto, se você solicitou um aumento de cota na v3 da API, faça o mesmo nas novas APIs v4.

Migrar da geocodificação direta v3

Se você usa a geocodificação v3 para geocodificar endereços, migre para o método v4 Geocodificar um endereço, que aceita uma solicitação GET.

A API v4 muda nomes, estrutura e suporte para vários parâmetros. Recomendamos usar uma máscara de campo para especificar os campos que você quer retornar na resposta.

Mudanças nos parâmetros de solicitação

Parâmetro v3 Parâmetro v4 Observações
address, components address O endereço não estruturado (v3 address) agora é transmitido no caminho do URL. Os componentes de endereço estruturados (v3 components) podem ser transmitidos como parâmetros de consulta address.*. Consulte Reproduzir filtros de componentes da v3.
bounds locationBias.rectangle Renomeado; a estrutura mudou para objeto.
language languageCode Renomeado.
region regionCode Renomeado.
extra_computations Removido Substituído pelo método SearchDestinations.

Mudanças no campo de resposta

Campo v3 Campo v4 Observações
status, error_message Removido A v4 usa códigos de status HTTP e corpos de erro.
results.address_components.long_name / results.address_components.short_name results.addressComponents.longText / results.addressComponents.shortText Renomeado.
results.geometry.location_type results.granularity Renomeado.
results.geometry.location results.location Nomes dos campos: lat/lng -> latitude/longitude.
results.geometry.viewport results.viewport Nomes dos campos: northeast/southwest -> high/low.
results.postcode_localities results.postalCodeLocalities Renomeado. Agora retornado para uma ou mais localidades (v3 obrigatório >1).
results.partial_match Removido
Nova results.addressComponents.languageCode Idioma do componente de endereço específico.
Nova results.bounds Limites explícitos usando high/low.
Nova results.place Nome do recurso para o lugar.
Nova results.postalAddress Objeto PostalAddress estruturado.

Reproduzir filtros de componentes da v3

O geocodificação direta na v3 incluía um parâmetro components que permitia a filtragem rígida de resultados para componentes específicos (por exemplo, components=country:US). A geocodificação direta na v4 não é compatível com esse tipo de filtragem rígida nos parâmetros de solicitação. Na v4, é possível fornecer informações de endereço como uma única string não estruturada no caminho ou como parâmetros de consulta estruturados, como address.addressLines, address.locality, address.administrativeArea, address.postalCode e address.regionCode. Os parâmetros estruturados não funcionam como filtros rígidos. Em vez disso, todos os componentes fornecidos são combinados para formar o endereço completo que a API vai tentar geocodificar. A API procura a melhor correspondência para o endereço completo especificado em todos os componentes. Fornecer componentes de maneira estruturada pode ajudar a API a entender melhor a intenção, principalmente quando as informações de endereço são coletadas de campos de formulário separados. Isso pode ajudar a API a lidar com pequenos erros de digitação ou ambiguidades em cada componente, já que o tipo de informação em cada campo é claro.

Para ter um comportamento semelhante aos filtros de componentes fixos da v3, implemente a filtragem do lado do cliente na matriz results retornada pela API v4 com base nos objetos postalAddress e addressComponents na resposta.

A tabela a seguir mostra a melhor correspondência entre os filtros components da v3 e os campos postalAddress da v4:

Filtro de componente da v3 Campo de resposta da v4
country postalAddress.regionCode
postal_code postalAddress.postalCode
administrative_area postalAddress.administrativeArea ou addressComponents

Exemplos de filtragem do lado do cliente

Os exemplos a seguir mostram como filtrar resultados para alcançar um comportamento semelhante à filtragem de componentes da v3 para campos compatíveis: país, área administrativa e código postal. Não é recomendável filtrar em outros campos porque não há critérios de filtragem confiáveis.

Filtrar por país

Faça a correspondência entre o address.regionCode da sua solicitação e o postalAddress.regionCode em cada resultado. Embora a API aceite códigos de região em letras minúsculas na solicitação, ela sempre os retorna em letras maiúsculas na resposta. Portanto, é necessário normalizar a entrada para letras maiúsculas antes da comparação.

Exemplo de código 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')
Exemplo de código do 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');
Filtrar por área administrativa

Faça a correspondência entre o address.administrativeArea da sua solicitação e o postalAddress.administrativeArea em cada resultado. Assim como os códigos de país, é necessário normalizar a entrada para maiúsculas antes da comparação. Isso só é confiável quando o administrativeArea na sua solicitação é fornecido com uma abreviação padrão de duas letras. O postalAddress.administrativeArea na resposta pode não corresponder diretamente aos sufixos de código ISO 3166-2 por vários motivos. Primeiro, em algumas áreas, a subdivisão correspondente ao código ISO 3166-2 não faz parte da representação padrão de endereços postais. Por exemplo, na Espanha, a área administrativa de nível 1 (por exemplo, "CN" para Canarias) pode estar presente em addressComponents, mas postalAddress.administrativeArea pode conter a área de nível 2 (por exemplo, "Santa Cruz de Tenerife"). Em segundo lugar, em algumas áreas, a abreviação da subdivisão não é usada com frequência e é representada em postalAddress.administrativeArea com um nome mais longo. Por motivos semelhantes, addressComponents.shortText para o componente de endereço correspondente à subdivisão pode não corresponder ao sufixo do código ISO 3166-2 da subdivisão. Além disso, em alguns casos, a subdivisão pode ser representada no componente de endereço para administrative_area_level_n com n maior que 1. Para ter os resultados mais abrangentes, verifique se há uma correspondência em postalAddress.administrativeArea e em qualquer addressComponents com um tipo administrative_area_level_n (por exemplo, administrative_area_level_1).

Exemplo de código 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')
Exemplo de código do 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');
Filtrar por CEP

Faça a correspondência entre o address.postalCode da sua solicitação e o postalAddress.postalCode em cada resultado. É necessário normalizar os códigos postais de entrada e de resultado antes da comparação. A lógica de normalização depende muito da região. Uma abordagem básica envolve remover espaços e hífens e converter para um caso consistente.

Uma normalização mais avançada pode ser necessária para processar prefixos (por exemplo, "L2" no Reino Unido) ou sufixos (por exemplo, "+4" em CEPs dos EUA). A lógica de normalização específica necessária varia de acordo com o país e os formatos de códigos postais envolvidos. Talvez seja necessário adaptar as funções de normalização fornecidas ou implementar uma lógica mais sofisticada para as regiões segmentadas.

O exemplo fornecido processa códigos postais dos EUA e permite a correspondência na base de cinco dígitos, mesmo que ZIP+4 seja fornecido ou retornado.

Exemplo de código Python (focado em CEPs dos EUA)
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')
Exemplo de código Node.js (focado em CEPs dos EUA)
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');

Migrar da geocodificação inversa v3

Se você usa a geocodificação inversa v3 para transformar coordenadas em endereços, migre para o método v4 Geocodificar inversamente um local, que aceita uma solicitação GET.

A API v4 muda nomes, estrutura e suporte para vários parâmetros. Recomendamos usar uma máscara de campo para especificar os campos que você quer retornar na resposta.

Mudanças nos parâmetros de solicitação

Parâmetro v3 Parâmetro v4 Observações
language languageCode Renomeado.
region regionCode Renomeado.
result_type types Renomeado; usa parâmetros de consulta repetidos.
location_type granularity Renomeado; usa parâmetros de consulta repetidos.
extra_computations Removido Substituído pelo método SearchDestinations.

Mudanças no campo de resposta

Campo v3 Campo v4 Observações
status, error_message Removido A v4 usa códigos de status HTTP e corpos de erro.
results.address_components.long_name / results.address_components.short_name results.addressComponents.longText / results.addressComponents.shortText Renomeado.
results.geometry.location_type results.granularity Renomeado.
results.geometry.location results.location Nomes dos campos: lat/lng -> latitude/longitude.
results.geometry.viewport results.viewport Nomes dos campos: northeast/southwest -> high/low.
Nova results.addressComponents.languageCode Idioma do componente de endereço específico.
Nova results.bounds Limites explícitos usando high/low.
Nova results.place Nome do recurso para o lugar.
Nova results.postalAddress Objeto PostalAddress estruturado.

Migrar dos descritores de endereço da v3

Se você usa address_descriptor para receber mais informações sobre um local com a API Geocoding v3, migre para o campo landmarks do SearchDestinationsResponse.

Migrar da geocodificação de lugares da v3

Se você usa place_id para receber o endereço de um ID de lugar específico com a API Geocoding v3, migre para o método Place Geocoding v4, que aceita uma solicitação GET.

A API v4 muda nomes, estrutura e suporte para vários parâmetros. Recomendamos usar uma máscara de campo para especificar os campos que você quer retornar na resposta.

Mudanças nos parâmetros de solicitação

Parâmetro v3 Parâmetro v4 Observações
place_id Campo place no proto de solicitação O ID do lugar agora é fornecido como um parâmetro de caminho places/{place}, por exemplo: https://geocode.googleapis.com/v4/geocode/places/ChIJj61dQgK6j4AR4GeTYWZsKWw. Isso é mapeado para o campo "place" na solicitação subjacente.
language languageCode Renomeado.
region regionCode Renomeado.

Mudanças no campo de resposta

Campo v3 Campo v4 Observações
status, error_message Removido A v4 usa códigos de status HTTP e corpos de erro.
results (raiz) A v4 retorna um único objeto de resultado, não uma matriz results.
results.address_components.long_name / results.address_components.short_name addressComponents.longText / addressComponents.shortText Renomeado.
results.geometry.location_type granularity Renomeado.
results.geometry.location location Nomes dos campos: lat/lng -> latitude/longitude.
results.geometry.viewport viewport Nomes dos campos: northeast/southwest -> high/low.
results.postcode_localities postalCodeLocalities Renomeado. Agora retornado para uma ou mais localidades (v3 obrigatório >1).
Nova addressComponents.languageCode Idioma do componente de endereço específico.
Nova bounds Limites explícitos usando high/low.
Nova place Nome do recurso para o lugar.
Nova postalAddress Objeto PostalAddress estruturado.

Migrar de dados hiperlocais de geocodificação para destinos

Os seguintes recursos da API Geocoding v3 estão sendo substituídos pelo método SearchDestinations da API Geocoding v4:

  • Entradas
  • Pontos de navegação
  • Crie textos na estrutura de tópicos
  • Acesso geral

Se você estava usando a API Geocoding v3 para os recursos acima, use este documento para ajudar a usar o método SearchDestinations e ter acesso a esses recursos. Este documento explica onde encontrar esses recursos na resposta SearchDestinations e as diferenças na forma como eles são representados nas respostas da API entre a API Geocoding v3 e o método SearchDestinations da API Geocoding v4.

Entradas

Para receber as entradas associadas a um destination, use o campo destination.entrances.

O formato de um entrance é um pouco diferente do formato de entrada na API Geocoding v3. Cada entrada em destination.entrances tem os seguintes campos:

  • displayName: um novo campo opcional que terá um nome legível para a entrada, por exemplo, "Portão B".
  • location: um local do tipo LatLng, que é diferente do formato usado na API Geocoding v3.
  • tags: é o mesmo que o campo tags das entradas da API Geocoding v3.
  • place: análogo ao campo buildingPlaceId das entradas da API Geocoding v3. No entanto, o ID de lugar nesse campo pode ser de um lugar de qualquer tipo, não necessariamente apenas um edifício.

Para receber os pontos de navegação associados a um destination, use o campo destination.navigationPoints.

O formato de um navigationPoint é um pouco diferente do formato de ponto de navegação na API Geocoding v3. Cada ponto de navegação em destination.navigationPoints tem os seguintes campos:

  • displayName: um novo campo opcional que terá um nome legível para o ponto de navegação, por exemplo, "5th Ave".
  • location: um local do tipo LatLng, que é diferente do formato usado na API Geocoding v3.
  • travelModes: semelhante ao campo restrictedTravelModes dos pontos de navegação da API Geocoding v3. Os valores de enumeração possíveis são os mesmos. A única diferença é que esse campo agora representa os modos de viagem aceitáveis para o ponto de navegação, em vez dos modos de viagem restritos.
  • usage: um novo campo que contém os casos de uso compatíveis com o ponto de navegação. A maioria dos pontos de navegação tem um uso de UNKNOWN, mas isso não significa que o uso do ponto de navegação seja restrito de alguma forma.

Crie textos na estrutura de tópicos

Para receber os contornos de edifícios associados a um destination, use o campo displayPolygon dos objetos placeView no destination que representam edifícios. Para cada placeView, você pode verificar se é um edifício com o campo placeView.structureType. Se o tipo de estrutura for BUILDING, você poderá extrair o contorno do campo placeView.displayPolygon. O placeView também terá outros campos para o edifício que não estavam na API Geocoding v3.

Um destination pode ter um objeto placeView que representa um edifício nos seguintes campos:

  • destination.primary: é o local principal do destino.
  • destination.containingPlaces: esse é um campo repetido que pode conter lugares maiores que "contêm" o lugar principal. Por exemplo, se o lugar principal for um subpremise, containingPlaces geralmente vai conter o placeView que representa o edifício.
  • destination.subDestinations: é um campo repetido que pode conter subdestinos do lugar principal. Por exemplo, unidades individuais de um prédio. Normalmente, esse campo não tem um placeView que representa um edifício.

O formato de placeView.displayPolygon corresponde ao formato de contorno do edifício na API Geocoding v3, que é o formato GeoJSON, usando o formato RFC 7946.

Acesso geral

Assim como na criação de contornos, para receber os fundamentos associados a um destination, use o campo displayPolygon dos objetos placeView no destination que representam fundamentos. Para cada placeView, você pode verificar se é um motivo com o campo placeView.structureType. Se o tipo de estrutura for GROUNDS, você poderá extrair o contorno do campo placeView.displayPolygon. O placeView também terá outros campos para os motivos que não estavam na API Geocoding v3.

Um destination pode ter um objeto placeView que representa um motivo nos seguintes campos:

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

O formato de placeView.displayPolygon corresponde ao formato de contorno de terrenos na API Geocoding v3, que é o formato GeoJSON, usando o formato RFC 7946.

Precisão dos resultados

Na API Geocoding v3, o campo location_type na geometria da resposta indicava a precisão dos resultados, e alguns clientes classificavam ou filtravam os resultados com base nesses valores (ROOFTOP, RANGE_INTERPOLATED, GEOMETRIC_CENTER e APPROXIMATE). Nas migrações padrão da API Geocoding v4, esse campo é renomeado como granularity.

Na API Destinations (v4 SearchDestinations), não há um campo location_type. Em vez disso, as informações espaciais são processadas de maneira diferente:

  • Não é necessário fazer filtragem manual do lado do cliente: embora o Geocoding padrão forneça vários resultados em diferentes granularidades, o método SearchDestinations minimiza a ambiguidade resolvendo um único destino otimizado sempre que possível. Assim, os clientes não precisam filtrar por tipo de local para determinar qual resultado é o melhor.
  • Informações espaciais representadas por tipo de estrutura e polígonos de exibição: A geometria e a estrutura espaciais são indicadas por:
    • O displayPolygon (para geometria exata).
    • O campo structureType no objeto placeView.
  • Mapeamento de tipo de estrutura:
    • Um structureType de POINT, BUILDING ou SECTION geralmente corresponde ao que era chamado de ROOFTOP anteriormente.
    • Um structureType de GROUNDS geralmente corresponde a GEOMETRIC_CENTER.

Use uma máscara de campo para solicitar esses recursos

O método SearchDestinations exige uma máscara de campo, conforme explicado em Escolher campos para retornar. A máscara de campo pode ser definida como * para retornar todos os campos ou como os campos específicos que você quer receber. Por exemplo, a solicitação de API a seguir define a máscara de campo para receber todos os campos necessários para acessar as entradas, os pontos de navegação, os contornos dos edifícios e os terrenos de um destino:

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

Considerações sobre segurança

A API Geocoding v4 foi projetada como uma API entre servidores. Não há um caminho de migração direta para usuários de JavaScript da v3 para a v4. Chamar os métodos da v4 diretamente do JavaScript do lado do cliente (por exemplo, em um navegador) usando uma chave de API expõe sua chave a um alto risco de roubo e uso indevido.

As restrições de referenciador HTTP, embora úteis, não são proteção suficiente para endpoints de serviços da Web, já que podem ser facilmente ignoradas por invasores que falsificam o cabeçalho Referer nas solicitações.

A maneira recomendada de usar a API Geocoding v4 é pelo seu próprio servidor de back-end. O aplicativo cliente precisa fazer solicitações a esse servidor intermediário, que chama a API do Google com segurança usando uma chave de API protegida (por exemplo, uma chave armazenada em uma variável de ambiente ou um gerenciador de secrets). Isso garante que sua chave de API nunca seja exposta no código do front-end.

Alternativas para necessidades do lado do cliente

Se você tiver necessidades do lado do cliente que exijam geocodificação, use uma das soluções atuais do lado do cliente: