Place Autocomplete Data API

Developer Wilayah Ekonomi Eropa (EEA)

Place Autocomplete Data API memungkinkan Anda mengambil prediksi tempat secara terprogram, untuk membuat pengalaman pelengkapan otomatis yang disesuaikan dengan tingkat kontrol yang lebih baik daripada yang dapat dilakukan dengan widget pelengkapan otomatis. Dalam panduan ini, Anda akan mempelajari cara menggunakan Place Autocomplete Data API untuk membuat permintaan pelengkapan otomatis berdasarkan kueri pengguna.

Contoh berikut menunjukkan integrasi saran penelusuran yang disederhanakan. Masukkan kueri penelusuran Anda, seperti "pizza" atau "poke", lalu klik untuk memilih hasil yang Anda inginkan.

Permintaan Pelengkapan Otomatis

Permintaan pelengkapan otomatis mengambil string input kueri dan menampilkan daftar prediksi tempat. Untuk membuat permintaan pelengkapan otomatis, panggil fetchAutocompleteSuggestions() dan teruskan permintaan dengan properti yang diperlukan. Properti input berisi string yang akan ditelusuri; dalam aplikasi umum, nilai ini akan diperbarui saat pengguna mengetik kueri. Permintaan harus menyertakan sessionToken, yang digunakan untuk tujuan penagihan.

Cuplikan berikut menunjukkan cara membuat isi permintaan dan menambahkan token sesi, lalu memanggil fetchAutocompleteSuggestions() untuk mendapatkan daftar 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;

Membatasi prediksi Autocomplete

Secara default, Place Autocomplete menampilkan semua jenis tempat, dengan bias prediksi di dekat lokasi pengguna, lalu mengambil semua kolom data yang tersedia untuk tempat yang dipilih pengguna. Tetapkan opsi Place Autocomplete untuk memberikan prediksi yang lebih relevan, dengan membatasi atau membiaskan hasil.

Membatasi hasil akan menyebabkan widget Autocomplete mengabaikan hasil apa pun yang berada di luar area pembatasan. Praktik yang umum adalah membatasi hasil ke batas peta. Membiaskan hasil akan membuat widget Autocomplete menampilkan hasil dalam area yang ditentukan, tetapi beberapa hasil yang cocok mungkin berada di luar area tersebut.

Gunakan properti origin untuk menentukan titik asal dari mana jarak geodetik ke tujuan akan dihitung. Jika nilai ini tidak disertakan, jarak tidak akan ditampilkan.

Gunakan properti includedPrimaryTypes untuk menentukan hingga lima jenis tempat. Jika tidak ada jenis yang ditentukan, tempat dari semua jenis akan ditampilkan.

Lihat referensi API

Mendapatkan detail tempat

Untuk menampilkan objek Place dari hasil prediksi tempat, panggil toPlace() terlebih dahulu, lalu panggil fetchFields() pada objek Place yang dihasilkan (ID sesi dari prediksi tempat disertakan secara otomatis). Memanggil fetchFields() akan mengakhiri sesi pelengkapan otomatis.

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;

Token sesi

Token sesi mengelompokkan fase kueri dan pemilihan dari penelusuran pelengkapan otomatis pengguna ke dalam sesi terpisah untuk tujuan penagihan. Sesi dimulai saat pengguna mulai mengetik. Sesi berakhir saat pengguna memilih tempat dan panggilan ke Place Details dilakukan.

Untuk membuat token sesi baru dan menambahkannya ke permintaan, buat instance AutocompleteSessionToken, lalu tetapkan properti sessionToken permintaan untuk menggunakan token seperti yang ditunjukkan dalam cuplikan berikut:

// Create a session token.
const token = new AutocompleteSessionToken();

// Add the token to the request.
// @ts-ignore
request.sessionToken = token;

Sesi berakhir saat fetchFields() dipanggil. Setelah membuat instance Place, Anda tidak perlu meneruskan token sesi ke fetchFields() karena hal ini ditangani secara otomatis.

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

Buat token sesi untuk sesi berikutnya dengan membuat instance baru AutocompleteSessionToken.

Rekomendasi token sesi:

  • Gunakan token sesi untuk semua panggilan Place Autocomplete.
  • Buat token baru untuk setiap sesi.
  • Teruskan token sesi unik untuk setiap sesi baru. Jika menggunakan token yang sama untuk lebih dari satu sesi, setiap permintaan akan ditagih satu per satu.

Anda dapat memilih untuk tidak menyertakan token sesi pelengkapan otomatis dari permintaan. Jika token sesi tidak disertakan, setiap permintaan ditagih secara terpisah, sehingga memicu SKU Autocomplete - Per Request. Jika Anda menggunakan kembali token sesi, sesi tersebut dianggap tidak valid dan permintaan akan dikenai biaya seolah-olah tidak ada token sesi yang diberikan.

Contoh

Saat pengguna mengetik kueri, permintaan pelengkapan otomatis dipanggil setiap beberapa penekanan tombol (bukan per karakter), dan daftar kemungkinan hasil ditampilkan. Saat pengguna membuat pilihan dari daftar hasil, pilihan tersebut dihitung sebagai permintaan, dan semua permintaan yang dibuat selama penelusuran digabungkan dan dihitung sebagai satu permintaan. Jika pengguna memilih tempat, kueri penelusuran tersedia tanpa biaya, dan hanya permintaan data Tempat yang dikenai biaya. Jika pengguna tidak membuat pilihan dalam beberapa menit setelah sesi dimulai, hanya kueri penelusuran yang ditagih.

Dari perspektif aplikasi, alur peristiwanya adalah sebagai berikut:

  1. Pengguna mulai mengetik kueri untuk menelusuri "Paris, Prancis".
  2. Setelah mendeteksi input pengguna, aplikasi membuat token sesi baru, "Token A".
  3. Saat pengguna mengetik, API akan membuat permintaan pelengkapan otomatis setiap beberapa karakter, menampilkan daftar baru hasil yang mungkin untuk setiap karakter:
    "P"
    "Par"
    "Paris",
    "Paris, Fr"
  4. Saat pengguna membuat pilihan:
    • Semua permintaan yang dihasilkan dari kueri dikelompokkan dan ditambahkan ke sesi yang diwakili oleh "Token A", sebagai satu permintaan.
    • Pilihan pengguna dihitung sebagai permintaan Place Detail, dan ditambahkan ke sesi yang diwakili oleh "Token A".
  5. Sesi selesai, dan aplikasi membuang "Token A".
Pelajari cara penagihan sesi

Kode contoh lengkap

Bagian ini berisi contoh lengkap yang menunjukkan cara menggunakan Place Autocomplete Data API .

Prediksi pelengkapan otomatis tempat

Contoh berikut menunjukkan cara memanggil fetchAutocompleteSuggestions() untuk input "Tadi", lalu memanggil toPlace() pada hasil prediksi pertama, diikuti dengan panggilan ke fetchFields() untuk mendapatkan detail tempat.

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>

Mencoba Contoh

Prediksi ketikan Place Autocomplete dengan sesi

Contoh ini menunjukkan cara memanggil fetchAutocompleteSuggestions() berdasarkan kueri pengguna, menampilkan daftar tempat yang diprediksi sebagai respons, dan terakhir mengambil detail tempat untuk tempat yang dipilih. Contoh ini juga menunjukkan penggunaan token sesi untuk mengelompokkan kueri pengguna dengan permintaan Place Details akhir.

TypeScript

let titleElement;
let resultsContainerElement;
let inputElement;

let newestRequestId = 0;

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

function init() {
    titleElement = document.getElementById('title');
    resultsContainerElement = document.getElementById('results');
    inputElement = document.querySelector('input');
    inputElement.addEventListener('input', makeAutocompleteRequest);
    refreshToken(request);
}

async function makeAutocompleteRequest(inputEvent) {
    // Reset elements and exit if an empty string is received.
    if (inputEvent.target.value == '') {
        titleElement.innerText = '';
        resultsContainerElement.replaceChildren();
        return;
    }

    // Add the latest char sequence to the request.
    request.input = inputEvent.target.value;

    // To avoid race conditions, store the request ID and compare after the request.
    const requestId = ++newestRequestId;

    // Fetch autocomplete suggestions and show them in a list.
    // @ts-ignore
    const { suggestions } = await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

    // If the request has been superseded by a newer request, do not render the output.
    if (requestId !== newestRequestId) return;

    titleElement.innerText = `Query predictions for "${request.input}"`;

    // Clear the list first.
    resultsContainerElement.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 item element.
        const li = document.createElement('li');
        li.appendChild(a);
        resultsContainerElement.appendChild(li);
    }
}

// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress'],
    });
    const placeText = document.createTextNode(`${place.displayName}: ${place.formattedAddress}`);
    resultsContainerElement.replaceChildren(placeText);
    titleElement.innerText = 'Selected Place:';
    inputElement.value = '';
    refreshToken(request);
}

// Helper function to refresh the session token.
function refreshToken(request) {
    // Create a new session token and add it to the request.
    request.sessionToken = new google.maps.places.AutocompleteSessionToken();
}

declare global {
    interface Window {
      init: () => void;
    }
  }
  window.init = init;

JavaScript

let titleElement;
let resultsContainerElement;
let inputElement;
let newestRequestId = 0;
// Add an initial request body.
const 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',
};
function init() {
    titleElement = document.getElementById('title');
    resultsContainerElement = document.getElementById('results');
    inputElement = document.querySelector('input');
    inputElement.addEventListener('input', makeAutocompleteRequest);
    refreshToken(request);
}
async function makeAutocompleteRequest(inputEvent) {
    // Reset elements and exit if an empty string is received.
    if (inputEvent.target.value == '') {
        titleElement.innerText = '';
        resultsContainerElement.replaceChildren();
        return;
    }
    // Add the latest char sequence to the request.
    request.input = inputEvent.target.value;
    // To avoid race conditions, store the request ID and compare after the request.
    const requestId = ++newestRequestId;
    // Fetch autocomplete suggestions and show them in a list.
    // @ts-ignore
    const { suggestions } = await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);
    // If the request has been superseded by a newer request, do not render the output.
    if (requestId !== newestRequestId)
        return;
    titleElement.innerText = `Query predictions for "${request.input}"`;
    // Clear the list first.
    resultsContainerElement.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 item element.
        const li = document.createElement('li');
        li.appendChild(a);
        resultsContainerElement.appendChild(li);
    }
}
// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress'],
    });
    const placeText = document.createTextNode(`${place.displayName}: ${place.formattedAddress}`);
    resultsContainerElement.replaceChildren(placeText);
    titleElement.innerText = 'Selected Place:';
    inputElement.value = '';
    refreshToken(request);
}
// Helper function to refresh the session token.
function refreshToken(request) {
    // Create a new session token and add it to the request.
    request.sessionToken = new google.maps.places.AutocompleteSessionToken();
}
window.init = init;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

a {
  cursor: pointer;
  text-decoration: underline;
  color: blue;
}

input {
  width: 300px;
}

HTML

<html>
  <head>
    <title>Place Autocomplete Data API Session</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <input id="input" type="text" placeholder="Search for a place..." />
    <div id="title"></div>
    <ul id="results"></ul>
    <img
      class="powered-by-google"
      src="https://storage.googleapis.com/geo-devrel-public-buckets/powered_by_google_on_white.png"
      alt="Powered by Google"
    />

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8&callback=init&libraries=places&v=weekly"
      defer
    ></script>
  </body>
</html>

Mencoba Contoh