Как перейти на новую версию автозаполнения мест

Разработчики из Европейской экономической зоны (ЕЭЗ)

Автозаполнение мест – это функция библиотеки Places в Maps JavaScript API. Вы можете использовать автозаполнение, чтобы добавить в приложение функцию поиска с предсказанием по мере ввода текста, как в строке поиска Google Карт.

На этой странице объясняются различия между устаревшими и новыми функциями автозаполнения мест. В обеих версиях есть два основных способа интеграции автозаполнения:

Программный интерфейс автозаполнения

В таблице ниже перечислены основные различия между автоматизированным использованием автозаполнения мест Places Autocomplete Service (устаревшая версия) и Autocomplete Data API (новая версия).

PlacesService (устаревший) Place (новое)
Справочная документация по сервису Places Autocomplete Autocomplete Data (new) reference
AutocompletionRequest AutocompleteRequest
AutocompleteService.getPlacePredictions AutocompleteSuggestion.fetchAutocompleteSuggestions
AutocompletePrediction PlacePrediction
Для обработки объекта результатов и ответа PlacesServiceStatus методы требуют использования обратного вызова. Использует объекты Promise и работает асинхронно.
Для методов требуется проверка PlacesServiceStatus. Проверка статуса не требуется, можно использовать стандартную обработку ошибок. Подробнее…
Поля данных о месте задаются в качестве параметров при создании экземпляра Autocomplete. Поля данных о месте задаются позже, при вызове fetchFields().
Поддерживаются подсказки запросов (только SearchBox). Подсказки запросов недоступны в классе Autocomplete.
Ограничено фиксированным набором типов мест и полей данных о местах. Доступ к расширенному набору типов мест и полей данных о местах.

Следующие поля используются как в устаревшем, так и в новом API автозаполнения:

Сравнение кода (алгоритмические продажи)

В этом разделе сравнивается код для автозаполнения, чтобы проиллюстрировать различия между сервисом Places и классом Place для программных интерфейсов.

Как получить подсказки автозаполнения (устаревший способ)

Устаревший сервис Places позволяет программно получать подсказки автозаполнения, что дает больше возможностей для управления пользовательским интерфейсом, чем класс Autocomplete. В примере ниже выполняется один запрос для "par" с параметром AutocompletionRequest, состоящим из входного значения и набора границ для смещения подсказки. В примере возвращается список экземпляров AutocompletePrediction и показывается описание каждого из них. Пример функции также создает токен сеанса и применяет его к запросу.

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

Получение подсказок автозаполнения (новое)

Новый класс Place также позволяет программно получать подсказки автозаполнения, что дает больше возможностей для управления пользовательским интерфейсом, чем класс PlaceAutocompleteElement. В примере ниже выполняется один запрос для "par" с AutocompleteRequest, состоящим из входного значения и набора границ для смещения подсказки. В примере возвращается список экземпляров placePrediction и показывается описание каждого из них. Пример функции также создает токен сеанса и применяет его к запросу.

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

Виджет автозаполнения мест

В таблице ниже приведены некоторые основные различия в использовании виджетов автозаполнения между сервисом Places (устаревшим) и классом Place (новым).

Сервис Places (устаревший) Место (новое)
Класс Autocomplete для подсказок мест. Класс PlaceAutocompleteElement для подсказок мест.
Класс SearchBox
для подсказок по запросам.
Подсказки запросов недоступны в классе Autocomplete.
Локализуется только текст-плейсхолдер по умолчанию. Плейсхолдер ввода текста, логотип списка подсказок и подсказки мест поддерживают региональную локализацию.
Виджет использует setBounds() или autocomplete.bindTo(), чтобы ограничить поиск указанными границами, и strictBounds, чтобы ограничить результаты указанными границами. Виджет использует свойство locationBias, чтобы отдавать предпочтение результатам в указанных границах, и свойство locationRestriction, чтобы ограничить поиск указанными границами.
Виджеты можно интегрировать только с помощью стандартного элемента ввода HTML. Виджет можно интегрировать с помощью стандартного элемента ввода HTML или элемента gmp-place-autocomplete.
При использовании виджета пользователи могут запрашивать недопустимые данные (например, "биснейленд"). Такие случаи должны обрабатываться явным образом. Виджет будет возвращать результаты только для предоставленных подсказок и не сможет отправлять запросы на произвольные значения, поэтому нет необходимости обрабатывать потенциально недопустимые запросы.
Возвращает устаревший экземпляр PlaceResult. Возвращает экземпляр Place.
Поля данных о месте задаются как параметры объекта Autocomplete. Поля данных о месте задаются, когда пользователь делает выбор и вызывается fetchFields().
Ограничено фиксированным набором типов мест и полей данных о местах. Доступ к расширенному набору типов мест и полей данных о местах.

Сравнение кода (виджеты)

В этом разделе сравнивается код для автозаполнения, чтобы проиллюстрировать различия между устаревшим виджетом автозаполнения мест и новым элементом автозаполнения мест.

Виджет автозаполнения мест (устаревший)

В сервисе Places имеется два типа виджетов автозаполнения, которые добавляются с помощью классов Autocomplete и SearchBox. Виджеты обоих типов можно добавлять на карту в качестве элементов управления или встраивать непосредственно в веб-страницу. В следующем примере кода показано, как встроить виджет Autocomplete в качестве элемента управления картой.

  • Конструктор виджета Autocomplete принимает два аргумента:
    • Элемент HTML input типа text. Это поле ввода, которое отслеживает сервис автозаполнения и к которому он прикрепляет результаты.
    • Необязательный аргумент AutocompleteOptions, в котором можно указать дополнительные параметры для ограничения запроса.
  • Чтобы задать границы, можно явно привязать экземпляр Autocomplete к карте, вызвав метод autocomplete.bindTo().
  • Укажите поля данных о местах в параметрах автозаполнения.
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);
  });
}

Виджет автозаполнения мест (новый)

Класс Place предлагает PlaceAutocompleteElement – подкласс HTMLElement, который предоставляет компонент пользовательского интерфейса, который можно добавить на карту в качестве элемента управления или встроить непосредственно на веб-страницу. В следующем примере кода показано, как встроить виджет PlaceAutocompleteElement в качестве элемента управления картой.

Виджет автозаполнения мест был улучшен следующим образом:

  • Интерфейс виджета Autocomplete поддерживает региональную локализацию (в том числе языки с написанием справа налево) плейсхолдера ввода текста, логотипа списка подсказок, а также отображаемых подсказок.
  • Расширенные специальные возможности, в том числе поддержка программ чтения с экрана и взаимодействие с помощью клавиатуры.
  • Виджет Autocomplete возвращает новый класс Place, который помогает упростить обработку возвращаемого объекта.
  • Улучшенная поддержка мобильных устройств и небольших экранов.
  • Повышенная производительность и усовершенствованный визуальный дизайн.

Основные различия в реализации:

  • PlaceAutocompleteElement предоставляет собственное поле ввода и вставляется непосредственно на страницу с помощью HTML или JavaScript (в отличие от существующего элемента ввода).
  • Подсказки запросов недоступны в классе Autocomplete.
  • Объект PlaceAutocompleteElement создается с помощью PlaceAutocompleteElementOptions.
    • Поля данных о месте указываются при выборе (когда вызывается fetchFields()).
  • Задайте границы с помощью параметра locationBounds или 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,
  });
}