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 wyprzedzeniem, która działa podobnie jak pole 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 Autocomplete:

Interfejs programowy autouzupełniania

W tabeli poniżej znajdziesz główne różnice w używaniu programowego autouzupełniania miejsc między usługą Autouzupełnianie miejsc (starszą)interfejsem Autocomplete Data API (nowym):

PlacesService (starsza wersja) Place (Nowy)
Dokumentacja usługi Autouzupełnianie miejsc Dokumentacja danych autouzupełniania (nowość)
AutocompletionRequest AutocompleteRequest
AutocompleteService.getPlacePredictions AutocompleteSuggestion.fetchAutocompleteSuggestions
AutocompletePrediction PlacePrediction
Metody wymagają użycia wywołania zwrotnego do obsługi obiektu wyników i PlacesServiceStatusodpowiedzi. Korzysta z obiektów Promise i działa asynchronicznie.
Metody wymagają sprawdzenia PlacesServiceStatus. Nie wymaga sprawdzania stanu, można użyć standardowej obsługi błędów. Więcej informacji
Pola danych o miejscach są ustawiane jako opcje podczas tworzenia instancjiAutocomplete. Pola danych miejsca są ustawiane później, gdy wywoływana jest funkcja fetchFields().
Obsługiwane są prognozy zapytań (tylko SearchBox). Prognozy zapytań nie są dostępne w przypadku klasy Autocomplete.
Ograniczone do stałego zestawu typów miejscpól danych o miejscach. Dostęp do rozszerzonego wyboru 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 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 Miejsc umożliwia programowe pobieranie prognoz autouzupełniania, co daje większą kontrolę nad interfejsem użytkownika niż klasa Autocomplete. W poniższym przykładzie wysyłane jest pojedyncze żądanie dotyczące „par” z AutocompletionRequest zawierającym wartość wejściową i zestaw granic do określania preferencji w prognozie. 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ż programowe pobieranie prognoz autouzupełniania, co daje większą kontrolę nad interfejsem użytkownika niż klasa PlaceAutocompleteElement. W poniższym przykładzie wysyłane jest pojedyncze żądanie dotyczące słowa „par” z AutocompleteRequest zawierającym wartość wejściową i zestaw zakresów do określania preferencji w prognozie. Przykład zwraca listę placePrediction instancji i wyświetla 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 główne różnice w używaniu widżetów autouzupełniania w usłudze Miejsca (starszej) i klasie Place (nowej):

Usługa Miejsca (starsza wersja) Miejsce (nowość)
klasy Autocomplete do prognozowania miejsc. klasy PlaceAutocompleteElement do prognozowania miejsc.
SearchBox class
do prognozowania zapytań.
Prognozy zapytań nie są dostępne w przypadku klasy Autocomplete.
Zlokalizowany jest tylko domyślny tekst zastępczy danych wejściowych. Obiekt zastępczy wpisywania tekstu, logo listy prognoz i prognozy miejsc obsługują lokalizację regionalną.
Widżet używa parametrów setBounds() lub autocomplete.bindTo(), aby ograniczyć (ukierunkować) wyszukiwanie do określonych granic, oraz parametru strictBounds, aby ograniczyć wyniki do określonych granic. Widżet używa właściwości locationBias, aby dostosować wyniki do określonych granic, 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.
Podczas korzystania z widżetu użytkownicy mogą wysyłać nieprawidłowe żądania (np. „bisneyland”). W takim przypadku należy podjąć odpowiednie działania. Widżet zwraca wyniki tylko dla podanych sugestii i nie może wysyłać żądań dotyczących dowolnych wartości, dlatego nie musisz obsługiwać potencjalnie nieprawidłowych żądań.
Zwraca instancję starszej wersji PlaceResult. Zwraca instancję Place.
Pola danych o miejscu są ustawiane jako opcje obiektu Autocomplete. Pola danych o miejscu są ustawiane, gdy użytkownik dokona wyboru i zostanie wywołana funkcja fetchFields().
Ograniczone do stałego zestawu typów miejscpól danych o miejscach. Dostęp do rozszerzonego wyboru 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 starszym widżetem autouzupełniania miejsca a nowym elementem autouzupełniania miejsca.

Widżet Autouzupełnianie miejsc (starsza wersja)

Usługa Miejsc 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 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 wejściowe, które będzie monitorowane przez usługę autouzupełniania, a wyniki będą do niego dołączane.
    • 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 miejsca 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 (nowość)

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 lub osadzić bezpośrednio na stronie internetowej. Poniższy przykład kodu pokazuje, jak umieścić widżet PlaceAutocompleteElement jako element sterujący mapą.

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

  • Interfejs widżetu Autocomplete obsługuje lokalizację regionalną (w tym języki zapisywane od prawej do lewej) w przypadku obiektu zastępczego do wpisywania tekstu, logo listy podpowiedzi i podpowiedzi dotyczących miejsc.
  • Ulepszone ułatwienia dostępu, w tym obsługa czytników ekranu i interakcja za pomocą klawiatury.
  • Widżet Autocomplete 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 lepszy wygląd graficzny.

Najważniejsze różnice w implementacji:

  • PlaceAutocompleteElement ma własne pole wprowadzania danych i jest wstawiany bezpośrednio na stronę za pomocą kodu HTML lub JavaScript (w przeciwieństwie do istniejącego elementu wejściowego).
  • Prognozy zapytań nie są dostępne w klasie Autocomplete.
  • PlaceAutocompleteElement jest tworzony przy użyciuPlaceAutocompleteElementOptions.
    • Pola danych o miejscu 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 ( 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,
  });
}