Przejście na nowe autouzupełnianie miejsc

Deweloperzy z Europejskiego Obszaru Gospodarczego (EOG)

Autouzupełnianie miejsc to funkcja biblioteki Miejsc w Maps JavaScript API. Możesz użyć autouzupełniania, aby zapewnić swoim aplikacjom funkcję wyszukiwania z podpowiedziami w polu wyszukiwania Map Google.

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

Interfejs programowy autouzupełniania

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

PlacesService (starsza wersja) Place (Nowość)
Dokumentacja usługi autouzupełniania miejsc Dokumentacja Autocomplete Data (new)
AutocompletionRequest AutocompleteRequest
AutocompleteService.getPlacePredictions AutocompleteSuggestion.fetchAutocompleteSuggestions
AutocompletePrediction PlacePrediction
Metody wymagają użycia wywołania zwrotnego do obsługi obiektu wyników i odpowiedzi PlacesServiceStatus. Używa obiektów Promise 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 miejsc są ustawiane jako opcje podczas tworzenia instancji Autocomplete. Pola danych miejsca są ustawiane później, gdy wywoływana jest funkcja fetchFields().
Obsługiwane są podpowiedzi zapytań (tylko SearchBox). Podpowiedzi zapytań są niedostę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.

Te elementy są używane zarówno przez starsze, jak i nowe interfejsy Autocomplete API:

Porównanie kodów (automatyzacja)

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

Pobieranie podpowiedzi autouzupełniania (starsza wersja)

Starsza usługa Places umożliwia automatyczne pobieranie podpowiedzi autouzupełniania, co zapewnia większą kontrolę nad interfejsem użytkownika niż klasa Autocomplete. W poniższym przykładzie wysyłane jest pojedyncze żądanie dotyczące „par” z parametrem AutocompletionRequest, który składa się z wartości wejściowej i zestawu granic do ukierunkowania podpowiedzi. Przykład zwraca listę instancji AutocompletePrediction i wyświetla opis każdej z nich. Przykładowa funkcja 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 (nowość)

Nowa klasa Place umożliwia też automatyczne pobieranie podpowiedzi autouzupełniania, co zapewnia większą kontrolę nad interfejsem użytkownika niż klasa PlaceAutocompleteElement. W poniższym przykładzie wysyłane jest pojedyncze żądanie dla „par” z parametrem AutocompleteRequest, który składa się z wartości wejściowej i zestawu granic do ukierunkowania podpowiedzi. W przykładzie zwracana jest lista instancji placePrediction i wyświetlany jest opis każdej z nich. Przykładowa funkcja 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 z głównych różnic w korzystaniu z widżetów autouzupełniania między usługą Places (starsza wersja) a klasą Place (nowa wersja):

Places Service (starsza wersja) Miejsce (nowość)
Klasa Autocomplete do podpowiedzi miejsc. Klasa PlaceAutocompleteElement do podpowiedzi miejsc.
SearchBox
do prognozowania zapytań.
Podpowiedzi zapytań są niedostępne w klasie Autocomplete.
Tłumaczony jest tylko domyślny tekst zastępczy pola do wprowadzania danych. Obiekt zastępczy do wpisywania tekstu, logo listy podpowiedzi i podpowiedzi miejsc obsługują lokalizację regionalną.
Widżet używa setBounds() lub autocomplete.bindTo(), aby ograniczyć (ukierunkować) wyszukiwanie do określonych granic, oraz strictBounds, aby ograniczyć wyniki do określonych granic. Widżet używa właściwości locationBias, aby faworyzować wyniki w określonych granicach, oraz właściwości locationRestriction, aby ograniczyć wyszukiwanie do określonych granic.
Widżety można integrować 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ą prosić o rzeczy, które mogą być nieprawidłowe (np. „bisneyland”). Ten przypadek musi być wyraźnie obsługiwany. Widżet zwraca wyniki tylko dla podanych sugestii i nie może wysyłać żądań dotyczących dowolnych wartości, więc nie ma potrzeby obsługi 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 zostanie wywołana metoda fetchFields().
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 rodzaje widżetów autouzupełniania, które możesz dodawać za pomocą klas Autocomplete i SearchBox. Każdy rodzaj widżetu można dodać do mapy jako element sterujący lub umieścić bezpośrednio na stronie internetowej. Poniższy przykładowy kod pokazuje, jak umieścić widżet Autocomplete jako element sterujący mapy.

  • Konstruktor widżetu Autocomplete przyjmuje 2 argumenty:
    • Element HTML input typu text. To jest pole do 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, instancję Autocomplete można jawnie powiązać z mapą, wywołując autocomplete.bindTo().
  • Określ pola danych miejsc 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 (nowy)

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

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 zapisywane od prawej do lewej) w przypadku tekstu zastępczego pola tekstowego, 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.
  • Wyższa wydajność i lepszy wygląd graficzny.

Najważniejsze różnice we wdrażaniu:

  • PlaceAutocompleteElement ma własne pole do wprowadzania danych i jest wstawiany bezpośrednio na stronę za pomocą kodu HTML lub JavaScriptu (w odróżnieniu od istniejącego elementu wejściowego).
  • Podpowiedzi zapytań nie są dostępne w klasie Autocomplete.
  • PlaceAutocompleteElement jest tworzony za pomocą PlaceAutocompleteElementOptions.
    • Pola danych miejsca są określane w momencie wyboru (gdy wywoływana jest metoda 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", "viewport"],
    });
    // 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,
  });
}