Interfejs API danych autouzupełniania miejsc umożliwia pobieranie prognozowanych lokalizacji programowo, co pozwala tworzyć spersonalizowane funkcje autouzupełniania z większym stopniem kontroli niż w przypadku widżetu autouzupełniania. Z tego przewodnika dowiesz się, jak używać interfejsu Place Autocomplete Data API do wysyłania żądań autouzupełniania na podstawie zapytań użytkownika.
Ten przykład pokazuje uproszczoną integrację z wyprzedzeniem. Wpisz zapytanie, a następnie kliknij, aby wybrać odpowiedni wynik.
Prośby o autouzupełnianie
Żądanie autouzupełniania przyjmuje ciąg znaków zapytania i zwraca listę prognozowanych miejsc. Aby przesłać żądanie autouzupełniania, wywołaj funkcję fetchAutocompleteSuggestions()
i przekaż żądanie z wymaganymi właściwościami. Właściwość input
zawiera ciąg znaków do wyszukania. W typowej aplikacji ta wartość jest aktualizowana, gdy użytkownik wpisze zapytanie. Prośba powinna zawierać sessionToken
, które służy do rozliczeń.
Ten fragment kodu pokazuje tworzenie treści żądania i dodawanie tokena sesji, a następnie wywołanie funkcji fetchAutocompleteSuggestions()
, aby uzyskać listę 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;
Ograniczanie podpowiedzi autouzupełniania
Domyślnie autouzupełnianie miejsc wyświetla wszystkie typy miejsc, preferując przewidywania w pobliżu lokalizacji użytkownika, i pobiera wszystkie dostępne pola danych dla wybranego miejsca. Ustaw opcje Autouzupełniania w sekcji Miejsce, aby wyświetlać trafniejsze przewidywania, ograniczając lub faworyzując wyniki.
Ograniczenie wyników powoduje, że widżet Autouzupełnianie ignoruje wyniki, które znajdują się poza obszarem ograniczeń. Typową praktyką jest ograniczanie wyników do granic mapy. Wyniki z uwzględnieniem preferencji sprawiają, że widżet autouzupełniania wyświetla wyniki w określonym obszarze, ale niektóre dopasowania mogą znajdować się poza tym obszarem.
Użyj właściwości origin
, aby określić punkt początkowy, z którego ma być obliczana odległość geodezyjna do miejsca docelowego. Jeśli ta wartość zostanie pominięta, odległość nie zostanie zwrócona.
Użyj właściwości includedPrimaryTypes
, aby określić maksymalnie 5 typów miejsc.
Jeśli nie podasz żadnych typów, zwrócone zostaną miejsca wszystkich typów.
Pobieranie informacji o miejscu
Aby zwrócić obiekt Place
z wyników przewidywania miejsc, najpierw wywołaj toPlace()
, a potem wywołaj fetchFields()
na otrzymanym obiekcie Place
(identyfikator sesji z przewidywania miejsca jest automatycznie uwzględniony). Wywołanie funkcji fetchFields()
kończy sesję autouzupełniania.
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;
Tokeny sesji
Na potrzeby rozliczeń tokeny sesji łączą fazy zapytania i wyboru w ramach wyszukiwania autouzupełniania przez użytkownika w jedną sesję. Sesja rozpoczyna się, gdy użytkownik zacznie pisać. Sesja kończy się, gdy użytkownik wybierze miejsce i wywoła funkcję szczegółów miejsca.
Aby utworzyć nowy token sesji i dodać go do żądania, utwórz instancję klasy AutocompleteSessionToken
, a następnie ustaw właściwość żądania sessionToken
, aby używać tokenów zgodnie z tym fragmentem kodu:
// Create a session token. const token = new AutocompleteSessionToken(); // Add the token to the request. // @ts-ignore request.sessionToken = token;
Sesja kończy się, gdy wywołana zostanie metoda fetchFields()
. Po utworzeniu instancji Place
nie musisz przekazywać tokena sesji do fetchFields()
, ponieważ jest on przekazywany automatycznie.
await place.fetchFields({ fields: ["displayName", "formattedAddress"], });
Utwórz token sesji na następną sesję, tworząc nową instancję funkcji AutocompleteSessionToken
.
Rekomendacje dotyczące tokena sesji:
- Używaj tokenów sesji we wszystkich wywołaniach autouzupełniania w Google Places.
- generować nowy token dla każdej sesji;
- Przekazywanie unikalnego tokena sesji w przypadku każdej nowej sesji. Użycie tego samego tokena w więcej niż 1 sesji spowoduje, że za każde żądanie zostanie naliczona osobna opłata.
Opcjonalnie możesz pominąć token sesji autouzupełniania w żądaniu. Jeśli pominiesz token sesji, każde żądanie zostanie rozliczone osobno, co spowoduje użycie SKU Autocomplete – per request. Jeśli używasz ponownie tokena sesji, sesja jest uznawana za nieprawidłową, a za żądania są naliczane tak, jakby token sesji nie został podany.
Przykład
Gdy użytkownik wpisze zapytanie, po każdym naciśnięciu klawisza (a nie po każdym znaku) zostanie wywołane żądanie autouzupełniania i zwrócona lista możliwych wyników. Gdy użytkownik wybierze coś z listy wyników, wybór jest traktowany jako żądanie, a wszystkie żądania wysłane podczas wyszukiwania są grupowane i liczone jako jedno żądanie. Jeśli użytkownik wybierze miejsce, zapytanie jest dostępne bezpłatnie, a opłata jest pobierana tylko za żądanie danych o miejscu. Jeśli użytkownik nie dokona wyboru w ciągu kilku minut od rozpoczęcia sesji, zostanie naliczona opłata tylko za zapytanie.
Z perspektywy aplikacji przebieg zdarzeń wygląda tak:
- Użytkownik zaczyna wpisywać zapytanie, aby wyszukać „Paryż, Francja”.
- Po wykryciu danych wejściowych użytkownika aplikacja tworzy nowy token sesji „Token A”.
- Gdy użytkownik wpisze kilka znaków, interfejs API wysyła zapytanie o autouzupełnianie po każdym znaku, wyświetlając nową listę potencjalnych wyników:
"P"
"Par"
"Paris,"
"Paris, Fr"
- Gdy użytkownik dokona wyboru:
- Wszystkie żądania wynikające z zapytania są grupowane i dodawane do sesji reprezentowanej przez „Token A” jako jedno żądanie.
- Wybór użytkownika jest liczony jako żądanie szczegółów miejsca i dodawany do sesji reprezentowanej przez „Token A”.
- Sesja została zakończona, a aplikacja odrzuciła „Token A”.
Pełny przykładowy kod
Ta sekcja zawiera pełne przykłady pokazujące, jak korzystać z interfejsu Autouzupełnianie danych miejsc API .Podpowiedzi autouzupełniania miejsc
W tym przykładzie wywołujemy funkcję fetchAutocompleteSuggestions()
z danymi wejściowymi „Tadi”, a potem wywołujemy funkcję toPlace()
z pierwszym wynikiem przewidywania, a następnie wywołujemy funkcję fetchFields()
, aby uzyskać szczegóły miejsca.
TypeScript
/** * 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>
Wypróbuj
Autouzupełnianie miejsc z wyszukiwaniem wyprzedzającym w sesjach
To przykład wywołania funkcji fetchAutocompleteSuggestions()
na podstawie zapytań użytkownika, pokazujący listę przewidywanych miejsc w odpowiedzi i ostatecznie pobierający szczegóły wybranego miejsca. Przykład pokazuje też użycie tokenów sesji do grupowania zapytań użytkownika z ostatecznym żądaniem szczegółów miejsca.
TypeScript
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; export {};
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>