Place Autocomplete Data API

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

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

ตัวอย่างต่อไปนี้แสดงการผสานรวมการพิมพ์ล่วงหน้าที่เรียบง่าย ป้อนคำค้นหา เช่น "พิซซ่า" หรือ "โปเก" แล้วคลิกเพื่อเลือกผลการค้นหาที่ต้องการ

คำขอเติมข้อความอัตโนมัติ

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

ข้อมูลโค้ดต่อไปนี้แสดงการสร้างเนื้อหาคำขอและการเพิ่มโทเค็นของเซสชัน จากนั้นเรียกใช้ fetchAutocompleteSuggestions() เพื่อรับรายการ PlacePrediction

// Add an initial request body.
const 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.
request.sessionToken = token;

จำกัดการคาดคะเนการเติมข้อความอัตโนมัติ

โดยค่าเริ่มต้น Place Autocomplete จะแสดงสถานที่ทุกประเภท โดยให้น้ำหนักกับการคาดคะเนที่อยู่ใกล้กับตำแหน่งของผู้ใช้ และดึงข้อมูลทุกฟิลด์ข้อมูลที่มีอยู่สำหรับสถานที่ที่ผู้ใช้เลือก ตั้งค่าตัวเลือก Place Autocomplete เพื่อแสดงการคาดคะเนที่เกี่ยวข้องมากขึ้นโดยการจำกัดหรือให้น้ำหนักพิเศษแก่ผลการค้นหา

การจำกัดผลลัพธ์จะทำให้วิดเจ็ตการเติมข้อความอัตโนมัติละเว้นผลลัพธ์ที่อยู่นอกพื้นที่ที่จำกัด แนวทางปฏิบัติที่พบบ่อยคือการจำกัดผลการค้นหาให้อยู่ในขอบเขตของแผนที่ การให้น้ำหนักพิเศษกับผลการค้นหาจะทำให้วิดเจ็ตการเติมข้อความอัตโนมัติแสดงผลลัพธ์ภายในพื้นที่ที่ระบุ แต่ผลการค้นหาที่ตรงกันบางรายการอาจอยู่นอกพื้นที่นั้น

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

ใช้พร็อพเพอร์ตี้ includedPrimaryTypes เพื่อระบุประเภทสถานที่ได้สูงสุด 5 ประเภท หากไม่ได้ระบุประเภท ระบบจะแสดงผลสถานที่ทุกประเภท

ดูเอกสารอ้างอิง API

ดูรายละเอียดสถานที่

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

const 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.
request.sessionToken = token;

เซสชันจะสิ้นสุดลงเมื่อมีการเรียกใช้ fetchFields() หลังจากสร้างอินสแตนซ์ Place แล้ว คุณไม่จำเป็นต้องส่งโทเค็นของเซสชันไปยัง fetchFields() เนื่องจากระบบจะจัดการให้โดยอัตโนมัติ

await place.fetchFields({
    fields: ['displayName', 'formattedAddress'],
});

สร้างโทเค็นของเซสชันสำหรับเซสชันถัดไปโดยสร้างอินสแตนซ์ใหม่ของ AutocompleteSessionToken

คำแนะนำเกี่ยวกับโทเค็นของเซสชัน

  • ใช้โทเค็นของเซสชันสำหรับการเรียกใช้ Place Autocomplete ทั้งหมด
  • สร้างโทเค็นใหม่สำหรับแต่ละเซสชัน
  • ส่งโทเค็นของเซสชันที่ไม่ซ้ำกันสำหรับเซสชันใหม่แต่ละรายการ การใช้โทเค็นเดียวกันสำหรับเซสชันมากกว่า 1 เซสชันจะส่งผลให้มีการเรียกเก็บเงินสำหรับคำขอแต่ละรายการแยกกัน

คุณสามารถละเว้นโทเค็นของเซสชันการเติมข้อความอัตโนมัติจากคำขอได้ (ไม่บังคับ) หากละเว้นโทเค็นของเซสชัน ระบบจะเรียกเก็บเงินสำหรับคำขอแต่ละรายการแยกกัน ซึ่งจะทริกเกอร์ SKU การเติมข้อความอัตโนมัติ - ต่อคำขอ หากคุณใช้โทเค็นของเซสชันซ้ำ ระบบจะถือว่าเซสชันไม่ถูกต้องและจะเรียกเก็บเงินคำขอเสมือนว่าไม่มีการระบุโทเค็นของเซสชัน

ตัวอย่าง

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

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

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

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

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

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

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

TypeScript

async function init() {
    const { AutocompleteSessionToken, AutocompleteSuggestion } =
        await google.maps.importLibrary('places');

    // Add an initial request body.
    const request: google.maps.places.AutocompleteRequest = {
        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.
    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 (const 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);
    }

    const 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}`;
}

void init();

JavaScript

async function init() {
    const { AutocompleteSessionToken, AutocompleteSuggestion } =
        await google.maps.importLibrary('places');

    // Add an initial request body.
    const 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.
    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 (const 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);
    }

    const 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}`;
}

void 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>
        <script>
            // prettier-ignore
            (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: "GOOGLE_MAPS_API_KEY"
            });
        </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>

Place Autocomplete แบบพิมพ์ล่วงหน้าพร้อมเซสชัน

ตัวอย่างนี้แสดงแนวคิดต่อไปนี้

  • การเรียกใช้ fetchAutocompleteSuggestions() โดยอิงตามคำค้นหาของผู้ใช้และแสดงรายการสถานที่ที่คาดการณ์ไว้เพื่อตอบกลับ
  • การใช้โทเค็นของเซสชันเพื่อจัดกลุ่มคำค้นหาของผู้ใช้กับคำขอรายละเอียดสถานที่ขั้นสุดท้าย
  • ดึงข้อมูลรายละเอียดสถานที่สำหรับสถานที่ที่เลือกและแสดงเครื่องหมาย
  • การใช้การจัดช่องควบคุมเพื่อฝังองค์ประกอบ UI ในองค์ประกอบ gmp-map

TypeScript

const mapElement = document.querySelector('gmp-map')!;
let innerMap: google.maps.Map;
let marker: google.maps.marker.AdvancedMarkerElement;
const titleElement = document.querySelector<HTMLElement>('.title')!;
const resultsContainerElement = document.querySelector('.results')!;
const inputElement = document.querySelector('input')!;
const tokenStatusElement = document.querySelector('.token-status')!;
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.
    innerMap.addListener('bounds_changed', () => {
        request.locationRestriction = innerMap.getBounds();
        request.origin = innerMap.getCenter();
    });

    inputElement.addEventListener('input', makeAutocompleteRequest);
}

async function makeAutocompleteRequest(inputEvent: Event) {
    // 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 as HTMLInputElement)?.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', () => {
            void 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');

    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}`;
}

void init();

JavaScript

const mapElement = document.querySelector('gmp-map');
let innerMap;
let marker;
const titleElement = document.querySelector('.title');
const resultsContainerElement = document.querySelector('.results');
const inputElement = document.querySelector('input');
const 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.
    innerMap.addListener('bounds_changed', () => {
        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', () => {
            void 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}`;
}

void 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>
        <script>
            // prettier-ignore
            (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: "GOOGLE_MAPS_API_KEY"
            });
        </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>

การเพิ่มประสิทธิภาพการเติมข้อความอัตโนมัติ (ใหม่)

ส่วนนี้จะอธิบายแนวทางปฏิบัติแนะนำเพื่อช่วยให้คุณใช้ประโยชน์จากบริการเติมข้อความอัตโนมัติ (ใหม่) ได้อย่างเต็มที่

หลักเกณฑ์ทั่วไปมีดังนี้

แนวทางปฏิบัติแนะนำในการเพิ่มประสิทธิภาพต้นทุน

การเพิ่มประสิทธิภาพต้นทุนพื้นฐาน

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

การเพิ่มประสิทธิภาพต้นทุนขั้นสูง

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

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

แอปพลิเคชันของคุณต้องการข้อมูลอื่นนอกเหนือจากที่อยู่และละติจูด/ลองจิจูดของการคาดคะเนที่เลือกหรือไม่

ใช่ ต้องระบุรายละเอียดเพิ่มเติม

ใช้การเติมข้อความอัตโนมัติ (ใหม่) ตามเซสชันกับรายละเอียดสถานที่ (ใหม่)
เนื่องจากแอปพลิเคชันของคุณต้องใช้รายละเอียดสถานที่ (ใหม่) เช่น ชื่อสถานที่ สถานะธุรกิจ หรือเวลาทำการ การใช้งานการเติมข้อความอัตโนมัติ (ใหม่) ควรใช้โทเค็นของเซสชัน (แบบเป็นโปรแกรมหรือฝังในวิดเจ็ต JavaScript, Android หรือ iOS) ต่อเซสชัน บวกกับ SKU ของ Places ที่เกี่ยวข้อง โดยขึ้นอยู่กับฟิลด์ข้อมูลสถานที่ที่คุณขอ1

การติดตั้งใช้งานวิดเจ็ต
การจัดการเซสชันจะติดตั้งมาในวิดเจ็ต JavaScript, Android หรือ iOS โดยอัตโนมัติ ซึ่งรวมถึงทั้งคำขอการเติมข้อความอัตโนมัติ (ใหม่) และคำขอรายละเอียดสถานที่ (ใหม่) ในการคาดคะเนที่เลือก อย่าลืมระบุพารามิเตอร์ fields เพื่อให้มั่นใจว่าคุณขอเฉพาะฟิลด์ข้อมูลการเติมข้อความอัตโนมัติ (ใหม่) ที่ต้องการเท่านั้น

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

  1. รหัสสถานที่จากการตอบกลับการเติมข้อความอัตโนมัติ (ใหม่)
  2. โทเค็นของเซสชันที่ใช้ในคำขอการเติมข้อความอัตโนมัติ (ใหม่)
  3. พารามิเตอร์ fields ที่ระบุฟิลด์ข้อมูลของฟีเจอร์เติมข้อความอัตโนมัติ (ใหม่) ที่คุณต้องการ

ไม่ ต้องใช้เพียงที่อยู่และสถานที่ตั้ง

Geocoding API อาจเป็นตัวเลือกที่คุ้มค่ากว่ารายละเอียดสถานที่ (ใหม่) สำหรับแอปพลิเคชันของคุณ ทั้งนี้ขึ้นอยู่กับประสิทธิภาพการใช้งานการเติมข้อความอัตโนมัติ (ใหม่) ประสิทธิภาพของ Autocomplete (ใหม่) ของแต่ละแอปพลิเคชันจะแตกต่างกันไปตามสิ่งที่ผู้ใช้ป้อน สถานที่ที่ใช้แอปพลิเคชัน และมีการใช้แนวทางปฏิบัติแนะนำในการเพิ่มประสิทธิภาพหรือไม่

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

ผู้ใช้เลือกการคาดคะเนการเติมข้อความอัตโนมัติ (ใหม่) โดยเฉลี่ย 4 คำขอหรือน้อยกว่านั้นใช่ไหม

ใช่

ใช้การเติมข้อความอัตโนมัติ (ใหม่) แบบเป็นโปรแกรมโดยไม่มีโทเค็นของเซสชัน และเรียกใช้ Geocoding API ในการคาดคะเนสถานที่ที่เลือก
Geocoding API จะแสดงที่อยู่และพิกัดละติจูด/ลองจิจูด การส่งคำขอ Autocomplete Requests 4 รายการบวกกับการเรียก Geocoding API เกี่ยวกับการคาดคะเนสถานที่ที่เลือกจะมีค่าใช้จ่ายน้อยกว่า Autocomplete (ใหม่) ต่อเซสชัน1

ลองใช้แนวทางปฏิบัติแนะนำด้านประสิทธิภาพเพื่อช่วยให้ผู้ใช้ได้รับการคาดคะเนที่ต้องการโดยใช้อักขระน้อยลง

ไม่ใช่

ใช้การเติมข้อความอัตโนมัติ (ใหม่) ตามเซสชันกับรายละเอียดสถานที่ (ใหม่)
เนื่องจากจำนวนคำขอโดยเฉลี่ยที่คุณคาดว่าจะทำก่อนที่ผู้ใช้จะเลือกการคาดคะเนการเติมข้อความอัตโนมัติ (ใหม่) เกินค่าใช้จ่ายของการกำหนดราคาต่อเซสชัน การใช้งานการเติมข้อความอัตโนมัติ (ใหม่) ของคุณจึงควรใช้โทเค็นเซสชันสำหรับทั้งคำขอการเติมข้อความอัตโนมัติ (ใหม่) และคำขอรายละเอียดสถานที่ (ใหม่) ที่เกี่ยวข้อง ต่อเซสชัน 1

การติดตั้งใช้งานวิดเจ็ต
การจัดการเซสชันจะติดตั้งมาในวิดเจ็ต JavaScript, Android หรือ iOS โดยอัตโนมัติ ซึ่งรวมถึงทั้งคำขอการเติมข้อความอัตโนมัติ (ใหม่) และคำขอรายละเอียดสถานที่ (ใหม่) ในการคาดคะเนที่เลือก อย่าลืมระบุพารามิเตอร์ fields เพื่อให้แน่ใจว่าคุณขอเฉพาะช่องที่ต้องการเท่านั้น

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

  1. รหัสสถานที่จากการตอบกลับการเติมข้อความอัตโนมัติ (ใหม่)
  2. โทเค็นของเซสชันที่ใช้ในคำขอการเติมข้อความอัตโนมัติ (ใหม่)
  3. พารามิเตอร์ fields ที่ระบุ ช่อง เช่น ที่อยู่และเรขาคณิต

พิจารณาการหน่วงเวลาคำขอการเติมข้อความอัตโนมัติ (ใหม่)
คุณสามารถใช้กลยุทธ์ต่างๆ เช่น หน่วงเวลาคำขอการเติมข้อความอัตโนมัติ (ใหม่) จนกว่าผู้ใช้จะพิมพ์อักขระ 3 หรือ 4 ตัวแรก เพื่อให้แอปพลิเคชันส่งคำขอน้อยลง ตัวอย่างเช่น การส่งคำขอการเติมข้อความอัตโนมัติ (ใหม่) สำหรับอักขระแต่ละตัวหลังจากที่ผู้ใช้พิมพ์อักขระตัวที่ 3 หมายความว่าหากผู้ใช้พิมพ์อักขระ 7 ตัวแล้วเลือกการคาดคะเนที่คุณส่งคำขอ Geocoding API 1 รายการ ค่าใช้จ่ายทั้งหมดจะเป็นค่าใช้จ่ายสำหรับการเติมข้อความอัตโนมัติ (ใหม่) 4 รายการต่อคำขอ + การเข้ารหัสพิกัดภูมิศาสตร์1

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

ลองใช้แนวทางปฏิบัติแนะนำด้านประสิทธิภาพเพื่อช่วยให้ผู้ใช้ได้รับการคาดคะเนที่ต้องการโดยใช้อักขระน้อยลง


  1. ดูค่าใช้จ่ายได้ที่รายการราคาของ Google Maps Platform

แนวทางปฏิบัติแนะนำด้านประสิทธิภาพ

หลักเกณฑ์ต่อไปนี้อธิบายวิธีเพิ่มประสิทธิภาพการเติมข้อความอัตโนมัติ (ใหม่)

  • เพิ่มข้อจำกัดในแต่ละประเทศ การให้น้ำหนักตามสถานที่ตั้ง และค่ากำหนดภาษา (สำหรับการติดตั้งใช้งานแบบเป็นโปรแกรม) ลงในการติดตั้งใช้งานการเติมข้อความอัตโนมัติ (ใหม่) ไม่จำเป็นต้องใช้ค่ากำหนดภาษาสำหรับวิดเจ็ต เนื่องจากวิดเจ็ตจะเลือกค่ากำหนดภาษาจากเบราว์เซอร์หรืออุปกรณ์เคลื่อนที่ของผู้ใช้
  • หากการเติมข้อความอัตโนมัติ (ใหม่) มาพร้อมกับแผนที่ คุณสามารถให้น้ำหนักสถานที่ตั้งตามวิวพอร์ตของแผนที่ได้
  • ในสถานการณ์ที่ผู้ใช้ไม่ได้เลือกการคาดคะเนการเติมข้อความอัตโนมัติ (ใหม่) รายการใดรายการหนึ่ง โดยทั่วไปแล้วเนื่องจากการคาดคะเนเหล่านั้นไม่ใช่ที่อยู่ผลลัพธ์ที่ต้องการ คุณสามารถใช้ข้อมูลจากผู้ใช้เดิมซ้ำเพื่อพยายามรับผลลัพธ์ที่เกี่ยวข้องมากขึ้นได้ ดังนี้
    • หากคุณคาดหวังให้ผู้ใช้ป้อนเฉพาะข้อมูลที่อยู่ ให้นำข้อมูลจากผู้ใช้เดิมมาใช้ซ้ำในการเรียกใช้ Geocoding API
    • หากคุณคาดหวังให้ผู้ใช้ป้อนคำค้นหาสำหรับสถานที่ที่เฉพาะเจาะจงตามชื่อหรือที่อยู่ ให้ใช้คำขอรายละเอียดสถานที่ (ใหม่) หากคาดว่าผลลัพธ์จะอยู่ในภูมิภาคที่เฉพาะเจาะจงเท่านั้น ให้ใช้การให้น้ำหนักตามสถานที่ตั้ง
    สถานการณ์อื่นๆ ที่ควรเปลี่ยนไปใช้ Geocoding API ได้แก่
    • ผู้ใช้ป้อนที่อยู่ย่อย เช่น ที่อยู่ของยูนิตหรืออพาร์ตเมนต์ที่เฉพาะเจาะจงภายในอาคาร เช่น ที่อยู่ในสาธารณรัฐเช็ก "Stroupežnického 3191/17, Praha" จะแสดงการคาดคะเนบางส่วนในการเติมข้อความอัตโนมัติ (ใหม่)
    • ผู้ใช้ป้อนที่อยู่ที่มีคำนำหน้าส่วนของถนน เช่น "23-30 29th St, Queens" ในนครนิวยอร์ก หรือ "47-380 Kamehameha Hwy, Kaneohe" บนเกาะคาไวในฮาวาย

การให้น้ำหนักพิเศษกับบางตำแหน่ง

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

การจำกัดสถานที่ตั้ง

จำกัดผลการค้นหาให้อยู่ในพื้นที่ที่ระบุโดยส่งพารามิเตอร์ locationRestriction

นอกจากนี้ คุณยังจำกัดผลการค้นหาให้อยู่ในภูมิภาคที่กำหนดโดย location และพารามิเตอร์ radius ได้ด้วยการเพิ่มพารามิเตอร์ locationRestriction ซึ่งจะสั่งให้การเติมข้อความอัตโนมัติ (ใหม่) แสดงผลลัพธ์เฉพาะภายในภูมิภาคนั้น