Place Autocomplete Data API

นักพัฒนาซอฟต์แวร์ในเขตเศรษฐกิจยุโรป (EEA)

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 ประเภท หากไม่ได้ระบุประเภท ระบบจะแสดงสถานที่ทุกประเภท

ดูเอกสารอ้างอิง 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}`;

โทเค็นของเซสชัน

โทเค็นเซสชันจะจัดกลุ่มระยะการค้นหาและการเลือกของการค้นหาแบบเติมข้อความอัตโนมัติของผู้ใช้เป็นเซสชันที่ไม่ต่อเนื่องเพื่อวัตถุประสงค์ในการเรียกเก็บเงิน เซสชันจะเริ่มต้นเมื่อผู้ใช้เริ่มพิมพ์ เซสชันจะสิ้นสุดเมื่อผู้ใช้เลือกสถานที่และมีการเรียกไปยังรายละเอียดสถานที่

หากต้องการสร้างโทเค็นเซสชันใหม่และเพิ่มลงในคำขอ ให้สร้างอินสแตนซ์ของ 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 - Per Request หากคุณนำโทเค็นเซสชันมาใช้ซ้ำ ระบบจะถือว่าเซสชันไม่ถูกต้องและจะเรียกเก็บเงินจากคำขอ ราวกับว่าไม่มีการระบุโทเค็นเซสชัน

ตัวอย่าง

ขณะที่ผู้ใช้พิมพ์คำค้นหา ระบบจะเรียกคำขอเติมข้อความอัตโนมัติทุกๆ 2-3 ครั้งที่กดแป้น (ไม่ใช่ต่ออักขระ) และจะแสดงรายการผลลัพธ์ที่เป็นไปได้ เมื่อผู้ใช้เลือกจากรายการผลลัพธ์ ระบบจะนับการเลือกเป็นคำขอ และจะรวมคำขอทั้งหมดที่ดำเนินการระหว่างการค้นหาและนับเป็นคำขอเดียว หากผู้ใช้เลือกสถานที่ ระบบจะไม่มีค่าใช้จ่ายสำหรับคำค้นหา และจะเรียกเก็บเงินเฉพาะคำขอข้อมูลสถานที่ หากผู้ใช้ไม่ได้เลือกภายในไม่กี่นาทีหลังจากเริ่มเซสชัน ระบบจะเรียกเก็บเงินเฉพาะคำค้นหา

จากมุมมองของแอป ขั้นตอนของเหตุการณ์จะเป็นดังนี้

  1. ผู้ใช้เริ่มพิมพ์คำค้นหาเพื่อค้นหา "ปารีส ฝรั่งเศส"
  2. เมื่อตรวจพบอินพุตของผู้ใช้ แอปจะสร้างโทเค็นเซสชันใหม่ "โทเค็น A"
  3. ขณะที่ผู้ใช้พิมพ์ API จะส่งคำขอเติมข้อความอัตโนมัติทุกๆ 2-3 อักขระ โดยจะแสดงรายการผลลัพธ์ใหม่ที่อาจเป็นไปได้สำหรับแต่ละคำ
    "P"
    "Par"
    "Paris"
    "Paris, Fr"
  4. เมื่อผู้ใช้เลือกรายการต่อไปนี้
    • ระบบจะจัดกลุ่มคำขอทั้งหมดที่เกิดจากการค้นหาและเพิ่มลงใน เซสชันที่แสดงโดย "โทเค็น A" เป็นคำขอเดียว
    • ระบบจะนับการเลือกของผู้ใช้เป็นคำขอรายละเอียดสถานที่ และเพิ่ม ลงในเซสชันที่แสดงโดย "โทเค็น A"
  5. เซสชันสิ้นสุดลง และแอปจะทิ้ง "โทเค็น A"
ดูข้อมูลเกี่ยวกับวิธีเรียกเก็บเงินสำหรับเซสชัน

โค้ดตัวอย่างที่สมบูรณ์

ส่วนนี้มีตัวอย่างที่สมบูรณ์ซึ่งแสดงวิธีใช้ Place Autocomplete Data API

การคาดคะเนการเติมข้อความอัตโนมัติของสถานที่

ตัวอย่างต่อไปนี้แสดงการเรียกใช้ fetchAutocompleteSuggestions() สำหรับอินพุต "Tadi" จากนั้นเรียกใช้ toPlace() ในผลการคาดคะเนแรก ตามด้วยการเรียกใช้ fetchFields() เพื่อรับรายละเอียดสถานที่

TypeScript

async function init() {
  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 + '":')
  );

  const resultsElement = document.getElementById("results") as HTMLElement;

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

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

    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

async function init() {
    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 + '":'));
    const resultsElement = document.getElementById("results");
    for (let suggestion of suggestions) {
        const placePrediction = suggestion.placePrediction;
        // Create a new list element.
        const listItem = document.createElement("li");
        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>
    <!-- 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>
    <div id="title"></div>
    <ul id="results"></ul>
    <p><span id="prediction"></span></p>
    <img
      class="powered-by-google"
      src="./powered_by_google_on_white.png"
      alt="Powered by Google"
    />

  </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. 
 */
gmp-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>

ลองใช้ตัวอย่าง