API Place Autocomplete Data

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

A API Place Autocomplete Data permite buscar previsões de lugares de forma programática para criar experiências de preenchimento automático personalizadas com um grau de controle mais refinado do que é possível com o widget de preenchimento automático. Neste guia, você vai aprender a usar a API Place Autocomplete Data para fazer solicitações de preenchimento automático com base em consultas do usuário.

O exemplo a seguir mostra uma integração simplificada de preenchimento automático. Digite sua consulta de pesquisa, como "pizza" ou "poke", e clique para selecionar o resultado desejado.

Solicitações de Autocomplete

Uma solicitação de preenchimento automático usa uma string de entrada de consulta e retorna uma lista de previsões de lugares. Para fazer uma solicitação de preenchimento automático, chame fetchAutocompleteSuggestions() e transmita uma solicitação com as propriedades necessárias. A propriedade input contém a string a ser pesquisada. Em um aplicativo típico, esse valor seria atualizado à medida que o usuário digita uma consulta. A solicitação precisa incluir um sessionToken, que é usado para fins de faturamento.

O snippet a seguir mostra como criar um corpo de solicitação e adicionar um token de sessão. Em seguida, ele chama fetchAutocompleteSuggestions() para receber uma lista de PlacePredictions.

// 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;

Restringir previsões de preenchimento automático

Por padrão, o Place Autocomplete apresenta todos os tipos de lugares, favorece previsões perto da localização do usuário e busca todos os campos de dados disponíveis para o lugar que a pessoa selecionou. Defina as opções do Place Autocomplete para mostrar previsões mais relevantes restringindo ou polarizando os resultados.

Quando você limita os resultados, o widget de preenchimento automático ignora todos os resultados que estão fora da área de restrição. Uma prática comum é restringir os resultados aos limites do mapa. A polarização de resultados faz com que o widget de preenchimento automático mostre resultados dentro da área especificada, mas algumas correspondências podem estar fora dessa região.

Use a propriedade origin para especificar o ponto de origem de onde calcular a distância geodésica até o destino. Se esse valor for omitido, a distância não será retornada.

Use a propriedade includedPrimaryTypes para especificar até cinco tipos de lugar. Se nenhum tipo for especificado, todos os tipos de lugares serão retornados.

Consulte a referência da API

Conferir detalhes sobre o lugar

Para retornar um objeto Place de um resultado de previsão de lugar, primeiro chame toPlace() e depois fetchFields() no objeto Place resultante. O ID da sessão da previsão de lugar é incluído automaticamente. Chamar fetchFields() encerra a sessão de preenchimento automático.

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;

Tokens de sessão

Os tokens de sessão agrupam as fases de consulta e seleção de uma pesquisa de preenchimento automático do usuário em uma sessão discreta para fins de faturamento. A sessão começa quando o usuário começa a digitar. A sessão é concluída quando o usuário seleciona um lugar e uma chamada para Place Details é feita.

Para criar um token de sessão e adicioná-lo a uma solicitação, crie uma instância de AutocompleteSessionToken, defina a propriedade sessionToken da solicitação para usar os tokens, conforme mostrado no snippet a seguir:

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

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

Uma sessão é concluída quando fetchFields() é chamado. Depois de criar a instância Place, não é necessário transmitir o token de sessão para fetchFields(), já que isso é processado automaticamente.

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

Crie um token de sessão para a próxima sessão criando uma nova instância de AutocompleteSessionToken.

Recomendações de token de sessão:

  • Use tokens de sessão para todas as chamadas do Place Autocomplete.
  • Gere um novo token para cada sessão.
  • Transmita um token de sessão exclusivo para cada sessão nova. Se você usar o mesmo token para mais de uma sessão, cada solicitação vai ser faturada individualmente.

Você pode omitir o token de sessão do Autocomplete de uma solicitação. Se o token de sessão for omitido, cada solicitação será faturada separadamente, acionando a SKU Autocomplete – por solicitação. Se você reutilizar um token, a sessão será considerada inválida, e as solicitações serão cobradas como se nenhum token de sessão tivesse sido fornecido.

Exemplo

À medida que o usuário digita uma consulta, uma solicitação de preenchimento automático é chamada a cada poucas teclas (não por caractere), e uma lista de possíveis resultados é retornada. Quando o usuário faz uma seleção na lista de resultados, ela é contabilizada como uma solicitação, e todas as solicitações feitas durante a pesquisa são agrupadas e contadas como uma única solicitação. Se o usuário selecionar um lugar, a consulta de pesquisa estará disponível sem custos financeiros, e apenas a solicitação de dados do lugar será cobrada. Se o usuário não fizer uma seleção em alguns minutos após o início da sessão, apenas a consulta de pesquisa será cobrada.

Do ponto de vista de um app, o fluxo de eventos é assim:

  1. Um usuário começa a digitar uma consulta para pesquisar "Paris, França".
  2. Ao detectar a entrada do usuário, o app cria um novo token de sessão, "Token A".
  3. À medida que o usuário digita, a API faz uma solicitação de preenchimento automático a cada poucos caracteres, mostrando uma nova lista de resultados possíveis para cada um:
    "P"
    "Par"
    "Paris"
    "Paris, Fr"
  4. Quando o usuário faz uma seleção:
    • Todas as solicitações resultantes da consulta são agrupadas e adicionadas à sessão representada pelo "Token A" como uma única solicitação.
    • A seleção do usuário é contabilizada como uma solicitação de Place Details e adicionada à sessão representada pelo "Token A".
  5. A sessão é concluída, e o app descarta o "Token A".
Saiba como as sessões são cobradas

Exemplo de código completo

Esta seção contém exemplos completos que mostram como usar a API Place Autocomplete Data .

Previsões de preenchimento automático de lugar

O exemplo a seguir demonstra como chamar fetchAutocompleteSuggestions() para a entrada "Tadi", depois chamar toPlace() no primeiro resultado da previsão, seguido por uma chamada para fetchFields() para receber detalhes do lugar.

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>

Testar amostra

Preenchimento automático de texto do Place Autocomplete com sessões

Este exemplo demonstra a chamada de fetchAutocompleteSuggestions() com base em consultas do usuário, mostrando uma lista de lugares previstos em resposta e, por fim, recuperando detalhes do lugar selecionado. O exemplo também demonstra o uso de tokens de sessão para agrupar uma consulta do usuário com a solicitação final de Place Details.

TypeScript

let titleElement;
let resultsContainerElement;
let inputElement;

let newestRequestId = 0;

// Add an initial request body.
const 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',
};

function init() {
    titleElement = document.getElementById('title');
    resultsContainerElement = document.getElementById('results');
    inputElement = document.querySelector('input');
    inputElement.addEventListener('input', makeAutocompleteRequest);
    refreshToken(request);
}

async function makeAutocompleteRequest(inputEvent) {
    // Reset elements and exit if an empty string is received.
    if (inputEvent.target.value == '') {
        titleElement.innerText = '';
        resultsContainerElement.replaceChildren();
        return;
    }

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

    // To avoid race conditions, store the request ID and compare after the request.
    const requestId = ++newestRequestId;

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

    // If the request has been superseded by a newer request, do not render the output.
    if (requestId !== newestRequestId) return;

    titleElement.innerText = `Query predictions for "${request.input}"`;

    // Clear the list first.
    resultsContainerElement.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 item element.
        const li = document.createElement('li');
        li.appendChild(a);
        resultsContainerElement.appendChild(li);
    }
}

// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress'],
    });
    const placeText = document.createTextNode(`${place.displayName}: ${place.formattedAddress}`);
    resultsContainerElement.replaceChildren(placeText);
    titleElement.innerText = 'Selected Place:';
    inputElement.value = '';
    refreshToken(request);
}

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

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

JavaScript

let titleElement;
let resultsContainerElement;
let inputElement;
let newestRequestId = 0;
// Add an initial request body.
const 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',
};
function init() {
    titleElement = document.getElementById('title');
    resultsContainerElement = document.getElementById('results');
    inputElement = document.querySelector('input');
    inputElement.addEventListener('input', makeAutocompleteRequest);
    refreshToken(request);
}
async function makeAutocompleteRequest(inputEvent) {
    // Reset elements and exit if an empty string is received.
    if (inputEvent.target.value == '') {
        titleElement.innerText = '';
        resultsContainerElement.replaceChildren();
        return;
    }
    // Add the latest char sequence to the request.
    request.input = inputEvent.target.value;
    // To avoid race conditions, store the request ID and compare after the request.
    const requestId = ++newestRequestId;
    // Fetch autocomplete suggestions and show them in a list.
    // @ts-ignore
    const { suggestions } = await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);
    // If the request has been superseded by a newer request, do not render the output.
    if (requestId !== newestRequestId)
        return;
    titleElement.innerText = `Query predictions for "${request.input}"`;
    // Clear the list first.
    resultsContainerElement.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 item element.
        const li = document.createElement('li');
        li.appendChild(a);
        resultsContainerElement.appendChild(li);
    }
}
// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress'],
    });
    const placeText = document.createTextNode(`${place.displayName}: ${place.formattedAddress}`);
    resultsContainerElement.replaceChildren(placeText);
    titleElement.innerText = 'Selected Place:';
    inputElement.value = '';
    refreshToken(request);
}
// Helper function to refresh the session token.
function refreshToken(request) {
    // Create a new session token and add it to the request.
    request.sessionToken = new google.maps.places.AutocompleteSessionToken();
}
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=AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8&callback=init&libraries=places&v=weekly"
      defer
    ></script>
  </body>
</html>

Testar amostra