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;
Ограничить прогнозы автозаполнения
По умолчанию Place Autocomplete представляет все типы мест, смещенные для прогнозов вблизи местоположения пользователя, и извлекает все доступные поля данных для выбранного пользователем места. Установите параметры Place Autocomplete, чтобы представить более релевантные прогнозы, ограничивая или смещая результаты.
Ограничение результатов заставляет виджет автозаполнения игнорировать любые результаты, которые находятся за пределами области ограничения. Распространенной практикой является ограничение результатов границами карты. Смещение результатов заставляет виджет автозаполнения показывать результаты в пределах указанной области, но некоторые совпадения могут быть за пределами этой области.
Используйте свойство origin
для указания исходной точки, от которой вычисляется геодезическое расстояние до пункта назначения. Если это значение пропущено, расстояние не возвращается.
Используйте свойство includedPrimaryTypes
для указания до пяти типов мест . Если типы не указаны, будут возвращены места всех типов.
Получить информацию о месте
Чтобы вернуть объект 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"], });
Создайте токен сеанса для следующего сеанса, создав новый экземпляр AutocompleteSessionToken
.
Рекомендации по токену сеанса:
- Используйте токены сеанса для всех вызовов Place Autocomplete.
- Генерируйте новый токен для каждого сеанса.
- Передача уникального токена сеанса для каждого нового сеанса. Использование одного и того же токена для более чем одного сеанса приведет к тому, что каждый запрос будет выставлен по отдельности.
При желании вы можете опустить токен сеанса автозаполнения из запроса. Если токен сеанса опущен, каждый запрос оплачивается отдельно, активируя SKU Autocomplete - Per Request . Если вы повторно используете токен сеанса, сеанс считается недействительным, и запросы оплачиваются так, как если бы токен сеанса не был предоставлен.
Пример
Когда пользователь вводит запрос, запрос автозаполнения вызывается каждые несколько нажатий клавиш (не посимвольно), и возвращается список возможных результатов. Когда пользователь делает выбор из списка результатов, выбор считается запросом, и все запросы, сделанные во время поиска, объединяются и учитываются как один запрос. Если пользователь выбирает место, поисковый запрос доступен бесплатно, и взимается только за запрос данных о месте. Если пользователь не делает выбор в течение нескольких минут с начала сеанса, взимается только за поисковый запрос.
С точки зрения приложения поток событий выглядит следующим образом:
- Пользователь начинает вводить запрос для поиска «Париж, Франция».
- При обнаружении пользовательского ввода приложение создает новый токен сеанса — «Токен А».
- По мере того, как пользователь печатает, API каждые несколько символов выполняет запрос автозаполнения, отображая новый список потенциальных результатов для каждого из них:
"П"
"Пар"
"Париж,"
"Париж, Фр" - Когда пользователь делает выбор:
- Все запросы, полученные в результате запроса, группируются и добавляются в сеанс, представленный «Токеном A», как один запрос.
- Выбор пользователя учитывается как запрос сведений о месте и добавляется к сеансу, представленному «Токеном A».
- Сеанс завершается, и приложение сбрасывает «Токен А».
Полный пример кода
В этом разделе содержатся полные примеры, показывающие, как использовать API Place Autocomplete Data.Место автозаполнения прогнозов
В следующем примере демонстрируется вызов fetchAutocompleteSuggestions()
для входных данных «Tadi», затем вызов 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 titleElement; let resultsContainerElement; let inputElement; let newestRequestId = 0; // Add an initial request body. const 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', }; function init() { titleElement = document.getElementById('title'); resultsContainerElement = document.getElementById('results'); inputElement = document.querySelector('input'); inputElement.addEventListener('input', makeAutocompleteRequest); refreshToken(request); } async function makeAutocompleteRequest(inputEvent) { // Reset elements and exit if an empty string is received. if (inputEvent.target.value == '') { titleElement.innerText = ''; resultsContainerElement.replaceChildren(); return; } // Add the latest char sequence to the request. request.input = inputEvent.target.value; // To avoid race conditions, store the request ID and compare after the request. const requestId = ++newestRequestId; // Fetch autocomplete suggestions and show them in a list. // @ts-ignore const { suggestions } = await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request); // If the request has been superseded by a newer request, do not render the output. if (requestId !== newestRequestId) return; titleElement.innerText = `Query predictions for "${request.input}"`; // Clear the list first. resultsContainerElement.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 item element. const li = document.createElement('li'); li.appendChild(a); resultsContainerElement.appendChild(li); } } // Event handler for clicking on a suggested place. async function onPlaceSelected(place) { await place.fetchFields({ fields: ['displayName', 'formattedAddress'], }); const placeText = document.createTextNode(`${place.displayName}: ${place.formattedAddress}`); resultsContainerElement.replaceChildren(placeText); titleElement.innerText = 'Selected Place:'; inputElement.value = ''; refreshToken(request); } // Helper function to refresh the session token. function refreshToken(request) { // Create a new session token and add it to the request. request.sessionToken = new google.maps.places.AutocompleteSessionToken(); } declare global { interface Window { init: () => void; } } window.init = init;
JavaScript
let titleElement; let resultsContainerElement; let inputElement; let newestRequestId = 0; // Add an initial request body. const 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', }; function init() { titleElement = document.getElementById('title'); resultsContainerElement = document.getElementById('results'); inputElement = document.querySelector('input'); inputElement.addEventListener('input', makeAutocompleteRequest); refreshToken(request); } async function makeAutocompleteRequest(inputEvent) { // Reset elements and exit if an empty string is received. if (inputEvent.target.value == '') { titleElement.innerText = ''; resultsContainerElement.replaceChildren(); return; } // Add the latest char sequence to the request. request.input = inputEvent.target.value; // To avoid race conditions, store the request ID and compare after the request. const requestId = ++newestRequestId; // Fetch autocomplete suggestions and show them in a list. // @ts-ignore const { suggestions } = await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request); // If the request has been superseded by a newer request, do not render the output. if (requestId !== newestRequestId) return; titleElement.innerText = `Query predictions for "${request.input}"`; // Clear the list first. resultsContainerElement.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 item element. const li = document.createElement('li'); li.appendChild(a); resultsContainerElement.appendChild(li); } } // Event handler for clicking on a suggested place. async function onPlaceSelected(place) { await place.fetchFields({ fields: ['displayName', 'formattedAddress'], }); const placeText = document.createTextNode(`${place.displayName}: ${place.formattedAddress}`); resultsContainerElement.replaceChildren(placeText); titleElement.innerText = 'Selected Place:'; inputElement.value = ''; refreshToken(request); } // Helper function to refresh the session token. function refreshToken(request) { // Create a new session token and add it to the request. request.sessionToken = new google.maps.places.AutocompleteSessionToken(); } 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=AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8&callback=init&libraries=places&v=weekly" defer ></script> </body> </html>