Migrar para o novo Place Autocomplete

O Place Autocomplete é um recurso da biblioteca Places na API Maps JavaScript. que pode ser usado para que os apps ofereçam pesquisa durante a digitação no campo de busca do Google Maps.

Esta página explica as diferenças entre os recursos legados e novos do Place Autocomplete. Em ambas as versões, há duas maneiras gerais de integrar o preenchimento automático:

Interface programática de preenchimento automático

A tabela a seguir lista algumas das principais diferenças no uso do Place Autocomplete programático entre o serviço Place Autocomplete (legado) e a API Autocomplete Data (nova):

PlacesService (legado) Place (novo)
Referência do serviço Place Autocomplete Referência de Dados de preenchimento automático (novo)
AutocompletionRequest AutocompleteRequest
AutocompleteService.getPlacePredictions AutocompleteSuggestion.fetchAutocompleteSuggestions
AutocompletePrediction PlacePrediction
Os métodos exigem o uso de um callback para processar o objeto de resultados e a resposta PlacesServiceStatus. Usa promessas e funciona de forma assíncrona.
Os métodos exigem uma verificação PlacesServiceStatus. Nenhuma verificação de status necessária. É possível usar o tratamento de erros padrão.
Os campos de dados de local são definidos como opções quando a instância Autocomplete é criada. Os campos de dados sobre lugares são definidos mais tarde, quando fetchFields() é chamado.
As previsões de consulta são compatíveis (somente SearchBox). As previsões de consulta não estão disponíveis na classe Autocomplete.
Limitado a um conjunto fixo de tipos de lugar e campos de dados de lugar. Acesso a uma seleção ampliada de tipos de lugar e campos de dados de lugar.

Os itens a seguir são usados pelas APIs legada e nova de preenchimento automático:

Comparação de código (programática)

Esta seção compara o código do preenchimento automático para ilustrar as diferenças entre o serviço do Places e a classe Place para interfaces programáticas.

Recuperar previsões de preenchimento automático (legado)

O serviço legado do Places permite recuperar previsões de preenchimento automático de forma programática, para ter mais controle sobre a interface do usuário do que é oferecido pela classe Autocomplete. No exemplo a seguir, uma única solicitação é feita para "par", com um AutocompletionRequest que consiste no valor de entrada e um conjunto de limites para enviesar a previsão. O exemplo retorna uma lista de instâncias de AutocompletePrediction e mostra a descrição de cada uma delas. A função de exemplo também cria um token de sessão e o aplica à solicitação.

function init() {
  const placeInfo = document.getElementById("prediction");
  const service = new google.maps.places.AutocompleteService();
  const placesService = new google.maps.places.PlacesService(placeInfo);
  var sessionToken = new google.maps.places.AutocompleteSessionToken();

  // Define request options.
  let request = {
    input: "par",
    sessionToken: sessionToken,
    bounds: {
      west: -122.44,
      north: 37.8,
      east: -122.39,
      south: 37.78,
    },
  }

  // Display the query string.
  const title = document.getElementById("title");
  title.appendChild(
    document.createTextNode('Place predictions for "' + request.input + '":'),
  );

  // Perform the query and display the results.
  const displaySuggestions = function (predictions, status) {
    // Check the status of the Places Service.
    if (status != google.maps.places.PlacesServiceStatus.OK || !predictions) {
      alert(status);
      return;
    }

    predictions.forEach((prediction) => {
      const li = document.createElement("li");
      li.appendChild(document.createTextNode(prediction.description));
      document.getElementById("results").appendChild(li);
    });

    const placeRequest = {
      placeId: predictions[0].place_id,
      fields: ["name", "formatted_address"],
    };

    placesService.getDetails(placeRequest, (place, status) => {
      if (status == google.maps.places.PlacesServiceStatus.OK && place) {
        placeInfo.textContent = `
          First predicted place: ${place.name} at ${place.formatted_address}`
      }
    });

  };

  // Show the results of the query.
  service.getPlacePredictions(request, displaySuggestions);
}

Recuperar previsões de preenchimento automático (novo)

A nova classe Place também permite recuperar previsões de preenchimento automático de forma programática para ter mais controle sobre a interface do usuário do que é oferecido pela classe PlaceAutocompleteElement. No exemplo a seguir, uma única solicitação é feita para "par", com um AutocompleteRequest que consiste no valor de entrada e um conjunto de limites para enviesar a previsão. O exemplo retorna uma lista de instâncias placePrediction e mostra a descrição de cada uma delas. A função de exemplo também cria um token de sessão e o aplica à solicitação.

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

  // Define request options.
  let request = {
    input: "par",
    sessionToken: sessionToken,
    locationBias: {
      west: -122.44,
      north: 37.8,
      east: -122.39,
      south: 37.78,
    },
  };

  // Display the query string.
  const title = document.getElementById("title");
  title.appendChild(
    document.createTextNode('Place predictions for "' + request.input + '":'),
  );

  // Perform the query and display the results.
  const { suggestions } =
    await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

  const resultsElement = document.getElementById("results");

  for (let suggestion of suggestions) {
    const placePrediction = suggestion.placePrediction;
    const listItem = document.createElement("li");

    listItem.appendChild(
      document.createTextNode(placePrediction.text.text),
    );

    resultsElement.appendChild(listItem);
  }

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

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

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

  placeInfo.textContent = `
    First predicted place: ${place.displayName} at ${place.formattedAddress}`
}

Widget de Place Autocomplete

A tabela a seguir lista algumas das principais diferenças no uso de widgets de preenchimento automático entre o serviço Places (legado) e a classe Place (nova):

Serviço do Places (legado) Lugar (novo)
Classe Autocomplete para previsões de lugares. Classe PlaceAutocompleteElement para previsões de lugares.
Classe SearchBox
para previsões de consulta.
As previsões de consulta não estão disponíveis na classe Autocomplete.
Somente o texto do marcador de posição de entrada padrão é localizado. O marcador de posição de entrada de texto, o logo da lista de previsões e as estimativas de lugares são compatíveis com a localização regional.
O widget usa setBounds() ou autocomplete.bindTo() para restringir (polarizar) a pesquisa aos limites especificados e strictBounds para restringir os resultados aos limites especificados. O widget usa a propriedade locationBias para polarizar os resultados nos limites especificados e a propriedade locationRestriction para restringir a pesquisa aos limites especificados.
Os widgets só podem ser integrados usando um elemento de entrada HTML padrão. O widget pode ser integrado usando um elemento de entrada HTML padrão ou um elemento gmp-place-autocomplete.
Ao usar o widget, os usuários podem solicitar coisas que podem não ser válidas (por exemplo, "bisneyland"). Esse caso precisa ser processado explicitamente. O widget só vai retornar resultados para as sugestões fornecidas e não pode emitir solicitações para valores arbitrários. Portanto, não é necessário processar solicitações potencialmente inválidas.
Retorna a instância legada de PlaceResult. Retorna a instância Place.
Os campos de dados do lugar são definidos como opções para o objeto Autocomplete. Os campos de dados do lugar são definidos quando o usuário faz uma seleção e fetchFields() é chamado.
Limitado a um conjunto fixo de tipos de lugar e campos de dados de lugar. Acesso a uma seleção ampliada de tipos de lugar e campos de dados de lugar.

Comparação de código (widgets)

Esta seção compara o código do preenchimento automático para ilustrar as diferenças entre o widget legada do Place Autocomplete e o novo elemento do Place Autocomplete.

Widget de preenchimento automático de lugares (legado)

O serviço Places oferece dois tipos de widgets de preenchimento automático, que podem ser adicionados usando as classes Autocomplete e SearchBox. Cada tipo de widget pode ser adicionado a um mapa como um controle ou incorporado diretamente a uma página da Web. O exemplo de código a seguir mostra como incorporar um widget Autocomplete como um controle de mapa.

  • O construtor do widget Autocomplete usa dois argumentos:
    • Um elemento HTML input do tipo text. O serviço de preenchimento automático monitora esse campo e anexa os resultados a ele.
    • Um argumento AutocompleteOptions opcional, em que você pode especificar outras opções para restringir a consulta.
  • Para definir limites, a instância Autocomplete pode ser vinculada explicitamente ao mapa chamando autocomplete.bindTo().
  • Especifique campos de dados de lugar nas opções de preenchimento automático.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 40.749933, lng: -73.98633 },
    zoom: 13,
    mapTypeControl: false,
  });
  const card = document.getElementById("pac-card");
  const input = document.getElementById("pac-input");
  const options = {
    fields: ["formatted_address", "geometry", "name"],
    strictBounds: false,
  };

  map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);

  const autocomplete = new google.maps.places.Autocomplete(input, options);

  // Bind the map's bounds (viewport) property to the autocomplete object,
  // so that the autocomplete requests use the current map bounds for the
  // bounds option in the request.
  autocomplete.bindTo("bounds", map);

  const infowindow = new google.maps.InfoWindow();
  const infowindowContent = document.getElementById("infowindow-content");

  infowindow.setContent(infowindowContent);

  const marker = new google.maps.Marker({
    map,
    anchorPoint: new google.maps.Point(0, -29),
  });

  autocomplete.addListener("place_changed", () => {
    infowindow.close();
    marker.setVisible(false);

    const place = autocomplete.getPlace();

    if (!place.geometry || !place.geometry.location) {
      // User entered the name of a Place that was not suggested and
      // pressed the Enter key, or the Place Details request failed.
      window.alert("No details available for input: '" + place.name + "'");
      return;
    }

    // If the place has a geometry, then present it on a map.
    if (place.geometry.viewport) {
      map.fitBounds(place.geometry.viewport);
    } else {
      map.setCenter(place.geometry.location);
      map.setZoom(17);
    }

    marker.setPosition(place.geometry.location);
    marker.setVisible(true);
    infowindowContent.children["place-name"].textContent = place.name;
    infowindowContent.children["place-address"].textContent =
      place.formatted_address;
    infowindow.open(map, marker);
  });
}

Widget de preenchimento automático do Place (novo)

A classe Place oferece o PlaceAutocompleteElement, uma subclasse HTMLElement que fornece um componente de interface que pode ser adicionado a um mapa como um controle de mapa ou incorporado diretamente a uma página da Web. O exemplo de código a seguir mostra como incorporar um widget PlaceAutocompleteElement como um controle de mapa.

O widget do Place Autocomplete foi aprimorado das seguintes maneiras:

  • A interface do widget de preenchimento automático agora é compatível com a localização regional (incluindo idiomas direcionados da direita para a esquerda) para o marcador de posição de entrada de texto, o logo da lista de previsões e as previsões de lugares.
  • A acessibilidade foi otimizada, incluindo suporte a leitores de tela e interação com o teclado.
  • O widget de preenchimento automático retorna a nova classe Place para simplificar o processamento do objeto retornado.
  • O suporte a dispositivos móveis e telas pequenas foi aprimorado.
  • Fizemos melhorias na performance e na aparência.

As principais diferenças de implementação incluem:

  • As previsões de consulta não estão disponíveis na classe Autocomplete.
  • O PlaceAutocompleteElement é criado usando PlaceAutocompleteElementOptions.
  • Os campos de dados sobre lugares são especificados no momento da seleção (quando fetchFields() é chamado).
  • Defina limites usando a opção locationBounds ou locationRestriction.
  • Associe o PlaceAutocompleteElement a um elemento de entrada de texto HTML usando o atributo id (herdado de HTMLElement).
let map;
let marker;
let infoWindow;

async function initMap() {
  // Request needed libraries.
  const [{ Map }, { AdvancedMarkerElement }] = await Promise.all([
    google.maps.importLibrary("marker"),
    google.maps.importLibrary("places"),
  ]);

  // Initialize the map.
  map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 40.749933, lng: -73.98633 },
    zoom: 13,
    mapId: "4504f8b37365c3d0",
    mapTypeControl: false,
  });

  const placeAutocomplete =
    new google.maps.places.PlaceAutocompleteElement({
      locationRestriction: map.getBounds(),
    });

  placeAutocomplete.id = "place-autocomplete-input";
  const card = document.getElementById("place-autocomplete-card");

  card.appendChild(placeAutocomplete);
  map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);

  // Create the marker and infowindow.
  marker = new google.maps.marker.AdvancedMarkerElement({
    map,
  });
  infoWindow = new google.maps.InfoWindow({});

  // Add the gmp-placeselect listener, and display the results on the map.
  placeAutocomplete.addEventListener("gmp-placeselect", async ({ place }) => {
    await place.fetchFields({
      fields: ["displayName", "formattedAddress", "location"],
    });
    // If the place has a geometry, then present it on a map.
    if (place.viewport) {
      map.fitBounds(place.viewport);
    } else {
      map.setCenter(place.location);
      map.setZoom(17);
    }

    let content =
      '<div id="infowindow-content">' +
      '<span id="place-displayname" class="title">' +
      place.displayName +
      '</span><br />' +
      '<span id="place-address">' +
      place.formattedAddress +
      '</span>' +
      '</div>';

    updateInfoWindow(content, place.location);
    marker.position = place.location;
  });
}

// Helper function to create an info window.
function updateInfoWindow(content, center) {
  infoWindow.setContent(content);
  infoWindow.setPosition(center);
  infoWindow.open({
    map,
    anchor: marker,
    shouldFocus: false,
  });
}