Migra de Geocoding v3 a v4

Desarrolladores del Espacio Económico Europeo (EEE)

La versión 4 de la API de Geocoding presenta varios métodos nuevos que reemplazan la funcionalidad de la versión 3 de la API. En esta guía, se muestra cómo migrar tu app para usar los nuevos métodos de la versión 4.

Puedes usar tus claves de API existentes con los nuevos métodos de la versión 4. Sin embargo, si solicitaste un aumento de cuota en la versión 3 de la API, debes solicitar un aumento en las nuevas APIs de la versión 4.

Migra desde la geocodificación directa de la versión 3

Si usas la versión 3 de Geocoding para geocodificar direcciones, debes migrar al método Geocode an address de la versión 4, que acepta una solicitud GET.

La API v4 cambia los nombres, la estructura y la compatibilidad de varios parámetros. Te recomendamos que uses una máscara de campo para especificar los campos que deseas que se muestren en la respuesta.

Cambios en los parámetros de solicitud

Parámetro de la versión 3 Parámetro de v4 Notas
address, components address La dirección no estructurada (v3 address) ahora se pasa en la ruta de URL. Los componentes de dirección estructurados (v3 components) se pueden pasar como parámetros de consulta address.*. Consulta Cómo reproducir filtros de componentes de v3.
bounds locationBias.rectangle Se cambió el nombre y la estructura pasó a ser un objeto.
language languageCode Se cambió el nombre. Cuando se omite, la versión 3 usa el encabezado Accept-Language o, de forma predeterminada, en, mientras que la versión 4 usa de forma predeterminada el idioma y la escritura locales de la ubicación.
region regionCode Se cambió el nombre. Cuando se omite, la versión 3 se establece de forma predeterminada en us, mientras que la versión 4 no tiene un valor predeterminado.
extra_computations Eliminado Se reemplazó por el método SearchDestinations.

Cambios en el campo de respuesta

Campo de v3 Campo v4 Notas
status, error_message Eliminado La versión 4 usa códigos de estado HTTP y cuerpos de error.
results.address_components.long_name/results.address_components.short_name results.addressComponents.longText/results.addressComponents.shortText Se cambió el nombre.
results.geometry.location_type results.granularity Se cambió el nombre.
results.geometry.location results.location Nombres de los campos: lat/lng -> latitude/longitude.
results.geometry.viewport results.viewport Nombres de los campos: northeast/southwest -> high/low.
results.postcode_localities results.postalCodeLocalities Se cambió el nombre. Ahora se devuelve para una o más localidades (la versión 3 requería más de 1).
results.partial_match Eliminado
Nuevo results.addressComponents.languageCode Es el idioma del componente de dirección específico.
Nuevo results.bounds Límites explícitos con high/low
Nuevo results.place Es el nombre del recurso del lugar.
Nuevo results.postalAddress Objeto PostalAddress estructurado.

Reproduce los filtros de componentes de la versión 3

La geocodificación directa en la versión 3 de Geocoding incluía un parámetro components que permitía un filtrado estricto de los resultados para componentes específicos (p.ej., components=country:US). La geocodificación directa en la versión 4 no admite este tipo de filtrado estricto en los parámetros de la solicitud. En la versión 4, puedes proporcionar información de la dirección como una sola cadena no estructurada en la ruta de acceso o como parámetros de consulta estructurados, como address.addressLines, address.locality, address.administrativeArea, address.postalCode y address.regionCode. Los parámetros estructurados no actúan como filtros estrictos. En cambio, todos los componentes proporcionados se combinan para formar la dirección completa que la API intentará geocodificar. La API busca la mejor coincidencia para la dirección completa especificada en todos los componentes. Proporcionar componentes de forma estructurada puede ayudar a la API a comprender mejor la intención, en especial cuando la información de la dirección se recopila de campos de formulario separados. Esto puede ayudar a la API a controlar errores tipográficos o ambigüedades menores dentro de cada componente, ya que el tipo de información en cada campo es claro.

Para lograr un comportamiento similar al de los filtros de componentes estrictos de la versión 3, debes implementar el filtrado del cliente en el array results que muestra la API de la versión 4 según los objetos postalAddress y addressComponents de la respuesta.

En la siguiente tabla, se muestra la mejor coincidencia entre los filtros components de la versión 3 y los campos postalAddress de la versión 4:

Filtro de componentes de la versión 3 Campo de respuesta de v4
country postalAddress.regionCode
postal_code postalAddress.postalCode
administrative_area postalAddress.administrativeArea o addressComponents

Ejemplos de filtrado del cliente

En los siguientes ejemplos, se muestra cómo filtrar los resultados para lograr un comportamiento similar al filtrado de componentes de la versión 3 para los campos admitidos: país, área administrativa y código postal. No se recomienda filtrar en otros campos, ya que no existen criterios de filtrado confiables.

Filtrar por país

Haz coincidir el address.regionCode de tu solicitud con el postalAddress.regionCode de cada resultado. Ten en cuenta que, si bien la API acepta códigos de región en minúsculas en la solicitud, siempre los devuelve en mayúsculas en la respuesta, por lo que debes normalizar la entrada a mayúsculas antes de la comparación.

Ejemplo de código de 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')
Ejemplo de código de 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');
Filtra por área administrativa

Haz coincidir el address.administrativeArea de tu solicitud con el postalAddress.administrativeArea de cada resultado. Al igual que con los códigos de país, debes normalizar tu entrada a mayúsculas antes de la comparación. Esto solo es confiable cuando el administrativeArea de tu solicitud se proporciona con una abreviatura estándar de 2 letras. Es posible que el postalAddress.administrativeArea de la respuesta no coincida directamente con los sufijos de los códigos ISO 3166-2 por varios motivos. En primer lugar, en algunas áreas, la subdivisión correspondiente al código ISO 3166-2 no forma parte de la representación estándar de las direcciones postales. Por ejemplo, en España, el nivel 1 del área administrativa (p.ej., "CN" para Canarias) podría estar presente en addressComponents, pero postalAddress.administrativeArea podría contener el área de nivel 2 (p.ej., "Santa Cruz de Tenerife"). En segundo lugar, en algunas áreas, la abreviatura de la subdivisión no se usa con frecuencia y se representa en postalAddress.administrativeArea con un nombre más largo (por motivos similares, es posible que addressComponents.shortText para el componente de dirección correspondiente a la subdivisión no coincida con el sufijo del código ISO 3166-2 de la subdivisión). Además, en algunos casos, la subdivisión se puede representar en el componente de dirección para administrative_area_level_n con n mayor que 1. Para obtener los resultados más completos, debes verificar si hay coincidencias tanto en postalAddress.administrativeArea como en cualquier addressComponents con un tipo administrative_area_level_n (p.ej., administrative_area_level_1).

Ejemplo de código de 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')
Ejemplo de código de 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 código postal

Haz coincidir el address.postalCode de tu solicitud con el postalAddress.postalCode de cada resultado. Debes normalizar los códigos postales de entrada y de resultado antes de la comparación. La lógica de normalización depende en gran medida de la región. Un enfoque básico implica quitar espacios y guiones, y convertir a un caso coherente.

Es posible que se necesite una normalización más avanzada para controlar los prefijos de los códigos postales (p. ej., "L2" en el Reino Unido) o los sufijos (p. ej., "+4" en los códigos postales de EE.UU.). La lógica de normalización específica requerida variará según el país y los formatos de los códigos postales involucrados. Es posible que debas adaptar las funciones de normalización proporcionadas o implementar una lógica más sofisticada para las regiones a las que te segmentas.

El ejemplo proporcionado controla los códigos postales de EE.UU. y permite la coincidencia en la base de 5 dígitos, incluso si se proporciona o devuelve ZIP+4.

Ejemplo de código de Python (enfocado en el código postal de EE.UU.)
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')
Ejemplo de código de Node.js (enfocado en códigos postales de EE.UU.)
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');

Migra desde la versión 3 de la API de geocodificación inversa

Si usas la geocodificación inversa de la versión 3 para convertir coordenadas en direcciones, debes migrar al método Geocodificación inversa de una ubicación de la versión 4, que acepta una solicitud GET.

La API v4 cambia los nombres, la estructura y la compatibilidad de varios parámetros. Te recomendamos que uses una máscara de campo para especificar los campos que deseas que se muestren en la respuesta.

Cambios en los parámetros de solicitud

Parámetro de la versión 3 Parámetro de v4 Notas
language languageCode Se cambió el nombre. Cuando se omite, la versión 3 usa el encabezado Accept-Language o, de forma predeterminada, en, mientras que la versión 4 usa de forma predeterminada el idioma y la escritura locales de la ubicación.
region regionCode Se cambió el nombre. Cuando se omite, la versión 3 usa us de forma predeterminada, mientras que la versión 4 no tiene un valor predeterminado.
result_type types Se cambió el nombre y se usan parámetros de consulta repetidos.
location_type granularity Se cambió el nombre y usa parámetros de consulta repetidos.
extra_computations Eliminado Se reemplazó por el método SearchDestinations.

Cambios en el campo de respuesta

Campo de v3 Campo v4 Notas
status, error_message Eliminado La versión 4 usa códigos de estado HTTP y cuerpos de error.
results.address_components.long_name/results.address_components.short_name results.addressComponents.longText/results.addressComponents.shortText Se cambió el nombre.
results.geometry.location_type results.granularity Se cambió el nombre.
results.geometry.location results.location Nombres de los campos: lat/lng -> latitude/longitude.
results.geometry.viewport results.viewport Nombres de los campos: northeast/southwest -> high/low.
Nuevo results.addressComponents.languageCode Es el idioma del componente de dirección específico.
Nuevo results.bounds Límites explícitos con high/low
Nuevo results.place Es el nombre del recurso del lugar.
Nuevo results.postalAddress Objeto PostalAddress estructurado.

Migra desde los descriptores de direcciones de la versión 3

Si usas address_descriptor para obtener información adicional sobre una ubicación con Geocoding v3, debes migrar al uso del campo landmarks de SearchDestinationsResponse.

Migra desde la versión 3 de la API de Place Geocoding

Si usas place_id para obtener la dirección de un ID de lugar específico con Geocoding v3, debes migrar al método Place Geocoding de la versión 4, que acepta una solicitud GET.

La API v4 cambia los nombres, la estructura y la compatibilidad de varios parámetros. Te recomendamos que uses una máscara de campo para especificar los campos que deseas que se muestren en la respuesta.

Cambios en los parámetros de solicitud

Parámetro de la versión 3 Parámetro de v4 Notas
place_id Campo place en el proto de solicitud Ahora, el ID de lugar se proporciona como un parámetro de ruta de acceso places/{place}, por ejemplo: https://geocode.googleapis.com/v4/geocode/places/ChIJj61dQgK6j4AR4GeTYWZsKWw. Esto se asigna al campo place en la solicitud subyacente.
language languageCode Se cambió el nombre. Cuando se omite, la versión 3 usa el encabezado Accept-Language o el valor predeterminado en, mientras que la versión 4 usa de forma predeterminada el idioma y la escritura locales de la ubicación.
region regionCode Se cambió el nombre. Cuando se omite, la versión 3 usa us de forma predeterminada, mientras que la versión 4 no tiene un valor predeterminado.

Cambios en el campo de respuesta

Campo de v3 Campo v4 Notas
status, error_message Eliminado La versión 4 usa códigos de estado HTTP y cuerpos de error.
results (raíz) La versión 4 devuelve un solo objeto de resultado, no un array results.
results.address_components.long_name/results.address_components.short_name addressComponents.longText/addressComponents.shortText Se cambió el nombre.
results.geometry.location_type granularity Se cambió el nombre.
results.geometry.location location Nombres de los campos: lat/lng -> latitude/longitude.
results.geometry.viewport viewport Nombres de los campos: northeast/southwest -> high/low.
results.postcode_localities postalCodeLocalities Se cambió el nombre. Ahora se devuelve para una o más localidades (la versión 3 requería más de 1).
Nuevo addressComponents.languageCode Es el idioma del componente de dirección específico.
Nuevo bounds Límites explícitos con high/low
Nuevo place Es el nombre del recurso del lugar.
Nuevo postalAddress Objeto PostalAddress estructurado.

Migra de datos hiperlocales de Geocoding a destinos

Las siguientes funciones de la versión 3 de la API de Geocoding se reemplazarán por el método SearchDestinations de la versión 4 de la API de Geocoding:

  • Entradas
  • Puntos de navegación
  • Esquemas de edificios
  • Terrenos

Si usabas la API de Geocoding v3 para las funciones anteriores, usa este documento para obtener ayuda y usar el método SearchDestinations en su lugar. En este documento, se explica en qué parte de la respuesta de SearchDestinations se encuentran estas funciones y las diferencias en la forma en que se representan en las respuestas de la API entre la API de Geocoding v3 y el método SearchDestinations de la API de Geocoding v4.

Entradas

Para obtener las entradas asociadas a un destination, usa el campo destination.entrances.

Ten en cuenta que el formato de un entrance es un poco diferente del formato de entrada de la API de Geocoding v3. Cada entrada en destination.entrances tiene los siguientes campos:

  • displayName: Es un nuevo campo opcional que tendrá un nombre legible para la entrada, por ejemplo, "Puerta B".
  • location: Es una ubicación de tipo LatLng, que es diferente del formato que se usa en la API de Geocoding v3.
  • tags: Es igual al campo tags de las entradas de la API de Geocoding v3.
  • place: Es similar al campo buildingPlaceId de las entradas de la API de Geocoding v3. Sin embargo, el ID de lugar de este campo podría corresponder a un lugar de cualquier tipo, no necesariamente solo a un edificio.

Para obtener los puntos de navegación asociados con un destination, usa el campo destination.navigationPoints.

Ten en cuenta que el formato de un navigationPoint es un poco diferente del formato del punto de navegación en la API de Geocoding v3. Cada punto de navegación en destination.navigationPoints tiene los siguientes campos:

  • displayName: Este es un nuevo campo opcional que tendrá un nombre legible por humanos para el punto de navegación, por ejemplo, "5th Ave".
  • location: Es una ubicación de tipo LatLng, que es diferente del formato que se usa en la API de Geocoding v3.
  • travelModes: Es similar al campo restrictedTravelModes de los puntos de navegación de la versión 3 de la API de Geocoding. Los valores de enumeración posibles son los mismos. La única diferencia es que este campo ahora representa los modos de viaje aceptables para el punto de navegación, en lugar de los modos de viaje restringidos.
  • usage: Es un campo nuevo que contiene los casos de uso que admite el punto de navegación.

Esquemas de edificios

Para obtener los contornos de los edificios asociados con un destination, debes usar el campo displayPolygon de los objetos placeView en el destination que representan edificios. Para cada placeView, puedes verificar si es un edificio con el campo placeView.structureType. Si el tipo de estructura es BUILDING, puedes obtener el contorno del campo placeView.displayPolygon. La placeView también tendrá campos adicionales para el edificio que no estaban en la API de Geocoding v3.

Un objeto destination puede tener un objeto placeView que represente un edificio en los siguientes campos:

  • destination.primary: Es el lugar principal del destino.
  • destination.containingPlaces: Este es un campo repetido que puede contener lugares más grandes que "contienen" el lugar principal. Por ejemplo, si el lugar principal es un subpremise, containingPlaces suele contener el placeView que representa el edificio.
  • destination.subDestinations: Es un campo repetido que puede contener subdestinos del lugar principal. Por ejemplo, las unidades de departamentos individuales de un edificio. Por lo general, este campo no tendrá un placeView que represente un edificio.

Ten en cuenta que el formato de placeView.displayPolygon coincide con el formato del contorno del edificio en la API de Geocoding v3, que es el formato GeoJSON, con el formato RFC 7946.

Terrenos

Al igual que con los contornos de edificios, para obtener los terrenos asociados con un destination, debes usar el campo displayPolygon de los objetos placeView en el destination que representan terrenos. Para cada placeView, puedes verificar si es un terreno con el campo placeView.structureType. Si el tipo de estructura es GROUNDS, puedes obtener el contorno del campo placeView.displayPolygon. El objeto placeView también tendrá campos adicionales para los motivos que no estaban en la versión 3 de la API de Geocoding.

Un destination puede tener un objeto placeView que represente un terreno en los siguientes campos:

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

Ten en cuenta que el formato de placeView.displayPolygon coincide con el formato de contorno de los terrenos en la API de Geocoding v3, que es el formato GeoJSON, con el formato RFC 7946.

Precisión de los resultados

En la API de Geocoding v3, el campo location_type de la geometría de respuesta indicaba la precisión de los resultados, y algunos clientes clasificaban o filtraban los resultados en función de estos valores (ROOFTOP, RANGE_INTERPOLATED, GEOMETRIC_CENTER y APPROXIMATE). En las migraciones estándar a la API de Geocoding v4, este campo se cambia a granularity.

En la API de Destinations (v4 SearchDestinations), no hay ningún campo location_type. En cambio, la información espacial se maneja de otra manera:

  • No se necesita filtrado manual del cliente: Si bien la API de Geocoding estándar proporciona varios resultados en diferentes niveles de detalle, el método SearchDestinations minimiza la ambigüedad, ya que resuelve una sola ubicación de destino optimizada siempre que sea posible. Esto elimina la necesidad de que los clientes filtren por tipo de ubicación para determinar qué resultado es el mejor.
  • Información espacial representada por el tipo de estructura y los polígonos de visualización: La geometría y la estructura espaciales se indican de la siguiente manera:
    • El displayPolygon (para la geometría exacta).
    • El campo structureType dentro del objeto placeView.
  • Asignación de tipos de estructura:
    • Un structureType de POINT, BUILDING o SECTION generalmente corresponde a lo que se llamaba ROOFTOP anteriormente.
    • Un structureType de GROUNDS suele corresponder a GEOMETRIC_CENTER.

Usa una máscara de campo para solicitar estas funciones

El método SearchDestinations requiere una máscara de campo, como se explica en Cómo elegir los campos que se devolverán. La máscara de campo se puede establecer en * para que se muestren todos los campos, o puedes establecerla en los campos específicos que deseas recibir. Por ejemplo, la siguiente solicitud a la API establece la máscara de campo para recibir todos los campos necesarios para obtener las entradas, los puntos de navegación, los esquemas de edificios y los terrenos de un 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

Consideraciones de seguridad

La API de Geocoding v4 está diseñada como una API de servidor a servidor. No hay una ruta de migración directa para los usuarios de JavaScript de la versión 3 a la 4. Llamar a los métodos de la versión 4 directamente desde JavaScript del cliente (por ejemplo, en un navegador) con una clave de API expone tu clave de API a un alto riesgo de robo y uso inadecuado.

Las restricciones de URLs de referencia HTTP, si bien son útiles, no son una protección suficiente para los extremos de servicios web, ya que los atacantes pueden falsificar el encabezado Referer en sus solicitudes para omitirlas con facilidad.

La forma recomendada de usar la API de Geocoding v4 es desde tu propio servidor de backend. Tu aplicación cliente debe realizar solicitudes a este servidor intermediario, que, luego, llama de forma segura a la API de Google con una clave de API protegida (por ejemplo, una clave almacenada en una variable de entorno o un Secret Manager). Esto garantiza que tu clave de API nunca se exponga en el código de frontend.

Alternativas para las necesidades del cliente

Si tienes necesidades del cliente que requieren geocodificación, considera usar una de las soluciones existentes del cliente: