La version 4 de l'API Geocoding introduit plusieurs nouvelles méthodes qui remplacent les fonctionnalités de la version 3 de l'API. Ce guide vous explique comment migrer votre application pour utiliser les nouvelles méthodes v4.
Vous pouvez utiliser vos clés API existantes avec les nouvelles méthodes v4. Toutefois, si vous avez demandé une augmentation de quota pour la version 3 de l'API, vous devez demander une augmentation pour les nouvelles API v4.
Migrer depuis le géocodage direct v3
Si vous utilisez v3 Geocoding pour géocoder des adresses, vous devez migrer vers la méthode v4 Geocode an address, qui accepte une requête GET.
L'API v4 modifie les noms, la structure et la compatibilité de plusieurs paramètres. Nous vous recommandons vivement d'utiliser un masque de champ pour spécifier les champs que vous souhaitez renvoyer dans la réponse.
Modifications des paramètres de requête
| Paramètre v3 | Paramètre v4 | Remarques |
|---|---|---|
address, components |
address |
L'adresse non structurée (v3 address) est désormais transmise dans le chemin d'URL. Les composants d'adresse structurés (components v3) peuvent être transmis en tant que paramètres de requête address.*. Consultez Reproduire les filtres de composants v3. |
bounds |
locationBias.rectangle |
Renommé ; structure remplacée par un objet. |
language |
languageCode |
Renommé. S'il est omis, la v3 utilise l'en-tête Accept-Language ou la valeur par défaut en, tandis que la v4 utilise par défaut la langue et l'écriture locales du lieu. |
region |
regionCode |
Renommé. Lorsqu'il est omis, la version 3 est définie par défaut sur us, tandis que la version 4 n'a pas de valeur par défaut. |
extra_computations |
Supprimé | Remplacée par la méthode SearchDestinations. |
Modifications apportées aux champs de réponse
| Champ v3 | Champ v4 | Remarques |
|---|---|---|
status, error_message |
Supprimé | La v4 utilise des codes d'état HTTP et des corps d'erreur. |
results.address_components.long_name/results.address_components.short_name |
results.addressComponents.longText/results.addressComponents.shortText |
Renommé. |
results.geometry.location_type |
results.granularity |
Renommé. |
results.geometry.location |
results.location |
Noms de champs : lat/lng -> latitude/longitude. |
results.geometry.viewport |
results.viewport |
Noms de champs : northeast/southwest -> high/low. |
results.postcode_localities |
results.postalCodeLocalities |
Renommé. Désormais renvoyé pour une ou plusieurs localités (v3 requiert >1). |
results.partial_match |
Supprimé | |
| Nouveauté | results.addressComponents.languageCode |
Langue du composant d'adresse spécifique. |
| Nouveauté | results.bounds |
Limites explicites à l'aide de high/low. |
| Nouveauté | results.place |
Nom de la ressource pour le lieu. |
| Nouveauté | results.postalAddress |
Objet PostalAddress structuré. |
Reproduire les filtres de composants v3
Le géocodage direct dans Geocoding v3 incluait un paramètre components qui permettait de filtrer strictement les résultats pour des composants spécifiques (par exemple, components=country:US). Le géocodage direct dans la v4 n'accepte pas ce type de filtrage strict dans les paramètres de requête. Dans la v4, vous pouvez fournir des informations d'adresse sous la forme d'une seule chaîne non structurée dans le chemin d'accès ou de paramètres de requête structurés tels que address.addressLines, address.locality, address.administrativeArea, address.postalCode et address.regionCode.
Les paramètres structurés ne font pas office de filtres stricts. Au lieu de cela, tous les composants fournis sont combinés pour former l'adresse complète que l'API tentera de géocoder. L'API recherche la meilleure correspondance pour l'adresse complète spécifiée dans tous les composants. Fournir des composants de manière structurée peut aider l'API à mieux comprendre l'intention, en particulier lorsque les informations d'adresse sont collectées à partir de champs de formulaire distincts. Cela peut aider l'API à gérer les fautes de frappe mineures ou les ambiguïtés au sein de chaque composant, car le type d'informations de chaque champ est clair.
Pour obtenir un comportement semblable à celui des filtres de composants stricts de la v3, vous devez implémenter un filtrage côté client sur le tableau results renvoyé par l'API v4 en fonction des objets postalAddress et addressComponents de la réponse.
Le tableau suivant présente la meilleure correspondance entre les filtres components de la version 3 et les champs postalAddress de la version 4 :
| Filtre de composant v3 | Champ de réponse v4 |
|---|---|
country |
postalAddress.regionCode |
postal_code |
postalAddress.postalCode |
administrative_area |
postalAddress.administrativeArea ou addressComponents |
Exemples de filtrage côté client
Les exemples suivants montrent comment filtrer les résultats pour obtenir un comportement semblable au filtrage des composants de la v3 pour les champs acceptés : pays, région administrative et code postal. Il n'est pas recommandé de filtrer sur d'autres champs, car il n'existe pas de critères de filtrage fiables.
Filtrer par pays
Faites correspondre le address.regionCode de votre requête avec le postalAddress.regionCode de chaque résultat. Notez que même si l'API accepte les codes de région en minuscules dans la requête, elle les renvoie toujours en majuscules dans la réponse. Vous devez donc normaliser votre entrée en majuscules avant de la comparer.
Exemple de code 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')
Exemple de code 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');
Filtrer par région administrative
Faites correspondre le address.administrativeArea de votre requête avec le postalAddress.administrativeArea de chaque résultat. Comme pour les codes pays, vous devez normaliser votre entrée en majuscules avant la comparaison. Cette méthode n'est fiable que lorsque le paramètre administrativeArea de votre requête est fourni avec une abréviation standard à deux lettres. Il est possible que le postalAddress.administrativeArea de la réponse ne corresponde pas directement aux suffixes de code ISO 3166-2 pour plusieurs raisons. Tout d'abord, dans certaines régions, la subdivision correspondant au code ISO 3166-2 ne fait pas partie de la représentation standard des adresses postales. Par exemple, en Espagne, la région administrative de niveau 1 (par exemple, "CN" pour les Canaries) peut être présente dans addressComponents, mais postalAddress.administrativeArea peut contenir la région de niveau 2 (par exemple, "Santa Cruz de Tenerife"). Deuxièmement, dans certaines régions, l'abréviation de la subdivision n'est pas couramment utilisée et est représentée dans postalAddress.administrativeArea par un nom plus long (pour des raisons similaires, addressComponents.shortText pour le composant d'adresse correspondant à la subdivision peut ne pas correspondre au suffixe du code ISO 3166-2 de la subdivision). De plus, dans certains cas, la subdivision peut être représentée au niveau du composant d'adresse pour administrative_area_level_n, avec n supérieur à 1.
Pour obtenir les résultats les plus complets, vous devez rechercher une correspondance à la fois dans postalAddress.administrativeArea et dans tout addressComponents avec un type administrative_area_level_n (par exemple, administrative_area_level_1).
Exemple de code 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')
Exemple de code 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');
Filtrer par code postal
Faites correspondre le address.postalCode de votre requête avec le postalAddress.postalCode de chaque résultat. Vous devez normaliser les codes postaux d'entrée et de résultat avant de les comparer. La logique de normalisation dépend fortement de la région. Une approche de base consiste à supprimer les espaces et les traits d'union, et à convertir les caractères dans une casse cohérente.
Une normalisation plus avancée peut être nécessaire pour gérer les préfixes de code postal (par exemple, "L2" au Royaume-Uni) ou les suffixes (par exemple, "+4" dans les codes postaux américains). La logique de normalisation spécifique requise varie en fonction du pays et des formats des codes postaux concernés. Vous devrez peut-être adapter les fonctions de normalisation fournies ou mettre en œuvre une logique plus sophistiquée pour les régions que vous ciblez.
L'exemple fourni gère les codes postaux américains et permet d'établir une correspondance sur la base des cinq chiffres, même si le code ZIP+4 est fourni ou renvoyé.
Exemple de code Python (axé sur les codes postaux américains)
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')
Exemple de code Node.js (axé sur les codes postaux américains)
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');
Migrer depuis le geocoding inversé v3
Si vous utilisez le geocoding inversé v3 pour convertir des coordonnées en adresses, vous devez migrer vers la méthode v4 Geocoding inversé d'un lieu, qui accepte une requête GET.
L'API v4 modifie les noms, la structure et la compatibilité de plusieurs paramètres. Nous vous recommandons vivement d'utiliser un masque de champ pour spécifier les champs que vous souhaitez renvoyer dans la réponse.
Modifications des paramètres de requête
| Paramètre v3 | Paramètre v4 | Remarques |
|---|---|---|
language |
languageCode |
Renommé. S'il est omis, la v3 utilise l'en-tête Accept-Language ou la valeur par défaut en, tandis que la v4 utilise par défaut la langue et l'écriture locales du lieu. |
region |
regionCode |
Renommé. Lorsqu'il est omis, la version 3 est définie par défaut sur us, tandis que la version 4 n'a pas de valeur par défaut. |
result_type |
types |
Renommé ; utilise des paramètres de requête répétés. |
location_type |
granularity |
Renommé ; utilise des paramètres de requête répétés. |
extra_computations |
Supprimé | Remplacée par la méthode SearchDestinations. |
Modifications apportées aux champs de réponse
| Champ v3 | Champ v4 | Remarques |
|---|---|---|
status, error_message |
Supprimé | La v4 utilise des codes d'état HTTP et des corps d'erreur. |
results.address_components.long_name/results.address_components.short_name |
results.addressComponents.longText/results.addressComponents.shortText |
Renommé. |
results.geometry.location_type |
results.granularity |
Renommé. |
results.geometry.location |
results.location |
Noms de champs : lat/lng -> latitude/longitude. |
results.geometry.viewport |
results.viewport |
Noms de champs : northeast/southwest -> high/low. |
| Nouveauté | results.addressComponents.languageCode |
Langue du composant d'adresse spécifique. |
| Nouveauté | results.bounds |
Limites explicites à l'aide de high/low. |
| Nouveauté | results.place |
Nom de la ressource pour le lieu. |
| Nouveauté | results.postalAddress |
Objet PostalAddress structuré. |
Migrer depuis les descripteurs d'adresse v3
Dans la version 3 de l'API Geocoding, la transmission de extra_computations=ADDRESS_DESCRIPTORS renvoyait un objet address_descriptor contenant landmarks[] et areas[]. Dans l'API Geocoding v4, cette fonctionnalité est remplacée par la méthode SearchDestinations (POST /v4/geocode/destinations), qui renvoie un contexte spatial enrichi directement dans chaque objet Destination.
Le tableau suivant met en correspondance les anciens champs address_descriptor de la v3 avec leurs équivalents SearchDestinations de la v4 :
Champ address_descriptor v3 |
Champ SearchDestinations v4 |
Notes de migration |
|---|---|---|
landmarks[] |
destinations[].landmarks[] |
Demandez destinations.landmarks dans votre X-Goog-FieldMask. |
landmarks[].place_id |
landmarks[].place.placeId |
Encapsulé dans l'objet place (PlaceView). |
landmarks[].display_name |
landmarks[].place.displayName |
Texte localisé (text et languageCode). |
landmarks[].types |
landmarks[].place.types |
Tableau de chaînes de types de lieux. |
landmarks[].spatial_relationship |
landmarks[].relationalDescription |
Au lieu d'une énumération brute (ACROSS_THE_ROAD, AROUND_THE_CORNER), la v4 renvoie une expression localisée et lisible par l'humain (par exemple, "Across from Central Park"). |
landmarks[].straight_line_distance_meters |
landmarks[].straightLineDistanceMeters |
Renommé en lower camelCase. |
landmarks[].travel_distance_meters |
landmarks[].travelDistanceMeters |
Renommé en lowerCamelCase. |
areas[] (énumération containment) |
destinations[].containingPlaces[] et subDestinations[] |
Équivalent disponible le plus proche pour la hiérarchie structurelle : les complexes, campus, centres commerciaux et bâtiments englobants sont renvoyés sous forme d'objets PlaceView structurés dans containingPlaces[] et subDestinations[] (avec structureType défini sur GROUNDS ou BUILDING et des contours displayPolygon facultatifs). Notez qu'il n'existe pas de remplacement direct 1:1 pour les zones de proximité de quartier/district ou l'énumération v3 containment (NEAR, WITHIN, OUTSKIRTS). |
Migrer depuis le géocodage de lieux v3
Si vous utilisez place_id pour obtenir l'adresse d'un ID de lieu spécifique avec Geocoding v3, vous devez migrer vers la méthode Place Geocoding v4, qui accepte une requête GET.
L'API v4 modifie les noms, la structure et la compatibilité de plusieurs paramètres. Nous vous recommandons vivement d'utiliser un masque de champ pour spécifier les champs que vous souhaitez renvoyer dans la réponse.
Modifications des paramètres de requête
| Paramètre v3 | Paramètre v4 | Remarques |
|---|---|---|
place_id |
Champ place dans le proto de requête |
L'ID de lieu est désormais fourni en tant que paramètre de chemin d'accès places/{place}, par exemple : https://geocode.googleapis.com/v4/geocode/places/ChIJj61dQgK6j4AR4GeTYWZsKWw. Cela correspond au champ "place" de la requête sous-jacente. |
language |
languageCode |
Renommé. En cas d'omission, la v3 utilise l'en-tête Accept-Language ou la valeur par défaut en, tandis que la v4 utilise par défaut la langue et l'écriture locales du lieu. |
region |
regionCode |
Renommé. Lorsqu'il est omis, la version 3 est définie par défaut sur us, tandis que la version 4 n'a pas de valeur par défaut. |
Modifications apportées aux champs de réponse
| Champ v3 | Champ v4 | Remarques |
|---|---|---|
status, error_message |
Supprimé | La v4 utilise des codes d'état HTTP et des corps d'erreur. |
results |
(root) | La v4 renvoie un seul objet de résultat, et non un tableau results. |
results.address_components.long_name/results.address_components.short_name |
addressComponents.longText/addressComponents.shortText |
Renommé. |
results.geometry.location_type |
granularity |
Renommé. |
results.geometry.location |
location |
Noms de champs : lat/lng -> latitude/longitude. |
results.geometry.viewport |
viewport |
Noms de champs : northeast/southwest -> high/low. |
results.postcode_localities |
postalCodeLocalities |
Renommé. Désormais renvoyé pour une ou plusieurs localités (v3 requiert >1). |
| Nouveauté | addressComponents.languageCode |
Langue du composant d'adresse spécifique. |
| Nouveauté | bounds |
Limites explicites à l'aide de high/low. |
| Nouveauté | place |
Nom de la ressource pour le lieu. |
| Nouveauté | postalAddress |
Objet PostalAddress structuré. |
Migrer des données hyperlocales de géocodage vers Destinations
Les fonctionnalités suivantes de l'API Geocoding v3 sont remplacées par la méthode SearchDestinations de l'API Geocoding v4 :
- Entrées
- Points de navigation
- Contours des bâtiments
- Domaine
Si vous utilisiez l'API Geocoding v3 pour les fonctionnalités ci-dessus, utilisez ce document pour vous aider à utiliser la méthode SearchDestinations à la place pour obtenir ces fonctionnalités.
Ce document explique où trouver ces fonctionnalités dans la réponse SearchDestinations, et les différences dans la façon dont elles sont représentées dans les réponses de l'API entre l'API Geocoding v3 et la méthode SearchDestinations de l'API Geocoding v4.
Entrées
Pour obtenir les entrées associées à un destination, utilisez le champ destination.entrances.
Chaque entrance dans destination.entrances comporte les champs suivants (en remplacement de l'ancien schéma v3 buildings.entrances) :
displayName: nouveau champ facultatif contenant un nom lisible par l'humain pour l'entrée, par exemple"Gate B".location: emplacement de typeLatLngutilisantlatitudeetlongitude(remplaçantlat/lngde la v3).tags: identique au champtagsdes entrées de l'API Geocoding v3 (commePREFERRED).place: nom de ressource du lieu (par exemple,places/ChIJ...), qui remplace le champbuilding_place_idde l'API Geocoding v3. Dans la v4, ce lieu peut représenter n'importe quelle structure de destination (bâtiment, campus ou parc), et pas seulement un bâtiment.
Points de navigation
Pour obtenir les points de navigation associés à un destination, utilisez le champ destination.navigationPoints.
Chaque navigationPoint dans destination.navigationPoints comporte les champs suivants (en remplacement de l'ancien schéma v3 navigation_points) :
navigationPointToken: chaîne de jeton chiffrée utilisée pour l'itinéraire vers ce point de navigation spécifique dans la méthodeComputeRoutes(Waypoint.navigationPointToken) de l'API Routes. Consultez Calculer un itinéraire à l'aide de jetons de point de navigation.displayName: nouveau champ facultatif contenant un nom lisible par l'humain pour le point de navigation, par exemple"5th Ave".location: un emplacement de typeLatLngutilisantlatitudeetlongitude.travelModes: semblable au champrestricted_travel_modesde l'API Geocoding v3, sauf que la v4 spécifie les modes de transport acceptables (DRIVE,WALK) plutôt que les modes de transport limités.usage: nouveau champ spécifiant les cas d'utilisation d'arrivée acceptés pour le point de navigation (par exemple,PICKUP,DROPOFFouPARKING).
Contours des bâtiments
Pour obtenir les contours des bâtiments associés à un destination, utilisez le champ displayPolygon des objets placeView du destination qui représentent des bâtiments (en remplaçant l'ancien tableau v3 buildings.building_outlines). Pour chaque placeView, vérifiez s'il s'agit d'un bâtiment avec le champ placeView.structureType. Si le type de structure est BUILDING, vous pouvez obtenir le plan à partir du champ placeView.displayPolygon. Le placeView comportera également des champs supplémentaires pour le bâtiment qui n'étaient pas présents dans l'API Geocoding v3.
Un destination peut avoir un objet placeView qui représente un bâtiment dans les champs suivants :
destination.primary: lieu principal de la destination.destination.containingPlaces: champ répété contenant des lieux plus grands qui "contiennent" le lieu principal. Par exemple, si le lieu principal est unsubpremise,containingPlacescontient généralement leplaceViewreprésentant le bâtiment.destination.subDestinations: champ répété contenant les sous-destinations du lieu principal (par exemple, des appartements ou des suites individuels dans un bâtiment).
Notez que le format de placeView.displayPolygon correspond au format de contour de bâtiment dans l'API Geocoding v3, qui est le format GeoJSON, en utilisant le format RFC 7946.
Domaine
Comme pour les contours de bâtiments, pour obtenir les terrains associés à un destination, utilisez le champ displayPolygon des objets placeView du destination qui représentent des terrains (en remplaçant l'ancien tableau v3 grounds). Pour chaque placeView, vérifiez s'il s'agit d'un polygone de terrain avec le champ placeView.structureType. Si le type de structure est GROUNDS, vous pouvez obtenir le plan à partir du champ placeView.displayPolygon. Le placeView comportera également des champs supplémentaires pour les motifs qui ne figuraient pas dans l'API Geocoding v3.
Un destination peut avoir un objet placeView qui représente un terrain dans les champs suivants :
destination.primarydestination.containingPlacesdestination.subDestinations
Notez que le format de placeView.displayPolygon correspond au format de contour des terrains dans l'API Geocoding v3, qui est le format GeoJSON, en utilisant le format RFC 7946.
Précision des résultats
Dans l'API Geocoding v3, le champ location_type de la géométrie de réponse indiquait la précision des résultats, et certains clients classaient ou filtraient les résultats en fonction de ces valeurs (ROOFTOP, RANGE_INTERPOLATED, GEOMETRIC_CENTER et APPROXIMATE). Dans les migrations standards vers l'API Geocoding v4, ce champ est renommé granularity.
Dans l'API Destinations (v4 SearchDestinations), il n'y a pas de champ location_type. Les informations spatiales sont traitées différemment :
- Aucun filtrage manuel côté client n'est nécessaire : alors que le geocoding standard fournit plusieurs résultats à différents niveaux de précision, la méthode
SearchDestinationsminimise l'ambiguïté en résolvant une seule destination optimisée dans la mesure du possible. Les clients n'ont donc plus besoin de filtrer par type de lieu pour déterminer le meilleur résultat. - Informations spatiales représentées par le type de structure et les polygones d'affichage :
La géométrie et la structure spatiales sont indiquées par :
displayPolygon(pour une géométrie exacte).- Le champ
structureTypedans l'objetplaceView.
- Mappage des types de structures :
- Un
structureTypedePOINT,BUILDINGouSECTIONcorrespond généralement à ce qui était auparavant appeléROOFTOP. - Un
structureTypedeGROUNDScorrespond généralement àGEOMETRIC_CENTER.
- Un
Utiliser un masque de champ pour demander ces fonctionnalités
La méthode SearchDestinations nécessite un masque de champ, comme expliqué dans Choisir les champs à renvoyer. Le masque de champ peut être défini sur * pour renvoyer tous les champs, ou vous pouvez le définir sur les champs spécifiques que vous souhaitez recevoir. Par exemple, la requête API suivante définit le masque de champ pour recevoir tous les champs requis pour obtenir les entrées, les points de navigation, les contours des bâtiments et les terrains d'une destination :
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
Recettes de migration et schémas de code courants
Lorsque vous migrez des workflows complexes de Geocoding v3 ou Geocoding++ vers SearchDestinations, utilisez les recettes de code suivantes pour extraire les structures spatiales et d'adresse courantes.
Extraire le meilleur polygone de bâtiment
Si vous souhaitez afficher l'empreinte d'un bâtiment pour un lieu ou une destination :
- Vérifiez si le lieu
primarycomportestructureType === 'BUILDING'et contient undisplayPolygon. - Si ce n'est pas le cas, inspectez
containingPlacespour trouver le bâtiment englobant (utile lorsque la destination principale est une sous-destination d'un bâtiment plus grand). - Si aucun bâtiment englobant n'est trouvé, vérifiez
subDestinationspour voir si des bâtiments individuels sont listés.
Exemple de code Python
def get_best_building_polygon(destination): primary = destination.get('primary', {}) if primary.get('structureType') == 'BUILDING' and 'displayPolygon' in primary: return primary['displayPolygon'] # Check containing places for the parent building for place in destination.get('containingPlaces', []): if place.get('structureType') == 'BUILDING' and 'displayPolygon' in place: return place['displayPolygon'] # Fallback to sub-destinations if available for place in destination.get('subDestinations', []): if place.get('structureType') == 'BUILDING' and 'displayPolygon' in place: return place['displayPolygon'] return None
Exemple de code Node.js
function getBestBuildingPolygon(destination) { const { primary = {}, containingPlaces = [], subDestinations = [] } = destination; if (primary.structureType === 'BUILDING' && primary.displayPolygon) { return primary.displayPolygon; } const parentBuilding = containingPlaces.find( p => p.structureType === 'BUILDING' && p.displayPolygon ); if (parentBuilding) { return parentBuilding.displayPolygon; } const subBuilding = subDestinations.find( p => p.structureType === 'BUILDING' && p.displayPolygon ); return subBuilding?.displayPolygon || null; }
Extraire le contour des terrains
Si vous avez besoin des limites d'un complexe d'appartements, d'un campus d'entreprise, d'un centre commercial ou d'un parc :
- Si le lieu
primaryreprésente l'ensemble du complexe (structureType === 'GROUNDS'), utilisezprimary.displayPolygon. - Si le lieu
primaryest un bâtiment ou une entrée situé dans un complexe plus grand, recherchez le terrain qui l'entoure danscontainingPlaces.
Exemple de code Python
def get_grounds_polygon(destination): primary = destination.get('primary', {}) if primary.get('structureType') == 'GROUNDS' and 'displayPolygon' in primary: return primary['displayPolygon'] for place in destination.get('containingPlaces', []): if place.get('structureType') == 'GROUNDS' and 'displayPolygon' in place: return place['displayPolygon'] return None
Exemple de code Node.js
function getGroundsPolygon(destination) { const { primary = {}, containingPlaces = [] } = destination; if (primary.structureType === 'GROUNDS' && primary.displayPolygon) { return primary.displayPolygon; } const groundsPlace = containingPlaces.find( p => p.structureType === 'GROUNDS' && p.displayPolygon ); return groundsPlace?.displayPolygon || null; }
Sélectionner des points de repère pour l'affichage de l'adresse par rapport à l'arrivée au dernier kilomètre
Geocoding v3 address_descriptor a renvoyé une énumération spatial_relationship (WITHIN, BESIDE, BEHIND, NEAR, ACROSS_THE_ROAD, AROUND_THE_CORNER). Dans SearchDestinations :
- Il n'existe pas d'énumération de relation brute. Utilisez plutôt
relationalDescription.textdirectement. Il contient des expressions localisées prêtes à être affichées, telles que"Across from Central Park"ou"Behind the convention center". N'ajoutez pas"Near "manuellement au début. - Utilisez
tagspour sélectionner le repère adapté à votre cas d'utilisation :ARRIVAL: repères hyperlocaux situés à proximité immédiate, en face ou de l'autre côté de la rue par rapport à la destination (généralement à une distance de 50 à 100 mètres). Idéal pour l'arrivée des chauffeurs en temps réel, la confirmation de livraison par coursier ou les cartes d'arrivée dans l'application.ADDRESS: points de repère importants à proximité (généralement dans un rayon de 100 à 500 mètres). Idéal pour le paiement côté client, l'examen des commandes ou la désambiguïsation de la destination avant le trajet.- Si un point de repère comporte à la fois les tags
ADDRESSetARRIVAL, cela signifie qu'il est bien connu dans le quartier et qu'il est immédiatement adjacent à la destination.
Exemple de code Python
def get_best_relational_landmark(destination, is_last_mile=True): """Select the best landmark based on user context. Args: destination: Destination object from SearchDestinations. is_last_mile: True for arrival and delivery guidance (prefers ARRIVAL tags). False for address display and disambiguation (prefers ADDRESS tags). Returns: Dict with landmark description, distances, tags, and placeId, or None. """ landmarks = destination.get('landmarks', []) if not landmarks: return None target_tag = 'ARRIVAL' if is_last_mile else 'ADDRESS' # Landmarks are ranked by relevance and proximity. Select the first candidate matching the target tag. for lm in landmarks: tags = lm.get('tags', []) if target_tag in tags or ('ARRIVAL' in tags and 'ADDRESS' in tags): description = lm.get('relationalDescription', {}).get('text') if description: return { 'description': description, 'travelDistanceMeters': lm.get('travelDistanceMeters'), 'straightLineDistanceMeters': lm.get('straightLineDistanceMeters'), 'tags': tags, 'placeId': lm.get('place', {}).get('placeId') } # Fallback to the first available landmark with a relational description if no tagged match is found for lm in landmarks: description = lm.get('relationalDescription', {}).get('text') if description: return { 'description': description, 'travelDistanceMeters': lm.get('travelDistanceMeters'), 'straightLineDistanceMeters': lm.get('straightLineDistanceMeters'), 'tags': lm.get('tags', []), 'placeId': lm.get('place', {}).get('placeId') } return None
Exemple de code Node.js
/** * Select the best landmark based on user context. * * @param {Object} destination Destination object from SearchDestinations. * @param {boolean} [isLastMile=true] True for arrival and delivery guidance * (prefers ARRIVAL tags). False for address display and disambiguation * (prefers ADDRESS tags). * @return {Object|null} */ function getBestRelationalLandmark(destination, isLastMile = true) { const landmarks = destination.landmarks || []; if (!landmarks.length) return null; const targetTag = isLastMile ? 'ARRIVAL' : 'ADDRESS'; // Landmarks are ranked by relevance and proximity. Select the first candidate matching the target tag. const match = landmarks.find((lm) => { const tags = lm.tags || []; return (tags.includes(targetTag) || (tags.includes('ARRIVAL') && tags.includes('ADDRESS'))) && lm.relationalDescription?.text; }) || landmarks.find((lm) => lm.relationalDescription?.text); if (match) { return { description: match.relationalDescription.text, travelDistanceMeters: match.travelDistanceMeters, straightLineDistanceMeters: match.straightLineDistanceMeters, tags: match.tags || [], placeId: match.place?.placeId || null, }; } return null; }
Itinéraire vers les points de navigation des véhicules et les entrées préférées
Les workflows de répartition et d'arrivée du dernier kilomètre combinent deux types complémentaires de points d'accès spatiaux :
- Navigation détaillée : dirigez les véhicules vers les points de dépose désignés sur la route à l'aide de
navigationPoints. Les points de navigation sont préclassés par proximité et pertinence. Ainsi, le premier candidat correspondant au mode de transport souhaité (par exemple,'DRIVE') et au tag d'utilisation (par exemple,'DROPOFF'ou'PICKUP') fournit le point de cheminement optimal pour le véhicule. Envoyez sonnavigationPointTokenà la méthodeComputeRoutes(Waypoint.navigationPointToken) de l'API Routes ou au SDK Navigation. Si aucun point de conduite aligné sur la route n'existe, utilisez l'entrée du bâtiment ou le centroïde principal. - Accès physique à l'entrée : guidez le coursier à pied ou le passager jusqu'à l'entrée du bâtiment à l'aide de
destinations.entrances. Vérifieztagspour'PREFERRED'afin de trouver les entrées qui offrent probablement un accès physique direct. Si aucune donnée d'entrée n'est disponible, utilisez un point de navigation piéton (travelModes, y compris'WALK') ou le centroïde principal.
Exemple de code Python
def get_routing_and_arrival_points(destination, usage_tag=None): navigation_points = destination.get('navigationPoints', []) entrances = destination.get('entrances', []) primary_location = destination.get('primary', {}).get('location') # 1. Doorstep / Physical Entrance # Prefer PREFERRED entrance -> any entrance -> WALK nav point -> primary location preferred_entrance = None for ent in entrances: if 'PREFERRED' in ent.get('tags', []): preferred_entrance = ent break if not preferred_entrance and entrances: preferred_entrance = entrances[0] walk_nav_point = None for np in navigation_points: if 'WALK' in np.get('travelModes', []): walk_nav_point = np break if preferred_entrance: doorstep_location = preferred_entrance.get('location') elif walk_nav_point: doorstep_location = walk_nav_point.get('location') else: doorstep_location = primary_location # 2. Vehicle Routing Waypoint # Find a driving navigation point. If usage_tag (such as 'DROPOFF' or 'PICKUP') # is specified, prioritize a candidate with that usage tag; otherwise fall back # to the first available driving point. drive_nav_point = None fallback_drive_point = None for np in navigation_points: if 'DRIVE' in np.get('travelModes', []): if usage_tag and usage_tag in np.get('usages', []): drive_nav_point = np break # Exact match for desired usage tag elif fallback_drive_point is None: fallback_drive_point = np # First driving point as fallback if not drive_nav_point: drive_nav_point = fallback_drive_point if drive_nav_point: vehicle_location = drive_nav_point.get('location') nav_token = drive_nav_point.get('navigationPointToken') elif preferred_entrance: vehicle_location = preferred_entrance.get('location') nav_token = None else: vehicle_location = primary_location nav_token = None return { 'vehicleRoutingWaypoint': { 'navigationPointToken': nav_token, 'location': vehicle_location, }, 'doorstepLocation': doorstep_location, }
Exemple de code Node.js
function getRoutingAndArrivalPoints(destination, usageTag = null) { const navigationPoints = destination.navigationPoints || []; const entrances = destination.entrances || []; const primaryLocation = destination.primary?.location || null; // 1. Doorstep / Physical Entrance const preferredEntrance = entrances.find(ent => ent.tags?.includes('PREFERRED')) || entrances[0] || null; const walkNavPoint = navigationPoints.find(np => np.travelModes?.includes('WALK')) || null; const doorstepLocation = preferredEntrance?.location || walkNavPoint?.location || primaryLocation; // 2. Vehicle Routing Waypoint // Find a driving navigation point. If usageTag (such as 'DROPOFF' or 'PICKUP') // is specified, prioritize a candidate with that usage tag; otherwise fall back // to the first available driving point. const driveNavPoint = (usageTag && navigationPoints.find(np => np.travelModes?.includes('DRIVE') && np.usages?.includes(usageTag))) || navigationPoints.find(np => np.travelModes?.includes('DRIVE')) || null; let vehicleLocation = primaryLocation; let navToken = null; if (driveNavPoint) { vehicleLocation = driveNavPoint.location; navToken = driveNavPoint.navigationPointToken; } else if (preferredEntrance) { vehicleLocation = preferredEntrance.location; } return { vehicleRoutingWaypoint: { navigationPointToken: navToken, location: vehicleLocation, }, doorstepLocation: doorstepLocation, }; }
Considérations de sécurité
L'API Geocoding v4 est conçue comme une API de serveur à serveur. Il n'existe pas de chemin de migration direct de la v3 vers la v4 pour les utilisateurs de JavaScript. L'appel des méthodes v4 directement à partir du code JavaScript côté client (par exemple, dans un navigateur) à l'aide d'une clé API expose votre clé API à un risque élevé de vol et d'utilisation abusive.
Les restrictions de l'URL de provenance HTTP, bien qu'utiles, ne constituent pas une protection suffisante pour les points de terminaison de service Web, car elles peuvent être facilement contournées par des pirates informatiques qui falsifient l'en-tête Referer dans leurs requêtes.
Approche recommandée
Nous vous recommandons d'utiliser l'API Geocoding v4 depuis votre propre serveur backend. Votre application cliente doit envoyer des requêtes à ce serveur intermédiaire, qui appelle ensuite l'API Google de manière sécurisée à l'aide d'une clé API protégée (par exemple, une clé stockée dans une variable d'environnement ou un gestionnaire de secrets). Cela garantit que votre clé API n'est jamais exposée dans le code de l'interface.
Alternatives pour les besoins côté client
Si vous avez des besoins côté client qui nécessitent un géocodage, envisagez d'utiliser l'une des solutions côté client existantes :
- Service Geocoding dans l'API Maps JavaScript : le service Geocoding continue d'utiliser le backend v3 et est conçu pour être utilisé dans un environnement de navigateur.
- Kit UI pour Places : utilisez le kit UI pour Places, y compris les éléments Place Autocomplete, pour les éléments d'interface utilisateur liés aux adresses.