Разместить API данных автозаполнения

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

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

Автозаполнение запросов

Запрос автозаполнения принимает входную строку запроса и возвращает список подсказок мест. Чтобы сделать запрос автозаполнения, вызовите fetchAutocompleteSuggestions() и передайте запрос с необходимыми свойствами. Свойство input содержит строку для поиска; в типичном приложении это значение будет обновляться по мере того, как пользователь вводит запрос. Запрос должен включать sessionToken , который используется для целей выставления счетов.

В следующем фрагменте показано создание тела запроса и добавление токена сеанса, а затем вызов fetchAutocompleteSuggestions() для получения списка PlacePrediction .

// Add an initial request body.
let request = {
  input: "Tadi",
  locationRestriction: {
    west: -122.44,
    north: 37.8,
    east: -122.39,
    south: 37.78,
  },
  origin: { lat: 37.7893, lng: -122.4039 },
  includedPrimaryTypes: ["restaurant"],
  language: "en-US",
  region: "us",
};
// Create a session token.
const token = new AutocompleteSessionToken();

// Add the token to the request.
// @ts-ignore
request.sessionToken = token;

Ограничить прогнозы автозаполнения

По умолчанию функция автозаполнения мест представляет все типы мест с учетом подсказок вблизи местоположения пользователя и извлекает все доступные поля данных для выбранного пользователем места. Установите параметры автозаполнения мест, чтобы предоставлять более релевантные прогнозы, ограничивая или искажая результаты.

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

Используйте свойство origin , чтобы указать исходную точку, от которой нужно вычислить геодезическое расстояние до пункта назначения. Если это значение опущено, расстояние не возвращается.

Используйте свойство includedPrimaryTypes чтобы указать до пяти типов мест . Если типы не указаны, будут возвращены места всех типов.

См. справочник по API

Получить информацию о месте

Чтобы вернуть объект Place из результата прогнозирования места, сначала вызовите toPlace() , затем вызовите fetchFields() для полученного объекта Place (идентификатор сеанса из прогноза места включается автоматически). Вызов fetchFields() завершает сеанс автозаполнения.

let place = suggestions[0].placePrediction.toPlace(); // Get first predicted place.

await place.fetchFields({
  fields: ["displayName", "formattedAddress"],
});

const placeInfo = document.getElementById("prediction");

placeInfo.textContent =
  "First predicted place: " +
  place.displayName +
  ": " +
  place.formattedAddress;

Токены сеанса

Токены сеанса группируют этапы запроса и выбора пользовательского поиска с автозаполнением в отдельный сеанс для целей выставления счетов. Сеанс начинается, когда пользователь начинает печатать. Сеанс завершается, когда пользователь выбирает место и выполняет вызов Place Details.

Чтобы создать новый токен сеанса и добавить его в запрос, создайте экземпляр AutocompleteSessionToken , затем установите для свойства sessionToken запроса использование токенов, как показано в следующем фрагменте кода:

// Create a session token.
const token = new AutocompleteSessionToken();

// Add the token to the request.
// @ts-ignore
request.sessionToken = token;

Сеанс завершается при вызове fetchFields() . После создания экземпляра Place вам не нужно передавать токен сеанса в функцию fetchFields() поскольку это обрабатывается автоматически.

await place.fetchFields({
  fields: ["displayName", "formattedAddress"],
});
await place.fetchFields({
    fields: ['displayName'],
  });

Создайте токен сеанса для следующего сеанса, создав новый экземпляр AutocompleteSessionToken .

Рекомендации по токенам сеанса:

  • Используйте токены сеанса для всех вызовов Place Autocomplete.
  • Генерируйте новый токен для каждого сеанса.
  • Передайте уникальный токен сеанса для каждого нового сеанса. Использование одного и того же токена для нескольких сеансов приведет к тому, что каждый запрос будет оплачиваться индивидуально.

При желании вы можете исключить токен сеанса автозаполнения из запроса. Если токен сеанса опущен, каждый запрос оплачивается отдельно, что активирует SKU «Автозаполнение — по запросу» . Если вы повторно используете токен сеанса, сеанс считается недействительным, а за запросы взимается плата, как если бы токен сеанса не был предоставлен.

Пример

Когда пользователь вводит запрос, запрос автозаполнения вызывается каждые несколько нажатий клавиш (не для каждого символа), и возвращается список возможных результатов. Когда пользователь делает выбор из списка результатов, этот выбор считается запросом, а все запросы, сделанные во время поиска, объединяются и учитываются как один запрос. Если пользователь выбирает место, поисковый запрос доступен бесплатно, и взимается только плата за запрос данных о месте. Если пользователь не делает выбор в течение нескольких минут после начала сеанса, тарифицируется только поисковый запрос.

С точки зрения приложения поток событий выглядит следующим образом:

  1. Пользователь начинает вводить запрос для поиска «Париж, Франция».
  2. Обнаружив ввод пользователя, приложение создает новый токен сеанса «Токен A».
  3. По мере ввода пользователем API выполняет запрос автозаполнения каждые несколько символов, отображая новый список потенциальных результатов для каждого:
    "П"
    "Пар"
    "Париж,"
    «Париж, фр.»
  4. Когда пользователь делает выбор:
    • Все запросы, возникающие в результате запроса, группируются и добавляются в сеанс, представленный «Токеном A», как один запрос.
    • Выбор пользователя считается запросом сведений о месте и добавляется к сеансу, представленному «токеном A».
  5. Сеанс завершается, и приложение удаляет «токен А».
Узнайте, как оплачиваются сеансы

Полный пример кода

В этом разделе содержатся полные примеры, показывающие, как использовать API данных автозаполнения места.

Размещайте подсказки автозаполнения

В следующем примере демонстрируется вызов fetchAutocompleteSuggestions() для входных данных «Тади», затем вызов toPlace() для первого результата прогнозирования, за которым следует вызов fetchFields() для получения сведений о месте.

Машинопись

/**
 * Demonstrates making a single request for Place predictions, then requests Place Details for the first result.
 */
async function init() {
    // @ts-ignore
    const { Place, AutocompleteSessionToken, AutocompleteSuggestion } = await google.maps.importLibrary("places") as google.maps.PlacesLibrary;

    // Add an initial request body.
    let request = {
        input: "Tadi",
        locationRestriction: { west: -122.44, north: 37.8, east: -122.39, south: 37.78 },
        origin: { lat: 37.7893, lng: -122.4039 },
        includedPrimaryTypes: ["restaurant"],
        language: "en-US",
        region: "us",
    };

    // Create a session token.
    const token = new AutocompleteSessionToken();
    // Add the token to the request.
    // @ts-ignore
    request.sessionToken = token;
    // Fetch autocomplete suggestions.
    const { suggestions } = await AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

    const title = document.getElementById('title') as HTMLElement;
    title.appendChild(document.createTextNode('Query predictions for "' + request.input + '":'));

    for (let suggestion of suggestions) {
        const placePrediction = suggestion.placePrediction;

        // Create a new list element.
        const listItem = document.createElement('li');
        const resultsElement = document.getElementById("results") as HTMLElement;
        listItem.appendChild(document.createTextNode(placePrediction.text.toString()));
        resultsElement.appendChild(listItem);
    }

    let place = suggestions[0].placePrediction.toPlace(); // Get first predicted place.
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress'],
    });

    const placeInfo = document.getElementById("prediction") as HTMLElement;
    placeInfo.textContent = 'First predicted place: ' + place.displayName + ': ' + place.formattedAddress;

}

init();

JavaScript

/**
 * Demonstrates making a single request for Place predictions, then requests Place Details for the first result.
 */
async function init() {
  // @ts-ignore
  const { Place, AutocompleteSessionToken, AutocompleteSuggestion } =
    await google.maps.importLibrary("places");
  // Add an initial request body.
  let request = {
    input: "Tadi",
    locationRestriction: {
      west: -122.44,
      north: 37.8,
      east: -122.39,
      south: 37.78,
    },
    origin: { lat: 37.7893, lng: -122.4039 },
    includedPrimaryTypes: ["restaurant"],
    language: "en-US",
    region: "us",
  };
  // Create a session token.
  const token = new AutocompleteSessionToken();

  // Add the token to the request.
  // @ts-ignore
  request.sessionToken = token;

  // Fetch autocomplete suggestions.
  const { suggestions } =
    await AutocompleteSuggestion.fetchAutocompleteSuggestions(request);
  const title = document.getElementById("title");

  title.appendChild(
    document.createTextNode('Query predictions for "' + request.input + '":'),
  );

  for (let suggestion of suggestions) {
    const placePrediction = suggestion.placePrediction;
    // Create a new list element.
    const listItem = document.createElement("li");
    const resultsElement = document.getElementById("results");

    listItem.appendChild(
      document.createTextNode(placePrediction.text.toString()),
    );
    resultsElement.appendChild(listItem);
  }

  let place = suggestions[0].placePrediction.toPlace(); // Get first predicted place.

  await place.fetchFields({
    fields: ["displayName", "formattedAddress"],
  });

  const placeInfo = document.getElementById("prediction");

  placeInfo.textContent =
    "First predicted place: " +
    place.displayName +
    ": " +
    place.formattedAddress;
}

init();

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

HTML

<html>
  <head>
    <title>Place Autocomplete Data API Predictions</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="title"></div>
    <ul id="results"></ul>
    <p><span id="prediction"></span></p>
    <img
      class="powered-by-google"
      src="https://storage.googleapis.com/geo-devrel-public-buckets/powered_by_google_on_white.png"
      alt="Powered by Google"
    />

    <!-- prettier-ignore -->
    <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "weekly"});</script>
  </body>
</html>

Попробуйте образец

Разместите автозаполнение текста впереди сеансов

В этом примере демонстрируется вызов fetchAutocompleteSuggestions() на основе запросов пользователя, показ списка предсказанных мест в ответ и, наконец, получение сведений о выбранном месте. В примере также показано использование токенов сеанса для группировки пользовательского запроса с окончательным запросом сведений о месте.

Машинопись

let title;
let results;
let input;
let token;

// Add an initial request body.
let request = {
    input: "",
    locationRestriction: { west: -122.44, north: 37.8, east: -122.39, south: 37.78 },
    origin: { lat: 37.7893, lng: -122.4039 },
    includedPrimaryTypes: ["restaurant"],
    language: "en-US",
    region: "us",
};

async function init() {
    token = new google.maps.places.AutocompleteSessionToken();

    title = document.getElementById('title');
    results = document.getElementById('results');
    input = document.querySelector("input");
    input.addEventListener("input", makeAcRequest);
    request = refreshToken(request) as any;
}

async function makeAcRequest(input) {
    // Reset elements and exit if an empty string is received.
    if (input.target.value == '') {
        title.innerText = '';
        results.replaceChildren();
        return;
    }

    // Add the latest char sequence to the request.
    request.input = input.target.value;

    // Fetch autocomplete suggestions and show them in a list.
    // @ts-ignore
    const { suggestions } = await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

    title.innerText = 'Query predictions for "' + request.input + '"';

    // Clear the list first.
    results.replaceChildren();

    for (const suggestion of suggestions) {
        const placePrediction = suggestion.placePrediction;

        // Create a link for the place, add an event handler to fetch the place.
        const a = document.createElement('a');
        a.addEventListener('click', () => {
            onPlaceSelected(placePrediction!.toPlace());
        });
        a.innerText = placePrediction!.text.toString();

        // Create a new list element.
        const li = document.createElement('li');
        li.appendChild(a);
        results.appendChild(li);
    }
}

// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress'],
    });
    let placeText = document.createTextNode(place.displayName + ': ' + place.formattedAddress);
    results.replaceChildren(placeText);
    title.innerText = 'Selected Place:';
    input.value = '';
    refreshToken(request);
}

// Helper function to refresh the session token.
async function refreshToken(request) {
    // Create a new session token and add it to the request.
    token = new google.maps.places.AutocompleteSessionToken();
    request.sessionToken = token;
    return request;
}

declare global {
    interface Window {
      init: () => void;
    }
  }
  window.init = init;

JavaScript

let title;
let results;
let input;
let token;
// Add an initial request body.
let request = {
  input: "",
  locationRestriction: {
    west: -122.44,
    north: 37.8,
    east: -122.39,
    south: 37.78,
  },
  origin: { lat: 37.7893, lng: -122.4039 },
  includedPrimaryTypes: ["restaurant"],
  language: "en-US",
  region: "us",
};

async function init() {
  token = new google.maps.places.AutocompleteSessionToken();
  title = document.getElementById("title");
  results = document.getElementById("results");
  input = document.querySelector("input");
  input.addEventListener("input", makeAcRequest);
  request = refreshToken(request);
}

async function makeAcRequest(input) {
  // Reset elements and exit if an empty string is received.
  if (input.target.value == "") {
    title.innerText = "";
    results.replaceChildren();
    return;
  }

  // Add the latest char sequence to the request.
  request.input = input.target.value;

  // Fetch autocomplete suggestions and show them in a list.
  // @ts-ignore
  const { suggestions } =
    await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(
      request,
    );

  title.innerText = 'Query predictions for "' + request.input + '"';
  // Clear the list first.
  results.replaceChildren();

  for (const suggestion of suggestions) {
    const placePrediction = suggestion.placePrediction;
    // Create a link for the place, add an event handler to fetch the place.
    const a = document.createElement("a");

    a.addEventListener("click", () => {
      onPlaceSelected(placePrediction.toPlace());
    });
    a.innerText = placePrediction.text.toString();

    // Create a new list element.
    const li = document.createElement("li");

    li.appendChild(a);
    results.appendChild(li);
  }
}

// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
  await place.fetchFields({
    fields: ["displayName", "formattedAddress"],
  });

  let placeText = document.createTextNode(
    place.displayName + ": " + place.formattedAddress,
  );

  results.replaceChildren(placeText);
  title.innerText = "Selected Place:";
  input.value = "";
  refreshToken(request);
}

// Helper function to refresh the session token.
async function refreshToken(request) {
  // Create a new session token and add it to the request.
  token = new google.maps.places.AutocompleteSessionToken();
  request.sessionToken = token;
  return request;
}

window.init = init;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

a {
  cursor: pointer;
  text-decoration: underline;
  color: blue;
}

input {
  width: 300px;
}

HTML

<html>
  <head>
    <title>Place Autocomplete Data API Session</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <input id="input" type="text" placeholder="Search for a place..." />
    <div id="title"></div>
    <ul id="results"></ul>
    <img
      class="powered-by-google"
      src="https://storage.googleapis.com/geo-devrel-public-buckets/powered_by_google_on_white.png"
      alt="Powered by Google"
    />

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=init&libraries=places&v=weekly"
      defer
    ></script>
  </body>
</html>

Попробуйте образец