Migrar para o novo Place Autocomplete

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

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 recurso de 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 de PlacesServiceStatus. Nenhuma verificação de status necessária, pode usar o tratamento de erros padrão. Saiba mais.
Os campos de dados de lugar 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 consultas são aceitas (somente SearchBox). As previsões de consultas 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 expandida de tipos de lugar e campos de dados de lugar.

As seguintes são usadas pelas APIs Autocomplete legada e nova:

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

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

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

O serviço Places legado permite recuperar previsões de preenchimento automático de forma programática, para ter mais controle sobre a interface do usuário do que a classe Autocomplete oferece. No exemplo a seguir, uma única solicitação é feita para "par", com um AutocompletionRequest que consiste no valor de entrada e em um conjunto de limites para influenciar a previsão. O exemplo retorna uma lista de instâncias AutocompletePrediction e mostra a descrição de cada uma. 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 maneira programática para ter mais controle sobre a interface do usuário do que a oferecida 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 influenciar 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 do 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) Place (novo)
Classe Autocomplete para previsões de lugares. Classe PlaceAutocompleteElement para previsões de lugares.
Classe SearchBox
para previsões de consultas.
As previsões de consultas 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 (tendência) a pesquisa aos limites especificados e strictBounds para restringir os resultados aos limites especificados. O widget usa a propriedade locationBias para polarizar os resultados aos 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 pedir coisas que não são válidas (por exemplo, "bisneyland"). Esse caso precisa ser tratado explicitamente. O widget só vai retornar resultados para as sugestões fornecidas e não pode emitir solicitações de valores arbitrários. Portanto, não é necessário processar solicitações potencialmente inválidas.
Retorna a instância legada PlaceResult. Retorna uma instância de Place.
Os campos de dados de lugar são definidos como opções para o objeto Autocomplete. Os campos de dados de 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 expandida 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 Place Autocomplete legado e o novo elemento Place Autocomplete.

Widget do Place Autocomplete (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 em uma página da Web. O exemplo de código a seguir mostra a incorporação de 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 é possível especificar mais 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 do Place Autocomplete (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 em uma página da Web. O exemplo de código a seguir mostra a incorporação de 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 escritos da direita para a esquerda) para o marcador de posição de entrada de texto, o logo da lista de previsões e as estimativas de lugares.
  • A acessibilidade foi otimizada, incluindo compatibilidade com leitores de tela e interação com o teclado.
  • O widget de preenchimento automático retorna a nova classe Place para simplificar o gerenciamento 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:

  • O PlaceAutocompleteElement fornece o próprio campo de entrada e é inserido diretamente na página usando HTML ou JavaScript, em vez de receber um elemento de entrada existente.
  • As previsões de consultas 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 os limites usando a opção locationBounds ou locationRestriction.
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-select listener, and display the results on the map.
  placeAutocomplete.addEventListener("gmp-select", async ( place ) => {
    const place = event.placePrediction.toPlace();
    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,
  });
}