Place Autocomplete Data API ช่วยให้คุณดึงข้อมูลการคาดคะเนสถานที่แบบเป็นโปรแกรมเพื่อสร้างประสบการณ์การเติมข้อความอัตโนมัติที่ปรับแต่งได้โดยมีการควบคุมที่ละเอียดกว่าวิดเจ็ตการเติมข้อความอัตโนมัติ ในคู่มือนี้ คุณจะได้เรียนรู้วิธีใช้ Place Autocomplete Data 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
เพื่อระบุประเภทสถานที่ได้สูงสุด 5 ประเภท
หากไม่ระบุประเภท ระบบจะแสดงสถานที่ทุกประเภท
ดูรายละเอียดสถานที่
หากต้องการแสดงผลออบเจ็กต์ 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;
โทเค็นเซสชัน
โทเค็นเซสชันจะจัดกลุ่มระยะการค้นหาและการเลือกของผู้ใช้ในการค้นหาที่เติมข้อความอัตโนมัติไว้ในเซสชันที่แยกต่างหากเพื่อวัตถุประสงค์ในการเรียกเก็บเงิน เซสชันจะเริ่มขึ้นเมื่อผู้ใช้เริ่มพิมพ์ เซสชันจะสิ้นสุดลงเมื่อผู้ใช้เลือกสถานที่และมีการเรียกใช้รายละเอียดสถานที่
หากต้องการสร้างโทเค็นเซสชันใหม่และเพิ่มลงในคําขอ ให้สร้างอินสแตนซ์ของ 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
คําแนะนําเกี่ยวกับโทเค็นเซสชัน
- ใช้โทเค็นเซสชันสำหรับการเรียกใช้ฟีเจอร์ป้อนข้อความอัตโนมัติของสถานที่ทั้งหมด
- สร้างโทเค็นใหม่สำหรับเซสชันแต่ละรายการ
- ส่งโทเค็นเซสชันที่ไม่ซ้ำกันสำหรับเซสชันใหม่แต่ละรายการ การใช้โทเค็นเดียวกันในเซสชันมากกว่า 1 เซสชันจะส่งผลให้มีการเรียกเก็บเงินสำหรับคำขอแต่ละรายการแยกกัน
คุณเลือกที่จะไม่ใส่โทเค็นเซสชันการเติมข้อความอัตโนมัติในคำขอได้ หากไม่ระบุโทเค็นเซสชัน ระบบจะเรียกเก็บเงินสำหรับคำขอแต่ละรายการแยกกัน ซึ่งจะทริกเกอร์ SKU Autocomplete - Per Request หากคุณใช้โทเค็นเซสชันซ้ำ ระบบจะถือว่าเซสชันไม่ถูกต้องและจะเรียกเก็บเงินสำหรับคำขอราวกับว่าไม่มีการระบุโทเค็นเซสชัน
ตัวอย่าง
ขณะที่ผู้ใช้พิมพ์ข้อความ ระบบจะเรียกใช้คําขอเติมข้อความอัตโนมัติทุกๆ 2-3 การกดแป้นพิมพ์ (ไม่ใช่ต่ออักขระ) และแสดงรายการผลลัพธ์ที่เป็นไปได้ เมื่อผู้ใช้เลือกจากรายการผลลัพธ์ การเลือกดังกล่าวจะนับเป็นคําขอ และระบบจะรวมคําขอทั้งหมดที่ส่งระหว่างการค้นหาไว้ด้วยกันและนับเป็นคําขอเดียว หากผู้ใช้เลือกสถานที่ คำค้นหาจะใช้งานได้โดยไม่มีค่าใช้จ่าย และระบบจะเรียกเก็บเงินเฉพาะคำขอข้อมูลสถานที่เท่านั้น หากผู้ใช้ไม่เลือกภายในไม่กี่นาทีหลังจากเริ่มเซสชัน ระบบจะเรียกเก็บเงินเฉพาะคำค้นหา
ลำดับเหตุการณ์จากมุมมองของแอปมีดังนี้
- ผู้ใช้เริ่มพิมพ์ข้อความค้นหาเพื่อค้นหา "ปารีส ฝรั่งเศส"
- เมื่อตรวจพบอินพุตของผู้ใช้ แอปจะสร้างโทเค็นเซสชันใหม่ "โทเค็น ก"
- ขณะที่ผู้ใช้พิมพ์ API จะส่งคําขอเติมข้อความอัตโนมัติทุกๆ 2-3 อักขระ โดยแสดงรายการผลลัพธ์ที่เป็นไปได้ใหม่สำหรับแต่ละรายการ
"P"
"Par"
"Paris,"
"Paris, Fr"
- เมื่อผู้ใช้เลือกตัวเลือก ระบบจะดำเนินการดังนี้
- ระบบจะจัดกลุ่มคำขอทั้งหมดที่เกิดจากการค้นหาและเพิ่มลงในเซสชันที่แสดงโดย "โทเค็น ก" เป็นคำขอเดียว
- ระบบจะนับการเลือกของผู้ใช้เป็นคำขอรายละเอียดสถานที่และเพิ่มลงในเซสชันที่แสดงโดย "โทเค็น ก"
- เซสชันสิ้นสุดลง และแอปจะทิ้ง "โทเค็น ก"
โค้ดตัวอย่างที่สมบูรณ์
ส่วนนี้มีตัวอย่างที่สมบูรณ์ซึ่งแสดงวิธีใช้ Place Autocomplete Data APIการคาดคะเนการเติมข้อความอัตโนมัติของสถานที่
ตัวอย่างต่อไปนี้แสดงการเรียกใช้ fetchAutocompleteSuggestions()
สำหรับอินพุต "Tadi" จากนั้นเรียกใช้ toPlace()
ในผลการคาดคะเนรายการแรก ตามด้วยการเรียกใช้ fetchFields()
เพื่อรับรายละเอียดสถานที่
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>
ลองใช้ตัวอย่าง
วางการพิมพ์ข้อความอัตโนมัติล่วงหน้าด้วยเซสชัน
ตัวอย่างนี้แสดงการเรียกใช้ fetchAutocompleteSuggestions()
ตามการค้นหาของผู้ใช้ การแสดงรายการสถานที่ที่คาดการณ์ไว้เพื่อตอบสนอง และสุดท้ายคือการดึงข้อมูลรายละเอียดสถานที่สำหรับสถานที่ที่เลือก ตัวอย่างนี้ยังแสดงการใช้โทเค็นเซสชันเพื่อจัดกลุ่มการค้นหาของผู้ใช้กับคําขอรายละเอียดสถานที่สุดท้ายด้วย
TypeScript
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>