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"], });
สร้างโทเค็นเซสชันสำหรับเซสชันถัดไปโดยสร้างอินสแตนซ์ใหม่ของ AutocompleteSessionToken
คำแนะนำเกี่ยวกับโทเค็นเซสชัน
- ใช้โทเค็นเซสชันสำหรับการเรียกใช้การเติมข้อความอัตโนมัติของสถานที่ทั้งหมด
- สร้างโทเค็นใหม่สำหรับแต่ละเซสชัน
- ส่งโทเค็นเซสชันที่ไม่ซ้ำกันสำหรับเซสชันใหม่แต่ละเซสชัน การใช้โทเค็นเดียวกันสำหรับเซสชันมากกว่า 1 รายการ จะส่งผลให้ระบบเรียกเก็บเงินสำหรับคำขอแต่ละรายการแยกกัน
คุณเลือกไม่ใส่โทเค็นเซสชันการเติมข้อความอัตโนมัติในคำขอได้ หากละเว้นโทเค็นเซสชัน ระบบจะเรียกเก็บเงินสำหรับคำขอแต่ละรายการแยกกัน ซึ่งจะทริกเกอร์ SKU Autocomplete - ต่อคำขอ หากคุณนำโทเค็นเซสชันมาใช้ซ้ำ ระบบจะถือว่าเซสชันไม่ถูกต้องและจะเรียกเก็บเงินจากคำขอ ราวกับว่าไม่มีการระบุโทเค็นเซสชัน
ตัวอย่าง
ขณะที่ผู้ใช้พิมพ์คำค้นหา ระบบจะเรียกคำขอเติมข้อความอัตโนมัติทุกๆ 2-3 ครั้งที่กดแป้น (ไม่ใช่ต่ออักขระ) และจะแสดงรายการผลลัพธ์ที่เป็นไปได้ เมื่อผู้ใช้เลือกจากรายการผลลัพธ์ ระบบจะนับการเลือกเป็นการร้องขอ และจะรวมคำขอทั้งหมดที่ดำเนินการระหว่างการค้นหาและนับเป็นคำขอเดียว หากผู้ใช้เลือกสถานที่ ระบบจะไม่มีค่าใช้จ่ายสำหรับคำค้นหา และจะเรียกเก็บเงินเฉพาะคำขอข้อมูลสถานที่ หากผู้ใช้ไม่ได้เลือกภายในไม่กี่นาทีหลังจากเริ่มเซสชัน ระบบจะเรียกเก็บเงินเฉพาะคำค้นหา
จากมุมมองของแอป ขั้นตอนของเหตุการณ์จะเป็นดังนี้
- ผู้ใช้เริ่มพิมพ์คำค้นหาเพื่อค้นหา "ปารีส ฝรั่งเศส"
- เมื่อตรวจพบอินพุตของผู้ใช้ แอปจะสร้างโทเค็นเซสชันใหม่ "โทเค็น A"
- ขณะที่ผู้ใช้พิมพ์ API จะส่งคำขอเติมข้อความอัตโนมัติทุกๆ 2-3 อักขระ โดยจะแสดงรายการผลลัพธ์ใหม่ที่อาจเป็นไปได้สำหรับแต่ละคำ
"P"
"Par"
"Paris"
"Paris, Fr"
- เมื่อผู้ใช้เลือกรายการใดรายการหนึ่ง
- ระบบจะจัดกลุ่มคำขอทั้งหมดที่เกิดจากการค้นหาและเพิ่มลงใน เซสชันที่แสดงโดย "โทเค็น A" เป็นคำขอเดียว
- ระบบจะนับการเลือกของผู้ใช้เป็นคำขอรายละเอียดสถานที่ และเพิ่ม ลงในเซสชันที่แสดงโดย "โทเค็น A"
- เซสชันสิ้นสุดลง และแอปจะทิ้ง "โทเค็น A"
โค้ดตัวอย่างที่สมบูรณ์
ส่วนนี้มีตัวอย่างที่สมบูรณ์ซึ่งแสดงวิธีใช้ 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()
ตามคำค้นหาของผู้ใช้และการแสดงรายการสถานที่ที่คาดการณ์ไว้เป็นคำตอบ - การใช้โทเค็นเซสชันเพื่อจัดกลุ่มคำค้นหาของผู้ใช้กับคำขอรายละเอียดสถานที่ขั้นสุดท้าย
- ดึงรายละเอียดสถานที่สำหรับสถานที่ที่เลือกและแสดงเครื่องหมาย
- การใช้การจัดช่องควบคุมเพื่อซ้อนองค์ประกอบ UI ในองค์ประกอบ
gmp-map
TypeScript
const mapElement = document.querySelector('gmp-map') as google.maps.MapElement; let innerMap: google.maps.Map; let marker: google.maps.marker.AdvancedMarkerElement; let titleElement = document.querySelector('.title') as HTMLElement; let resultsContainerElement = document.querySelector('.results') as HTMLElement; let inputElement = document.querySelector('input') as HTMLInputElement; let tokenStatusElement = document.querySelector('.token-status') as HTMLElement; let newestRequestId = 0; let tokenCount = 0; // Create an initial request body. const request: google.maps.places.AutocompleteRequest = { input: '', includedPrimaryTypes: [ 'restaurant', 'cafe', 'museum', 'park', 'botanical_garden', ], } async function init() { await google.maps.importLibrary('maps'); innerMap = mapElement.innerMap; innerMap.setOptions({ mapTypeControl: false, }); // Update request center and bounds when the map bounds change. google.maps.event.addListener(innerMap, 'bounds_changed', async () => { request.locationRestriction = innerMap.getBounds(); request.origin = innerMap.getCenter(); }); inputElement.addEventListener('input', makeAutocompleteRequest); } async function makeAutocompleteRequest(inputEvent) { // To avoid race conditions, store the request ID and compare after the request. const requestId = ++newestRequestId; const { AutocompleteSuggestion } = (await google.maps.importLibrary( 'places' )) as google.maps.PlacesLibrary; if (!inputEvent.target?.value) { titleElement.textContent = ''; resultsContainerElement.replaceChildren(); return; } // Add the latest char sequence to the request. request.input = (inputEvent.target as HTMLInputElement).value; // Fetch autocomplete suggestions and show them in a list. const { suggestions } = await AutocompleteSuggestion.fetchAutocompleteSuggestions(request); // If the request has been superseded by a newer request, do not render the output. if (requestId !== newestRequestId) return; titleElement.innerText = `Place predictions for "${request.input}"`; // Clear the list first. resultsContainerElement.replaceChildren(); for (const suggestion of suggestions) { const placePrediction = suggestion.placePrediction; if (!placePrediction) { continue; } // Create a link for the place, add an event handler to fetch the place. // We are using a button element to take advantage of its a11y capabilities. const placeButton = document.createElement('button'); placeButton.addEventListener('click', () => { onPlaceSelected(placePrediction.toPlace()); }); placeButton.textContent = placePrediction.text.toString(); placeButton.classList.add('place-button'); // Create a new list item element. const li = document.createElement('li'); li.appendChild(placeButton); resultsContainerElement.appendChild(li); } } // Event handler for clicking on a suggested place. async function onPlaceSelected(place: google.maps.places.Place) { const { AdvancedMarkerElement } = (await google.maps.importLibrary( 'marker' )) as google.maps.MarkerLibrary; await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'], }); resultsContainerElement.textContent = `${place.displayName}: ${place.formattedAddress}`; titleElement.textContent = 'Selected Place:'; inputElement.value = ''; await refreshToken(); // Remove the previous marker, if it exists. if (marker) { marker.remove(); } // Create a new marker. marker = new AdvancedMarkerElement({ map: innerMap, position: place.location, title: place.displayName, }) // Center the map on the selected place. if (place.location) { innerMap.setCenter(place.location); innerMap.setZoom(15); } } // Helper function to refresh the session token. async function refreshToken() { const { AutocompleteSessionToken } = (await google.maps.importLibrary( 'places' )) as google.maps.PlacesLibrary; // Increment the token counter. tokenCount++; // Create a new session token and add it to the request. request.sessionToken = new AutocompleteSessionToken(); tokenStatusElement.textContent = `Session token count: ${tokenCount}`; } init();
JavaScript
const mapElement = document.querySelector('gmp-map'); let innerMap; let marker; let titleElement = document.querySelector('.title'); let resultsContainerElement = document.querySelector('.results'); let inputElement = document.querySelector('input'); let tokenStatusElement = document.querySelector('.token-status'); let newestRequestId = 0; let tokenCount = 0; // Create an initial request body. const request = { input: '', includedPrimaryTypes: [ 'restaurant', 'cafe', 'museum', 'park', 'botanical_garden', ], }; async function init() { await google.maps.importLibrary('maps'); innerMap = mapElement.innerMap; innerMap.setOptions({ mapTypeControl: false, }); // Update request center and bounds when the map bounds change. google.maps.event.addListener(innerMap, 'bounds_changed', async () => { request.locationRestriction = innerMap.getBounds(); request.origin = innerMap.getCenter(); }); inputElement.addEventListener('input', makeAutocompleteRequest); } async function makeAutocompleteRequest(inputEvent) { // To avoid race conditions, store the request ID and compare after the request. const requestId = ++newestRequestId; const { AutocompleteSuggestion } = (await google.maps.importLibrary('places')); if (!inputEvent.target?.value) { titleElement.textContent = ''; resultsContainerElement.replaceChildren(); return; } // Add the latest char sequence to the request. request.input = inputEvent.target.value; // Fetch autocomplete suggestions and show them in a list. const { suggestions } = await AutocompleteSuggestion.fetchAutocompleteSuggestions(request); // If the request has been superseded by a newer request, do not render the output. if (requestId !== newestRequestId) return; titleElement.innerText = `Place predictions for "${request.input}"`; // Clear the list first. resultsContainerElement.replaceChildren(); for (const suggestion of suggestions) { const placePrediction = suggestion.placePrediction; if (!placePrediction) { continue; } // Create a link for the place, add an event handler to fetch the place. // We are using a button element to take advantage of its a11y capabilities. const placeButton = document.createElement('button'); placeButton.addEventListener('click', () => { onPlaceSelected(placePrediction.toPlace()); }); placeButton.textContent = placePrediction.text.toString(); placeButton.classList.add('place-button'); // Create a new list item element. const li = document.createElement('li'); li.appendChild(placeButton); resultsContainerElement.appendChild(li); } } // Event handler for clicking on a suggested place. async function onPlaceSelected(place) { const { AdvancedMarkerElement } = (await google.maps.importLibrary('marker')); await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'], }); resultsContainerElement.textContent = `${place.displayName}: ${place.formattedAddress}`; titleElement.textContent = 'Selected Place:'; inputElement.value = ''; await refreshToken(); // Remove the previous marker, if it exists. if (marker) { marker.remove(); } // Create a new marker. marker = new AdvancedMarkerElement({ map: innerMap, position: place.location, title: place.displayName, }); // Center the map on the selected place. if (place.location) { innerMap.setCenter(place.location); innerMap.setZoom(15); } } // Helper function to refresh the session token. async function refreshToken() { const { AutocompleteSessionToken } = (await google.maps.importLibrary('places')); // Increment the token counter. tokenCount++; // Create a new session token and add it to the request. request.sessionToken = new AutocompleteSessionToken(); tokenStatusElement.textContent = `Session token count: ${tokenCount}`; } 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; } .place-button { height: 3rem; width: 100%; background-color: transparent; text-align: left; border: none; cursor: pointer; } .place-button:focus-visible { outline: 2px solid #0056b3; border-radius: 2px; } .input { width: 300px; font-size: small; margin-bottom: 1rem; } /* Styles for the floating panel */ .controls { background-color: #fff; border-radius: 8px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); font-family: sans-serif; font-size: small; margin: 12px; padding: 1rem; } .title { font-weight: bold; margin-top: 1rem; margin-bottom: 0.5rem; } .results { list-style-type: none; margin: 0; padding: 0; } .results li:not(:last-child) { border-bottom: 1px solid #ddd; } .results li:hover { background-color: #eee; }
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> <!-- 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: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</script> </head> <body> <gmp-map center="37.7893, -122.4039" zoom="12" map-id="DEMO_MAP_ID"> <div class="controls" slot="control-inline-start-block-start" > <input type="text" class="input" placeholder="Search for a place..." autocomplete="off" /><!-- Turn off the input's own autocomplete (not supported by all browsers).--> <div class="token-status"></div> <div class="title"></div> <ol class="results"></ol> </div> </gmp-map> </body> </html>