วาง API ข้อมูลที่เติมข้อความอัตโนมัติ

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"],
});
await place.fetchFields({
    fields: ['displayName'],
  });

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

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

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

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

ตัวอย่าง

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

จากมุมมองของแอป โฟลว์ของเหตุการณ์จะมีลักษณะดังต่อไปนี้

  1. ผู้ใช้เริ่มพิมพ์ข้อความค้นหาเพื่อค้นหา "ปารีส ประเทศฝรั่งเศส"
  2. เมื่อตรวจพบอินพุตของผู้ใช้ แอปจะสร้างโทเค็นเซสชันใหม่ "โทเค็น A"
  3. เมื่อผู้ใช้พิมพ์ API จะส่งคำขอเติมข้อความอัตโนมัติทุกๆ 2-3 อักขระ โดยแสดงรายการผลลัพธ์ใหม่ที่เป็นไปได้สำหรับแต่ละอักขระดังนี้
    "P"
    "Par"
    "ปารีส"
    "ปารีส, Fr"
  4. สิ่งที่จะเกิดขึ้นเมื่อผู้ใช้เลือกมีดังนี้
    • ระบบจะจัดกลุ่มคำขอทั้งหมดที่เกิดจากการค้นหาดังกล่าวและเพิ่มลงในเซสชันที่แสดงด้วย "โทเค็น A" เป็นคำขอเดียว
    • การเลือกของผู้ใช้จะนับเป็นคำขอรายละเอียดสถานที่และเพิ่มลงในเซสชันที่แสดงด้วย "โทเค็น A"
  5. เซสชันสิ้นสุดลงและแอปทิ้ง "โทเค็น 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>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <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>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <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>

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