Przejście na nowe autouzupełnianie miejsc

Deweloperzy z Europejskiego Obszaru Gospodarczego (EOG)

Autouzupełnianie miejsc to funkcja biblioteki Places w interfejsie Maps JavaScript API. Autouzupełnianie umożliwia dodanie do aplikacji funkcji wyszukiwania z podpowiedziami, podobnej do tej w polu wyszukiwania Map Google.

Na tej stronie wyjaśniamy różnice między starszymi a nowymi funkcjami autouzupełniania miejsc. W obu wersjach autouzupełnianie można zintegrować na 2 sposoby:

Interfejs programowy autouzupełniania

W tabeli poniżej znajdziesz niektóre główne różnice w korzystaniu z programowego autouzupełniania miejsc między usługą autouzupełniania miejsc (starsza wersja) a interfejsem Autocomplete Data API (nowa wersja):

PlacesService (starsza wersja) Place (nowa wersja)
Dokumentacja usługi autouzupełniania miejsc Dokumentacja interfejsu Autocomplete Data API (nowa wersja)
AutocompletionRequest AutocompleteRequest
AutocompleteService.getPlacePredictions AutocompleteSuggestion.fetchAutocompleteSuggestions
AutocompletePrediction PlacePrediction
Metody wymagają użycia wywołania zwrotnego do obsługi obiektu wyników i PlacesServiceStatus odpowiedzi. Korzysta z obietnic i działa asynchronicznie.
Metody wymagają sprawdzenia PlacesServiceStatus. Nie jest wymagane sprawdzanie stanu, można użyć standardowej obsługi błędów. Więcej informacji.
Pola danych o miejscach są ustawiane jako opcje podczas tworzenia instancji Autocomplete. Pola danych o miejscach są ustawiane później, gdy fetchFields() jest wywoływana.
Obsługiwane są podpowiedzi zapytań (tylko SearchBox). Podpowiedzi zapytań nie są dostępne w klasie Autocomplete.
Ograniczone do stałego zestawu typów miejsc i pól danych o miejscach. Dostęp do rozszerzonego wyboru typów miejsc i pól danych o miejscach.

Starsze i nowe interfejsy Autocomplete API używają tych samych elementów:

Porównanie kodu (programowe)

W tej sekcji porównujemy kod autouzupełniania, aby zilustrować różnice między usługą Places a klasą Place w przypadku interfejsów programowych.

Pobieranie podpowiedzi autouzupełniania (starsza wersja)

Starsza usługa Miejsca umożliwia programowe pobieranie podpowiedzi autouzupełniania, co daje większą kontrolę nad interfejsem użytkownika niż klasa Autocomplete. W tym przykładzie wysyłamy pojedyncze żądanie dotyczące „par” z elementem AutocompletionRequest zawierającym wartość wejściową i zestaw granic, które mają wpływać na podpowiedź. Przykład zwraca listę AutocompletePrediction instancji i wyświetla opis każdej z nich. Funkcja w przykładzie tworzy też token sesji i stosuje go do żądania.

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);
}

Pobieranie podpowiedzi autouzupełniania (nowa wersja)

Nowa klasa Place umożliwia też programowe pobieranie podpowiedzi autouzupełniania, co daje większą kontrolę nad interfejsem użytkownika niż klasa PlaceAutocompleteElement. W tym przykładzie wysyłamy pojedyncze żądanie dotyczące „par” z elementem AutocompleteRequest zawierającym wartość wejściową i zestaw granic, które mają wpływać na podpowiedź. Przykład zwraca listę instancji placePrediction i wyświetla opis każdej z nich. Funkcja w przykładzie tworzy też token sesji i stosuje go do żądania.

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}`
}

Widżet autouzupełniania miejsc

W tabeli poniżej znajdziesz niektóre główne różnice w korzystaniu z widżetów autouzupełniania między usługą Places (starsza wersja) a klasą Place (nowa wersja):

Usługa Places (starsza wersja) Miejsce (nowa wersja)
Autocomplete klasa do podpowiedzi miejsc. PlaceAutocompleteElement klasa do podpowiedzi miejsc.
SearchBox klasa
do podpowiedzi zapytań.
Podpowiedzi zapytań nie są dostępne w klasie Autocomplete.
Tylko domyślny tekst zastępczy pola wejściowego jest zlokalizowany. Tekst zastępczy pola wejściowego, logo listy podpowiedzi i podpowiedzi miejsc obsługują lokalizację regionalną.
Widżet używa setBounds() lub autocomplete.bindTo() aby ograniczyć (wpływać na) wyszukiwanie do określonych granic, oraz strictBounds aby ograniczyć wyniki do określonych granic. Widżet używa właściwości locationBias aby wpływać na wyniki w określonych granicach, oraz właściwości locationRestriction aby ograniczyć wyszukiwanie do określonych granic.
Widżety można zintegrować tylko za pomocą standardowego elementu wejściowego HTML. Widżet można zintegrować za pomocą standardowego elementu wejściowego HTML lub elementu gmp-place-autocomplete.
Gdy użytkownicy korzystają z widżetu, mogą wysyłać żądania dotyczące elementów które mogą być nieprawidłowe (np. „bisneyland”); w takim przypadku należy je wyraźnie obsłużyć. Widżet będzie zwracać tylko wyniki dla podanych sugestii i nie może wysyłać żądań dotyczących dowolnych wartości. Nie ma więc potrzeby obsługi potencjalnie nieprawidłowych żądań.
Zwraca starszą PlaceResult instancję. Zwraca Place instancję.
Pola danych o miejscach są ustawiane jako opcje obiektu Autocomplete. Pola danych o miejscach są ustawiane, gdy użytkownik wybierze opcję i fetchFields() zostanie wywołana.
Ograniczone do stałego zestawu typów miejsc i pól danych o miejscach. Dostęp do rozszerzonego wyboru typów miejsc i pól danych o miejscach.

Porównanie kodu (widżety)

W tej sekcji porównujemy kod autouzupełniania, aby zilustrować różnice między starszym widżetem autouzupełniania miejsc a nowym elementem autouzupełniania miejsc.

Widżet autouzupełniania miejsc (starsza wersja)

Usługa Places oferuje 2 typy widżetów autouzupełniania, które można dodać za pomocą klas Autocomplete i SearchBox. Każdy rodzaj widżetu można dodać do mapy jako element sterujący mapy lub umieścić bezpośrednio na stronie internetowej. Poniższy przykład kodu pokazuje, jak umieścić widżet Autocomplete jako element sterujący mapy.

  • Konstruktor widżetu Autocomplete przyjmuje 2 argumenty:
    • Element HTML input typu text. Jest to pole do wprowadzania danych, które będzie monitorowane przez usługę autouzupełniania, a wyniki będą do niego dołączane.
    • Opcjonalny AutocompleteOptions argument, w którym można określić dodatkowe opcje ograniczające zapytanie.
  • Aby ustawić granice, instancję Autocomplete można jawnie powiązać z mapą, wywołując funkcję autocomplete.bindTo().
  • Określ pola danych o miejscach w opcjach autouzupełniania.
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);
  });
}

Widżet autouzupełniania miejsc (nowa wersja)

Klasa Place oferuje PlaceAutocompleteElement, podklasę HTMLElement, która udostępnia komponent interfejsu użytkownika, który można dodać do mapy jako element sterujący mapy lub umieścić bezpośrednio na stronie internetowej. Poniższy przykład kodu pokazuje, jak umieścić widżet PlaceAutocompleteElement jako element sterujący mapy.

Widżet autouzupełniania miejsc został ulepszony w tych aspektach:

  • Interfejs widżetu autouzupełniania obsługuje lokalizację regionalną (w tym języki pisane od prawej do lewej) w przypadku tekstu zastępczego pola wejściowego, logo listy podpowiedzi i podpowiedzi miejsc.
  • Ulepszone ułatwienia dostępu, w tym obsługa czytników ekranu i interakcji za pomocą klawiatury.
  • Widżet autouzupełniania zwraca nową klasę Place, aby uprościć obsługę zwracanego obiektu.
  • Lepsza obsługa urządzeń mobilnych i małych ekranów.
  • Lepsza wydajność i ulepszony wygląd graficzny.

Główne różnice w implementacji:

  • Element PlaceAutocompleteElement udostępnia własne pole do wprowadzania danych i jest wstawiany bezpośrednio do strony za pomocą kodu HTML lub JavaScript (w przeciwieństwie do istniejącego elementu wejściowego).
  • Podpowiedzi zapytań nie są dostępne w Autocomplete klasie.
  • Element PlaceAutocompleteElement jest tworzony za pomocą PlaceAutocompleteElementOptions.
    • Pola danych o miejscach są określane w momencie wyboru (gdy wywoływana jest funkcja fetchFields())
  • Ustaw granice za pomocą opcji locationBounds lub 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 ( event ) => {
    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,
  });
}