API Place Autocomplete Data

L'API Place Autocomplete Data vous permet d'extraire des prédictions de lieux de manière programmatique afin de créer des expériences de saisie semi-automatique personnalisées avec un degré de contrôle plus précis que celui sans frais par 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 en fonction des requêtes des utilisateurs.

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

Requêtes Autocomplete

Une requête de saisie semi-automatique prend une chaîne 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 requises. La propriété input contient la chaîne à rechercher. Dans une application typique, cette valeur est mise à jour lorsque l'utilisateur saisit une requête. La requête doit inclure un sessionToken, qui est utilisé à des fins de 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 une liste de 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.

Si vous limitez les résultats, le widget de saisie semi-automatique ignore tous les résultats 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 d'origine à 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é, tous les types de lieux 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 appelez fetchFields() sur l'objet Place généré (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 de 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 de code 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 fetchFields() est appelé. Une fois l'instance Place créée, vous n'avez pas besoin de transmettre le jeton de session à fetchFields(), car cela est géré automatiquement.

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

Créez un jeton de session pour la prochaine session 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 Autocomplete 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 en réutilisez un, 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 toutes les quelques frappes (et non par caractère), et une liste de résultats possibles est renvoyée. Lorsque l'utilisateur fait une sélection dans la liste de résultats, cette sélection est comptabilisée comme une requête. Toutes les requêtes effectuées lors 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 sur le lieu est facturée. Si l'utilisateur ne fait pas de sélection dans les quelques minutes suivant 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. Lorsque l'application détecte une entrée utilisateur, elle crée un nouveau jeton de session, "Jeton A".
  3. À mesure que l'utilisateur saisit du texte, l'API envoie une requête de saisie semi-automatique tous les quelques caractères, et affiche une nouvelle liste de résultats potentiels pour chacun:
    "P"
    "Par"
    "Paris,"
    "Paris, Fr"
  4. Lorsque l'utilisateur fait une sélection :
    • Toutes les requêtes issues de la requête sont regroupées et ajoutées à la session représentée par le jeton A, en tant que requête unique.
    • La sélection de 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 qui montrent comment utiliser l'API Place Autocomplete Data .

Prédictions de saisie semi-automatique de lieux

L'exemple suivant montre comment appeler fetchAutocompleteSuggestions() pour la saisie "Tadi", puis appeler toPlace() sur le premier résultat de prédiction, suivi d'un appel à fetchFields() pour obtenir des informations 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>

    <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

Saisie semi-automatique Place Autocomplete avec sessions

Cet exemple montre comment appeler fetchAutocompleteSuggestions() en fonction des requêtes de l'utilisateur, afficher une liste de lieux prédits en réponse et, enfin, récupérer les informations sur le lieu sélectionné. L'exemple montre également comment utiliser des jetons de session pour regrouper une requête utilisateur avec la requête Place 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>

    <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