Przejście na nowe autouzupełnianie miejsc

Autouzupełnianie miejsc to funkcja biblioteki Miejsca w interfejsie Maps JavaScript API. Możesz użyć autouzupełniania, aby umożliwić aplikacjom korzystanie z funkcji wyszukiwania typu „type ahead” w polu wyszukiwania w Mapach Google.

Na tej stronie opisujemy różnice między starszymi a nowymi funkcjami autouzupełniania miejsc. W obu wersjach istnieją 2 ogólne sposoby integracji funkcji Autouzupełnianie:

Interfejs automatycznego uzupełniania w ramach automatyzacji

W tabeli poniżej znajdziesz niektóre główne różnice w używaniu automatycznego autouzupełniania miejsc w ramach usługi autouzupełniania miejsc (starszej)interfejsu Autocomplete Data API (nowego):

PlacesService (starsza wersja) Place (Nowy)
Dokumentacja usługi autouzupełniania miejsc Dane autouzupełniania (nowe)
AutocompletionRequest AutocompleteRequest
AutocompleteService.getPlacePredictions AutocompleteSuggestion.fetchAutocompleteSuggestions
AutocompletePrediction PlacePrediction
Metody wymagają użycia wywołania zwrotnego do obsługi obiektu wyników i odpowiedzi PlacesServiceStatus. Korzysta z obietnic i działa asynchronicznie.
Metody wymagają sprawdzenia PlacesServiceStatus. Nie wymaga sprawdzania stanu, może używać standardowej obsługi błędów.
Pola danych o miejscu są ustawiane jako opcje podczas tworzenia instancji Autocomplete. Pola danych o miejscu są ustawiane później, gdy wywoływane jest fetchFields().
Obsługiwane są prognozy zapytań (tylko SearchBox). Podpowiedzi w zapytaniach są niedostępne w klasie Autocomplete.
Ograniczone do stałego zbioru typów miejsc i pol danych o miejscach. Dostęp do większej liczby typów miejscpól danych o miejscach.

Zarówno starszy, jak i nowy interfejs Autocomplete API używają tych elementów:

Porównanie kodu (automatyzacja)

W tej sekcji porównujemy kod służący do 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 pobieranie prognoz autouzupełniania za pomocą programów, co zapewnia większą kontrolę nad interfejsem użytkownika niż klasa Autocomplete. W tym przykładzie wysyłane jest jedno żądanie dotyczące „par”, a parametr AutocompletionRequest zawiera wartość wejściową i zbiór ograniczeń służących do ukierunkowania prognozy. Przykład zwraca listę instancji AutocompletePrediction oraz ich opisy. Przykładowa funkcja tworzy też token sesji i zastosowuje 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 (nowość)

Nowa klasa Place umożliwia też pobieranie przewidywań autouzupełniania w ramach programowania, co zapewnia większą kontrolę nad interfejsem użytkownika niż klasa PlaceAutocompleteElement. W tym przykładzie wysyłane jest jedno żądanie dotyczące „par”, a parametr AutocompleteRequest zawiera wartość wejściową i zbiór ograniczeń służących do ukierunkowania prognozy. Przykład zwraca listę instancji placePrediction oraz pokazuje opis każdej z nich. Przykładowa funkcja tworzy też token sesji i zastosowuje 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łnianie miejsc

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

Usługa Miejsca (starsza wersja) Miejsce (nowość)
Autocomplete do prognozowania miejsc. PlaceAutocompleteElement do prognozowania miejsc.
SearchBox klasa
do prognozowania zapytań.
Podpowiedzi w zapytaniach są niedostępne w klasie Autocomplete.
Tylko domyślny tekst obiektu zastępczego danych jest tłumaczony. Obiekt zastępczy tekstu, logo listy prognoz i prognozy miejsca obsługiwane są przez lokalizację regionalną.
Widget używa parametru setBounds() lub autocomplete.bindTo(), aby ograniczyć (skierować) wyszukiwanie do określonych granic, oraz parametru strictBounds, aby ograniczyć wyniki do określonych granic. Widżet używa właściwości locationBias do dopasowywania wyników do określonych granic oraz właściwości locationRestriction do ograniczania wyszukiwania 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.
Podczas korzystania z widżetu użytkownicy mogą poprosić o rzeczy, które mogą być nieprawidłowe (np. „bisneyland”). W takim przypadku należy wyraźnie obsłużyć tę sytuację. Widget zwraca wyniki tylko dla podanych sugestii i nie może wysyłać żądań dotyczących dowolnych wartości. W związku z tym nie trzeba obsługiwać potencjalnie nieprawidłowych żądań.
Zwraca starszą instancję PlaceResult. Zwraca instancję Place.
Pola danych miejsca są ustawiane jako opcje obiektu Autocomplete. Pola danych miejsca są ustawiane, gdy użytkownik dokona wyboru i wywoła funkcję fetchFields().
Ograniczone do stałego zbioru typów miejsc i pol danych o miejscach. Dostęp do większej liczby typów miejscpól danych o miejscach.

Porównanie kodu (widżety)

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

Widżet Autouzupełnianie miejsc (starsza wersja)

Usługa Miejsca oferuje 2 typy widżetów autouzupełniania, które możesz dodać za pomocą klas AutocompleteSearchBox. Każdy rodzaj widżetu można dodać do mapy jako element sterujący mapą lub osadzić bezpośrednio na stronie internetowej. Ten przykładowy kod pokazuje umieszczanie widżetu Autocomplete jako elementu sterującego mapą.

  • Konstruktor widżetu Autocomplete przyjmuje 2 argumenty:
    • Element HTML input typu text. To pole wprowadzania danych, które usługa autouzupełniania będzie monitorować i do którego będzie dołączać wyniki.
    • Opcjonalny argument AutocompleteOptions, w którym możesz określić dodatkowe opcje ograniczające zapytanie.
  • Aby ustawić granice, instancja Autocomplete może zostać jawnie powiązana z mapą przez wywołanie funkcji autocomplete.bindTo().
  • W opcjach autouzupełniania określ pola danych o miejscach.
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 (nowy)

Klasa Miejsce udostępnia obiekt PlaceAutocompleteElement, który jest podklasą HTMLElement i zawiera element interfejsu użytkownika, który można dodać do mapy jako element sterujący mapą lub osadzić bezpośrednio na stronie internetowej. Poniższy przykład kodu pokazuje umieszczanie widżetu PlaceAutocompleteElement jako elementu sterującego mapą.

Widżet autouzupełniania miejsc został ulepszony w następujący sposób:

  • Interfejs widżetu autouzupełniania obsługuje lokalizację regionalną (w tym języki z orientacją poziomą) w przypadku obiektu zastępczego w polu tekstowym, logo listy podpowiedzi i podpowiedzi dotyczących miejsc.
  • Ulepszone ułatwienia dostępu, w tym obsługa czytników ekranu i interakcji za pomocą klawiatury.
  • Aby uprościć obsługę zwracanego obiektu, widżet autouzupełniania zwraca nową klasę Place.
  • lepsza obsługa urządzeń mobilnych i małych ekranów;
  • Lepsza wydajność i wygląd graficzny.

Najważniejsze różnice w implementacji:

  • Podpowiedzi w zapytaniach są niedostępne w klasie Autocomplete.
  • Funkcja PlaceAutocompleteElement jest tworzona za pomocą funkcji PlaceAutocompleteElementOptions.
  • Pola danych o miejscach są określane w momencie wyboru (gdy wywoływana jest funkcja fetchFields()).
  • Ustaw granice, używając opcji locationBounds lub locationRestriction.
  • Połącz element HTML PlaceAutocompleteElement z elementem wejściowym tekstu HTML, używając atrybutu id (odziedziczonego z elementu 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,
  });
}