API Place Autocomplete Data

L'API Place Autocomplete Data vous permet d'extraire des prédictions de lieu de manière programmatique, afin de créer des expériences de saisie semi-automatique personnalisées avec plus de contrôle que le widget de saisie semi-automatique. Dans ce guide, vous allez apprendre à utiliser l'API Place Autocomplete Data pour effectuer des requêtes de saisie semi-automatique basées sur les requêtes des utilisateurs.

L'exemple suivant illustre une intégration simple de la saisie semi-automatique. Saisissez votre requête de recherche, puis cliquez pour sélectionner le résultat souhaité.

Requêtes Autocomplete

Une requête de saisie semi-automatique prend une chaîne d'entrée de requête et renvoie une liste de prédictions de lieux. Pour effectuer une requête de saisie semi-automatique, appelez fetchAutocompleteSuggestions() et transmettez une requête avec les propriétés nécessaires. La propriété input contient la chaîne à rechercher. Dans une application classique, cette valeur est mise à jour lorsque l'utilisateur saisit une requête. La requête doit inclure un élément sessionToken, qui est utilisé pour la facturation.

L'extrait de code suivant montre comment créer un corps de requête et ajouter un jeton de session, puis appeler fetchAutocompleteSuggestions() pour obtenir la liste des PlacePrediction.

// Add an initial request body.
let request = {
  input: "Tadi",
  locationRestriction: {
    west: -122.44,
    north: 37.8,
    east: -122.39,
    south: 37.78,
  },
  origin: { lat: 37.7893, lng: -122.4039 },
  includedPrimaryTypes: ["restaurant"],
  language: "en-US",
  region: "us",
};
// Create a session token.
const token = new AutocompleteSessionToken();

// Add the token to the request.
// @ts-ignore
request.sessionToken = token;

Limiter les prédictions de saisie semi-automatique

Par défaut, Place Autocomplete présente tous les types de lieux, avec une pondération en faveur des prédictions de lieux proches de l'utilisateur, et extrait tous les champs de données disponibles pour le lieu qu'il sélectionne. Définissez des options Place Autocomplete pour présenter des prédictions plus pertinentes en limitant ou en pondérant les résultats.

Lorsque vous limitez les résultats, le widget Autocomplete ignore les résultats qui se trouvent en dehors de la zone de restriction. Une pratique courante consiste à limiter les résultats aux limites de la carte. Pondérer la saisie semi-automatique permet d'afficher les résultats dans la zone spécifiée. Toutefois, certaines correspondances peuvent se trouver en dehors de cette zone.

Utilisez la propriété origin pour spécifier le point de départ à partir duquel calculer la distance géodésique jusqu'à la destination. Si cette valeur est omise, la distance n'est pas renvoyée.

Utilisez la propriété includedPrimaryTypes pour spécifier jusqu'à cinq types de lieux. Si aucun type n'est spécifié, les lieux de tous types sont renvoyés.

Consulter la documentation de référence de l'API

Obtenir des informations sur un lieu

Pour renvoyer un objet Place à partir d'un résultat de prédiction de lieu, appelez d'abord toPlace(), puis fetchFields() sur l'objet Place obtenu (l'ID de session de la prédiction de lieu est automatiquement inclus). L'appel de fetchFields() met fin à la session de saisie semi-automatique.

let place = suggestions[0].placePrediction.toPlace(); // Get first predicted place.

await place.fetchFields({
  fields: ["displayName", "formattedAddress"],
});

const placeInfo = document.getElementById("prediction");

placeInfo.textContent =
  "First predicted place: " +
  place.displayName +
  ": " +
  place.formattedAddress;

Jetons de session

Les jetons de session regroupent les phases de requête et de sélection d'une recherche avec saisie semi-automatique d'un utilisateur dans une session distincte à des fins de facturation. La session commence lorsque l'utilisateur commence à saisir du texte. La session se termine lorsque l'utilisateur sélectionne un lieu et qu'un appel à Place Details est effectué.

Pour créer un jeton de session et l'ajouter à une requête, créez une instance de AutocompleteSessionToken, puis définissez la propriété sessionToken de la requête pour utiliser les jetons, comme indiqué dans l'extrait suivant:

// Create a session token.
const token = new AutocompleteSessionToken();

// Add the token to the request.
// @ts-ignore
request.sessionToken = token;

Une session se termine lorsque la méthode fetchFields() est appelée. Après avoir créé l'instance Place, vous n'avez pas besoin de transmettre le jeton de session à fetchFields(), car cette opération est gérée automatiquement.

await place.fetchFields({
  fields: ["displayName", "formattedAddress"],
});
await place.fetchFields({
    fields: ['displayName'],
  });

Générez un jeton pour la session suivante en créant une instance de AutocompleteSessionToken.

Recommandations concernant les jetons de session:

  • Utilisez des jetons de session pour tous les appels Place Autocomplete.
  • Générez un nouveau jeton pour chaque session.
  • Transmettez un jeton de session unique pour chaque nouvelle session. Si vous utilisez le même jeton pour plusieurs sessions, chaque requête est facturée individuellement.

Vous pouvez éventuellement omettre le jeton de session de saisie semi-automatique d'une requête. Si le jeton de session est omis, chaque requête est facturée séparément, ce qui déclenche le SKU Autocomplete - Per Request. Si vous réutilisez un jeton de session, la session est considérée comme non valide, et les requêtes sont facturées comme si aucun jeton n'était fourni.

Exemple

Lorsque l'utilisateur saisit une requête, une requête de saisie semi-automatique est appelée à quelques frappes de touches (et non par caractère), et une liste de résultats possibles est renvoyée. Lorsque l'utilisateur effectue une sélection dans la liste des résultats, celle-ci est comptabilisée comme une requête. Toutes les requêtes effectuées au cours de la recherche sont regroupées et comptabilisées comme une seule requête. Si l'utilisateur sélectionne un lieu, la requête de recherche est disponible sans frais, et seule la requête de données de lieu est facturée. Si l'utilisateur n'effectue pas de sélection dans les minutes qui suivent le début de la session, seule la requête de recherche est facturée.

Du point de vue d'une application, le flux d'événements se présente comme suit:

  1. Un utilisateur commence à saisir une requête pour rechercher "Paris, France".
  2. Lorsqu'elle détecte une entrée utilisateur, l'application crée un jeton de session, "Jeton A".
  3. Au fur et à mesure que l'utilisateur saisit du texte, l'API envoie une requête de saisie semi-automatique à quelques caractères d'intervalle, et affiche une nouvelle liste de résultats potentiels pour chacun d'eux:
    "P"
    "Par"
    "Paris,"
    "Paris, France"
  4. Lorsque l'utilisateur effectue une sélection :
    • Toutes les requêtes résultant de la requête sont regroupées et ajoutées à la session représentée par le "Jeton A", sous la forme d'une requête unique.
    • La sélection effectuée par l'utilisateur est comptabilisée comme une requête Place Details et ajoutée à la session représentée par le "Jeton A".
  5. La session est terminée et l'application supprime le "jeton A".
En savoir plus sur la facturation des sessions

Exemple de code complet

Cette section contient des exemples complets d'utilisation de l'API Place Autocomplete Data .

Placer des prédictions de saisie semi-automatique

L'exemple suivant montre comment appeler fetchAutocompleteSuggestions() pour l'entrée "Tadi", puis toPlace() au niveau du premier résultat de prédiction, puis un appel à fetchFields() pour obtenir des détails sur le lieu.

TypeScript

/**
 * Demonstrates making a single request for Place predictions, then requests Place Details for the first result.
 */
async function init() {
    // @ts-ignore
    const { Place, AutocompleteSessionToken, AutocompleteSuggestion } = await google.maps.importLibrary("places") as google.maps.PlacesLibrary;

    // Add an initial request body.
    let request = {
        input: "Tadi",
        locationRestriction: { west: -122.44, north: 37.8, east: -122.39, south: 37.78 },
        origin: { lat: 37.7893, lng: -122.4039 },
        includedPrimaryTypes: ["restaurant"],
        language: "en-US",
        region: "us",
    };

    // Create a session token.
    const token = new AutocompleteSessionToken();
    // Add the token to the request.
    // @ts-ignore
    request.sessionToken = token;
    // Fetch autocomplete suggestions.
    const { suggestions } = await AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

    const title = document.getElementById('title') as HTMLElement;
    title.appendChild(document.createTextNode('Query predictions for "' + request.input + '":'));

    for (let suggestion of suggestions) {
        const placePrediction = suggestion.placePrediction;

        // Create a new list element.
        const listItem = document.createElement('li');
        const resultsElement = document.getElementById("results") as HTMLElement;
        listItem.appendChild(document.createTextNode(placePrediction.text.toString()));
        resultsElement.appendChild(listItem);
    }

    let place = suggestions[0].placePrediction.toPlace(); // Get first predicted place.
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress'],
    });

    const placeInfo = document.getElementById("prediction") as HTMLElement;
    placeInfo.textContent = 'First predicted place: ' + place.displayName + ': ' + place.formattedAddress;

}

init();

JavaScript

/**
 * Demonstrates making a single request for Place predictions, then requests Place Details for the first result.
 */
async function init() {
  // @ts-ignore
  const { Place, AutocompleteSessionToken, AutocompleteSuggestion } =
    await google.maps.importLibrary("places");
  // Add an initial request body.
  let request = {
    input: "Tadi",
    locationRestriction: {
      west: -122.44,
      north: 37.8,
      east: -122.39,
      south: 37.78,
    },
    origin: { lat: 37.7893, lng: -122.4039 },
    includedPrimaryTypes: ["restaurant"],
    language: "en-US",
    region: "us",
  };
  // Create a session token.
  const token = new AutocompleteSessionToken();

  // Add the token to the request.
  // @ts-ignore
  request.sessionToken = token;

  // Fetch autocomplete suggestions.
  const { suggestions } =
    await AutocompleteSuggestion.fetchAutocompleteSuggestions(request);
  const title = document.getElementById("title");

  title.appendChild(
    document.createTextNode('Query predictions for "' + request.input + '":'),
  );

  for (let suggestion of suggestions) {
    const placePrediction = suggestion.placePrediction;
    // Create a new list element.
    const listItem = document.createElement("li");
    const resultsElement = document.getElementById("results");

    listItem.appendChild(
      document.createTextNode(placePrediction.text.toString()),
    );
    resultsElement.appendChild(listItem);
  }

  let place = suggestions[0].placePrediction.toPlace(); // Get first predicted place.

  await place.fetchFields({
    fields: ["displayName", "formattedAddress"],
  });

  const placeInfo = document.getElementById("prediction");

  placeInfo.textContent =
    "First predicted place: " +
    place.displayName +
    ": " +
    place.formattedAddress;
}

init();

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

HTML

<html>
  <head>
    <title>Place Autocomplete Data API Predictions</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="title"></div>
    <ul id="results"></ul>
    <p><span id="prediction"></span></p>
    <img
      class="powered-by-google"
      src="https://storage.googleapis.com/geo-devrel-public-buckets/powered_by_google_on_white.png"
      alt="Powered by Google"
    />

    <!-- prettier-ignore -->
    <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "weekly"});</script>
  </body>
</html>

Essayer avec un exemple

Place à la saisie semi-automatique avec les sessions

Cet exemple montre comment appeler fetchAutocompleteSuggestions() en fonction des requêtes des utilisateurs, afficher une liste de lieux prédits dans la réponse et enfin récupérer les détails du lieu sélectionné. L'exemple illustre également l'utilisation de jetons de session pour regrouper une requête utilisateur dans la requête Places Details finale.

TypeScript

let title;
let results;
let input;
let token;

// Add an initial request body.
let request = {
    input: "",
    locationRestriction: { west: -122.44, north: 37.8, east: -122.39, south: 37.78 },
    origin: { lat: 37.7893, lng: -122.4039 },
    includedPrimaryTypes: ["restaurant"],
    language: "en-US",
    region: "us",
};

async function init() {
    token = new google.maps.places.AutocompleteSessionToken();

    title = document.getElementById('title');
    results = document.getElementById('results');
    input = document.querySelector("input");
    input.addEventListener("input", makeAcRequest);
    request = refreshToken(request) as any;
}

async function makeAcRequest(input) {
    // Reset elements and exit if an empty string is received.
    if (input.target.value == '') {
        title.innerText = '';
        results.replaceChildren();
        return;
    }

    // Add the latest char sequence to the request.
    request.input = input.target.value;

    // Fetch autocomplete suggestions and show them in a list.
    // @ts-ignore
    const { suggestions } = await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

    title.innerText = 'Query predictions for "' + request.input + '"';

    // Clear the list first.
    results.replaceChildren();

    for (const suggestion of suggestions) {
        const placePrediction = suggestion.placePrediction;

        // Create a link for the place, add an event handler to fetch the place.
        const a = document.createElement('a');
        a.addEventListener('click', () => {
            onPlaceSelected(placePrediction.toPlace());
        });
        a.innerText = placePrediction.text.toString();

        // Create a new list element.
        const li = document.createElement('li');
        li.appendChild(a);
        results.appendChild(li);
    }
}

// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress'],
    });
    let placeText = document.createTextNode(place.displayName + ': ' + place.formattedAddress);
    results.replaceChildren(placeText);
    title.innerText = 'Selected Place:';
    input.value = '';
    refreshToken(request);
}

// Helper function to refresh the session token.
async function refreshToken(request) {
    // Create a new session token and add it to the request.
    token = new google.maps.places.AutocompleteSessionToken();
    request.sessionToken = token;
    return request;
}

declare global {
    interface Window {
      init: () => void;
    }
  }
  window.init = init;

JavaScript

let title;
let results;
let input;
let token;
// Add an initial request body.
let request = {
  input: "",
  locationRestriction: {
    west: -122.44,
    north: 37.8,
    east: -122.39,
    south: 37.78,
  },
  origin: { lat: 37.7893, lng: -122.4039 },
  includedPrimaryTypes: ["restaurant"],
  language: "en-US",
  region: "us",
};

async function init() {
  token = new google.maps.places.AutocompleteSessionToken();
  title = document.getElementById("title");
  results = document.getElementById("results");
  input = document.querySelector("input");
  input.addEventListener("input", makeAcRequest);
  request = refreshToken(request);
}

async function makeAcRequest(input) {
  // Reset elements and exit if an empty string is received.
  if (input.target.value == "") {
    title.innerText = "";
    results.replaceChildren();
    return;
  }

  // Add the latest char sequence to the request.
  request.input = input.target.value;

  // Fetch autocomplete suggestions and show them in a list.
  // @ts-ignore
  const { suggestions } =
    await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(
      request,
    );

  title.innerText = 'Query predictions for "' + request.input + '"';
  // Clear the list first.
  results.replaceChildren();

  for (const suggestion of suggestions) {
    const placePrediction = suggestion.placePrediction;
    // Create a link for the place, add an event handler to fetch the place.
    const a = document.createElement("a");

    a.addEventListener("click", () => {
      onPlaceSelected(placePrediction.toPlace());
    });
    a.innerText = placePrediction.text.toString();

    // Create a new list element.
    const li = document.createElement("li");

    li.appendChild(a);
    results.appendChild(li);
  }
}

// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
  await place.fetchFields({
    fields: ["displayName", "formattedAddress"],
  });

  let placeText = document.createTextNode(
    place.displayName + ": " + place.formattedAddress,
  );

  results.replaceChildren(placeText);
  title.innerText = "Selected Place:";
  input.value = "";
  refreshToken(request);
}

// Helper function to refresh the session token.
async function refreshToken(request) {
  // Create a new session token and add it to the request.
  token = new google.maps.places.AutocompleteSessionToken();
  request.sessionToken = token;
  return request;
}

window.init = init;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

a {
  cursor: pointer;
  text-decoration: underline;
  color: blue;
}

input {
  width: 300px;
}

HTML

<html>
  <head>
    <title>Place Autocomplete Data API Session</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <input id="input" type="text" placeholder="Search for a place..." />
    <div id="title"></div>
    <ul id="results"></ul>
    <img
      class="powered-by-google"
      src="https://storage.googleapis.com/geo-devrel-public-buckets/powered_by_google_on_white.png"
      alt="Powered by Google"
    />

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=init&libraries=places&v=weekly"
      defer
    ></script>
  </body>
</html>

Essayer avec un exemple