地點自動完成

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

引言

自動完成功能是 Maps JavaScript API 中的地點介面集功能。您可以使用自動完成功能,讓應用程式預先提供 Google 地圖搜尋欄位的預先搜尋行為。自動完成服務可比對完整字詞和子字串,進而解析地點名稱、地址和加號代碼。因此,應用程式會在使用者類型中傳送查詢,以便即時提供預測。

開始

使用 Maps JavaScript API 中的 Places Library 前,請先確認 Google Cloud Console 已啟用的 Places API,請務必為您為 Maps JavaScript API 設定的專案啟用。

查看已啟用的 API 清單:

  1. 前往 Google Cloud Console
  2. 按一下「選取專案」按鈕,然後選取您為 Maps JavaScript API 設定的專案,然後按一下「開啟」
  3. 資訊主頁的 API 清單中,尋找 Places API
  4. 如果清單中有這個 API,表示您已完成所有設定。如果 API 未列出 API,請啟用該 API:
    1. 選取頁面頂端的「ENABLE API」,即可顯示「Library」(資料庫) 分頁標籤。或者,從左側選單中選取 [程式庫]
    2. 搜尋「Places API」,然後從結果清單中選取 API。
    3. 選取「啟用」。程序完成後,資訊主頁的 API 清單會顯示「Places API」

正在載入程式庫

「地點」服務是獨立的程式庫,與主要的 Maps JavaScript API 程式碼不同。如要使用這個程式庫提供的功能,您必須先使用 Maps API 啟動網址的 libraries 參數載入:

<script async
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap">
</script>

詳情請參閱程式庫總覽

課程摘要

API 提供兩種自動完成小工具,您可以透過 AutocompleteSearchBox 類別分別新增。此外,您也可以使用 AutocompleteService 類別,透過程式輔助方式擷取自動完成結果 (請參閱 Maps JavaScript API 參考資料:AutocompleteService 類別)。

以下簡要說明我們提供的類別:

  • Autocomplete 會在網頁中加入文字輸入欄位,並監控該欄位的半形字元。當使用者輸入文字時,自動完成功能會以下拉式選單的形式,傳回地點預測值。當使用者從清單中選取地點時,系統會將該地點資訊傳回自動完成物件,供應用程式擷取。詳情請參閱下方說明。
    自動輸入文字欄位,以及使用者輸入搜尋查詢時提供的地點預測選項清單。
    圖 1:自動完成文字欄位及選取清單
    完成的地址表單。
    圖 2:完成的地址表單
  • SearchBox 在網頁中加入文字輸入欄位,做法與 Autocomplete 相同。差別如下:
    • 主要差異在於顯示清單中顯示的結果。SearchBox 提供擴充的預測清單,其中可能包含地點 (由 Places API 定義) 和建議搜尋字詞。舉例來說,如果使用者輸入「#39; in new in new'」,選項清單可能包含「' New York, NY'」這個詞組,以及各種披薩店的名稱。
    • SearchBox 提供較少搜尋選項的 Autocomplete 選項。在前者中,您可以將搜尋範圍限定在指定的 LatLngBounds。在第二種情況下,您可以將搜尋範圍限制於特定國家/地區和特定的地點類型,以及設定邊界。詳情請參閱下方說明
    完成的地址表單。
    圖 3:SearchBox 顯示搜尋字詞和地點預測。
    詳情請參閱下方說明。
  • 您可以建立 AutocompleteService 物件,透過程式輔助方式擷取預測。呼叫 getPlacePredictions() 以擷取相符的地點,或呼叫 getQueryPredictions() 以擷取相符的地點以及建議搜尋字詞。 注意:AutocompleteService 不會新增任何 UI 控制項。 而是透過上述方法傳回預測查詢字串物件的陣列。每個預測物件均包含預測文字,以及參考結果和結果與使用者輸入內容相符的詳細資料。詳情請參閱下文

新增自動完成小工具

Autocomplete 小工具可為網頁建立文字輸入欄位、在 UI 選擇清單中提供地點預測,並回應 getPlace() 要求。挑選器清單中的每個項目都對應於單一地點 (由 Places API 定義)。

Autocomplete 建構函式會採用兩個引數:

  • text 類型的 HTML input 元素。這是自動完成服務會監控並附加結果的輸入欄位。
  • 選用的 AutocompleteOptions 引數,可包含以下屬性:
    • 要在所選 PlaceResultPlace Details 回應中加入的資料陣列 fields。如未設定屬性或傳遞 ['ALL'],系統會傳回所有可用的欄位,並「計費」 (不適用於實際工作環境部署作業)。如需欄位清單,請參閱 PlaceResult
    • 指定明確類型或類型集合的 types 陣列,如「支援類型」一節中所述。如未指定類型,則會傳回所有類型。
    • boundsgoogle.maps.LatLngBounds 物件,用於指定搜尋地點的區域。這些結果會偏誤 (包括但不限於) 這些邊界內的地點。
    • strictBounds 是一個 boolean,用於指定 API 是否只能傳回嚴格於指定 bounds 定義區域內的地點。即使結果與使用者比對相符,API 也不會傳回這個區域以外的結果。
    • componentRestrictions 可用於將結果限制為特定群組。目前,您可以使用 componentRestrictions 來篩選最多 5 個國家/地區。國家/地區必須以兩個字元組成的 ISO 3166-1 Alpha-2 相容國家/地區代碼。必須以國家/地區代碼清單的形式傳遞多個國家/地區。

      注意:如果使用國家/地區代碼收到非預期的結果,請確認您使用的代碼包含所需國家/地區、相依地域和特殊地理區域。您可以在維基百科頁面查看 ISO 3166 國家/地區代碼清單ISO 線上瀏覽平台,取得各項程式碼資訊。

    • placeIdOnly 可用來指示 Autocomplete 小工具只擷取地點 ID。在 Autocomplete 物件上呼叫 getPlace() 時,可用的 PlaceResult 只會設定 place idtypesname 屬性。您可以將傳回的地點 ID 用於呼叫「地點」、「地理編碼」、「路線」或「距離矩陣」服務。

限制自動完成功能的預測

根據預設,Place Autocomplete 會顯示所有地點類型,並針對特定使用者所在位置附近的預測值進行偏誤,並擷取使用者所選地點的所有可用資料欄位。設定 Place Autocomplete 選項,根據您的用途提供更相關的預測結果。

提供施工選項

Autocomplete 建構函式接受 AutocompleteOptions 參數,以便在建立小工具時設定限制。下列範例會設定 boundscomponentRestrictionstypes 選項來要求 establishment 類型地點,偏愛特定地理區域中的地點,並將預測範圍限制為美國境內的地點。設定 fields 選項會指定關於使用者所選地點的資訊。

呼叫 setOptions() 變更現有小工具的選項值。

TypeScript

const center = { lat: 50.064192, lng: -130.605469 };
// Create a bounding box with sides ~10km away from the center point
const defaultBounds = {
  north: center.lat + 0.1,
  south: center.lat - 0.1,
  east: center.lng + 0.1,
  west: center.lng - 0.1,
};
const input = document.getElementById("pac-input") as HTMLInputElement;
const options = {
  bounds: defaultBounds,
  componentRestrictions: { country: "us" },
  fields: ["address_components", "geometry", "icon", "name"],
  strictBounds: false,
  types: ["establishment"],
};

const autocomplete = new google.maps.places.Autocomplete(input, options);

JavaScript

const center = { lat: 50.064192, lng: -130.605469 };
// Create a bounding box with sides ~10km away from the center point
const defaultBounds = {
  north: center.lat + 0.1,
  south: center.lat - 0.1,
  east: center.lng + 0.1,
  west: center.lng - 0.1,
};
const input = document.getElementById("pac-input");
const options = {
  bounds: defaultBounds,
  componentRestrictions: { country: "us" },
  fields: ["address_components", "geometry", "icon", "name"],
  strictBounds: false,
  types: ["establishment"],
};
const autocomplete = new google.maps.places.Autocomplete(input, options);

指定資料欄位

指定資料欄位,避免為不需要的地點資料 SKU 計費。將 fields 屬性傳送至 AutocompleteOptions,藉此傳遞至小工具建構函式 (如以上範例所示),或是在現有的 Autocomplete 物件上呼叫 setFields()

autocomplete.setFields(["place_id", "geometry", "name"]);

定義「自動完成」的偏誤和搜尋區域邊界

您可以按照下列方式,對自動完成結果進行偏誤,藉此使用概略位置或區域:

  • 在建立 Autocomplete 物件時設定邊界。
  • 變更現有 Autocomplete 的邊界。
  • 將界限設定為地圖的檢視點。
  • 將搜尋範圍限制在邊界。
  • 將搜尋範圍限制在特定國家/地區。

以上範例說明如何在建立時設定邊界。以下範例說明其他偏誤技巧。

變更現有 Autocomplete 物件的界限

呼叫 setBounds() 將現有 Autocomplete 的搜尋區域變更為矩形邊界。

TypeScript

const southwest = { lat: 5.6108, lng: 136.589326 };
const northeast = { lat: 61.179287, lng: 2.64325 };
const newBounds = new google.maps.LatLngBounds(southwest, northeast);

autocomplete.setBounds(newBounds);

JavaScript

const southwest = { lat: 5.6108, lng: 136.589326 };
const northeast = { lat: 61.179287, lng: 2.64325 };
const newBounds = new google.maps.LatLngBounds(southwest, northeast);

autocomplete.setBounds(newBounds);
將界限設定為地圖的檢視點

即使該可視區域變更,也可以使用 bindTo() 將結果偏誤到地圖的可視區域。

TypeScript

autocomplete.bindTo("bounds", map);

JavaScript

autocomplete.bindTo("bounds", map);

使用 unbind() 將自動完成的預測功能與地圖可視區域解除繫結。

TypeScript

autocomplete.unbind("bounds");
autocomplete.setBounds({ east: 180, west: -180, north: 90, south: -90 });

JavaScript

autocomplete.unbind("bounds");
autocomplete.setBounds({ east: 180, west: -180, north: 90, south: -90 });

查看範例

將搜尋範圍限定在目前邊界

設定 strictBounds 選項,即可將結果限制在目前的邊界內 (無論地圖可視區域或矩形邊界)。

autocomplete.setOptions({ strictBounds: true });
將預測範圍限制於特定國家/地區

使用 componentRestrictions 選項或呼叫 setComponentRestrictions(),將自動完成搜尋範圍限制在最多五個國家/地區的特定組合中。

TypeScript

autocomplete.setComponentRestrictions({
  country: ["us", "pr", "vi", "gu", "mp"],
});

JavaScript

autocomplete.setComponentRestrictions({
  country: ["us", "pr", "vi", "gu", "mp"],
});

查看範例

限制地點類型

使用 types 選項或呼叫 setTypes(),將預測限制於特定地點類型。這項限制會指定類型或類型集合,如「地點類型」一文所述。 如未指定限制,系統會傳回所有類型。

對於 types 選項的值或傳遞至 setTypes() 的值,您可以指定下列其中一項:

  • 一個陣列最多可包含 表 1表 2 地點類型例如:

    types: ['hospital', 'pharmacy', 'bakery', 'country']

    或是:

    autocomplete.setTypes(['hospital', 'pharmacy', 'bakery', 'country']);
  • 表 3 中任何來自「地點類型」的篩選器。您只能指定資料表 3 中的單一值。

如有下列情況,我們就會拒絕要求:

  • 您指定了超過五個類型。
  • 請指定任何無法辨識的類型。
  • 針對表 1表 2 中的任何類型,與表 3 中的任何篩選器混合。

「地點自動完成」示範示範了不同地點類型之間的預測差異。

前往示範影片

取得地點資訊

當使用者從自動完成文字欄位中附加的預測結果中選取地點時,服務就會觸發 place_changed 事件。如何取得地點詳細資料:

  1. place_changed 事件建立事件處理常式,並對 Autocomplete 物件呼叫 addListener() 以新增處理常式。
  2. 呼叫 Autocomplete 物件的 Autocomplete.getPlace() 以擷取 PlaceResult 物件,以便取得所選地點的更多相關資訊。

根據預設,當使用者選取地點時,自動完成功能會傳回所選地點所有可用的資料欄位,而系統會據此收費。使用 Autocomplete.setFields() 指定要傳回的位置資料欄位。進一步瞭解 PlaceResult 物件,包括可要求的地點資料欄位清單。為避免支付不必要的資料費用,請務必使用 Autocomplete.setFields() 指定要使用的地點資料。

name 屬性包含 Places Autocomplete 預測中的 description。如要進一步瞭解 description,請參閱 Places Autocomplete 文件

以地址表單來說,取得結構化格式的地址會很有幫助。如要傳回所選地點的結構化地址,請呼叫 Autocomplete.setFields() 並指定 address_components 欄位。

以下範例使用自動完成功能填寫地址表單中的欄位。

TypeScript

function fillInAddress() {
  // Get the place details from the autocomplete object.
  const place = autocomplete.getPlace();
  let address1 = "";
  let postcode = "";

  // Get each component of the address from the place details,
  // and then fill-in the corresponding field on the form.
  // place.address_components are google.maps.GeocoderAddressComponent objects
  // which are documented at http://goo.gle/3l5i5Mr
  for (const component of place.address_components as google.maps.GeocoderAddressComponent[]) {
    // @ts-ignore remove once typings fixed
    const componentType = component.types[0];

    switch (componentType) {
      case "street_number": {
        address1 = `${component.long_name} ${address1}`;
        break;
      }

      case "route": {
        address1 += component.short_name;
        break;
      }

      case "postal_code": {
        postcode = `${component.long_name}${postcode}`;
        break;
      }

      case "postal_code_suffix": {
        postcode = `${postcode}-${component.long_name}`;
        break;
      }

      case "locality":
        (document.querySelector("#locality") as HTMLInputElement).value =
          component.long_name;
        break;

      case "administrative_area_level_1": {
        (document.querySelector("#state") as HTMLInputElement).value =
          component.short_name;
        break;
      }

      case "country":
        (document.querySelector("#country") as HTMLInputElement).value =
          component.long_name;
        break;
    }
  }

  address1Field.value = address1;
  postalField.value = postcode;

  // After filling the form with address components from the Autocomplete
  // prediction, set cursor focus on the second address line to encourage
  // entry of subpremise information such as apartment, unit, or floor number.
  address2Field.focus();
}

JavaScript

function fillInAddress() {
  // Get the place details from the autocomplete object.
  const place = autocomplete.getPlace();
  let address1 = "";
  let postcode = "";

  // Get each component of the address from the place details,
  // and then fill-in the corresponding field on the form.
  // place.address_components are google.maps.GeocoderAddressComponent objects
  // which are documented at http://goo.gle/3l5i5Mr
  for (const component of place.address_components) {
    // @ts-ignore remove once typings fixed
    const componentType = component.types[0];

    switch (componentType) {
      case "street_number": {
        address1 = `${component.long_name} ${address1}`;
        break;
      }

      case "route": {
        address1 += component.short_name;
        break;
      }

      case "postal_code": {
        postcode = `${component.long_name}${postcode}`;
        break;
      }

      case "postal_code_suffix": {
        postcode = `${postcode}-${component.long_name}`;
        break;
      }
      case "locality":
        document.querySelector("#locality").value = component.long_name;
        break;
      case "administrative_area_level_1": {
        document.querySelector("#state").value = component.short_name;
        break;
      }
      case "country":
        document.querySelector("#country").value = component.long_name;
        break;
    }
  }

  address1Field.value = address1;
  postalField.value = postcode;
  // After filling the form with address components from the Autocomplete
  // prediction, set cursor focus on the second address line to encourage
  // entry of subpremise information such as apartment, unit, or floor number.
  address2Field.focus();
}

window.initAutocomplete = initAutocomplete;

查看範例

自訂預留位置文字

根據預設,自動完成服務建立的文字欄位會包含標準預留位置文字。如要修改文字,請在 input 元素上設定 placeholder 屬性:

<input id="searchTextField" type="text" size="50" placeholder="Anything you want!">

注意:系統會自動將預設預留位置文字翻譯成當地語言。如果您指定自己的預留位置值,則必須在應用程式中處理這個值。如要進一步瞭解 Google Maps JavaScript API 如何選擇要使用的語言,請參閱本地化說明文件。

請參閱「設定自動完成和搜尋框方塊小工具」,以自訂小工具外觀。

SearchBox 可讓使用者執行文字搜尋功能,例如 ' New York New York (#39; New York in New York')。您可以將 SearchBox 附加到文字欄位中,隨著文字輸入,服務將以下拉式方式的形式傳回預測。

SearchBox 提供擴充的預測清單,其中可能包含 Places API (如 Places API 所定義) 和建議的搜尋字詞。舉例來說,如果使用者輸入「#39; in new in new'」,選項清單可能包含「#39; New York, NY'」這個詞組,以及各種披薩店的名稱。當使用者從清單中選取地點時,系統會將該地點的相關資訊傳回 SearchSearch 物件,並由應用程式擷取。

SearchBox 建構函式會採用兩個引數:

  • text 類型的 HTML input 元素。這是 SearchBox 服務要監控並附加結果的輸入欄位。
  • options 引數可包含 bounds 屬性:bounds 是一個 google.maps.LatLngBounds 物件,用來指定搜尋地點的區域。這些結果會偏向 (但不限於) 屬於這些邊界內的地點。

以下程式碼會使用 Bounds 參數,將結果限定於特定地理區域內的地點,透過經緯度座標指定。

var defaultBounds = new google.maps.LatLngBounds(
  new google.maps.LatLng(-33.8902, 151.1759),
  new google.maps.LatLng(-33.8474, 151.2631));

var input = document.getElementById('searchTextField');

var searchBox = new google.maps.places.SearchBox(input, {
  bounds: defaultBounds
});

變更 SearchBox 的搜尋區域

如要變更現有 SearchBox 的搜尋區域,請在 SearchBox 物件上呼叫 setBounds() 並傳遞相關的 LatLngBounds 物件。

查看範例

取得地點資訊

當使用者從搜尋框中附加的預測項目中選取項目時,服務會觸發 places_changed 事件。您可以在 SearchBox 物件上呼叫 getPlaces(),以擷取含有多個預測的陣列,每個預測都是 PlaceResult 物件。

如要進一步瞭解 PlaceResult 物件,請參閱地點詳細資料結果的說明文件。

TypeScript

// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener("places_changed", () => {
  const places = searchBox.getPlaces();

  if (places.length == 0) {
    return;
  }

  // Clear out the old markers.
  markers.forEach((marker) => {
    marker.setMap(null);
  });
  markers = [];

  // For each place, get the icon, name and location.
  const bounds = new google.maps.LatLngBounds();

  places.forEach((place) => {
    if (!place.geometry || !place.geometry.location) {
      console.log("Returned place contains no geometry");
      return;
    }

    const icon = {
      url: place.icon as string,
      size: new google.maps.Size(71, 71),
      origin: new google.maps.Point(0, 0),
      anchor: new google.maps.Point(17, 34),
      scaledSize: new google.maps.Size(25, 25),
    };

    // Create a marker for each place.
    markers.push(
      new google.maps.Marker({
        map,
        icon,
        title: place.name,
        position: place.geometry.location,
      })
    );

    if (place.geometry.viewport) {
      // Only geocodes have viewport.
      bounds.union(place.geometry.viewport);
    } else {
      bounds.extend(place.geometry.location);
    }
  });
  map.fitBounds(bounds);
});

JavaScript

// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener("places_changed", () => {
  const places = searchBox.getPlaces();

  if (places.length == 0) {
    return;
  }

  // Clear out the old markers.
  markers.forEach((marker) => {
    marker.setMap(null);
  });
  markers = [];

  // For each place, get the icon, name and location.
  const bounds = new google.maps.LatLngBounds();

  places.forEach((place) => {
    if (!place.geometry || !place.geometry.location) {
      console.log("Returned place contains no geometry");
      return;
    }

    const icon = {
      url: place.icon,
      size: new google.maps.Size(71, 71),
      origin: new google.maps.Point(0, 0),
      anchor: new google.maps.Point(17, 34),
      scaledSize: new google.maps.Size(25, 25),
    };

    // Create a marker for each place.
    markers.push(
      new google.maps.Marker({
        map,
        icon,
        title: place.name,
        position: place.geometry.location,
      })
    );
    if (place.geometry.viewport) {
      // Only geocodes have viewport.
      bounds.union(place.geometry.viewport);
    } else {
      bounds.extend(place.geometry.location);
    }
  });
  map.fitBounds(bounds);
});

查看範例

請參閱「設定自動完成和搜尋框方塊小工具」,以自訂小工具外觀。

透過程式輔助方式擷取 Place Autocomplete 服務預測

如要透過程式擷取預測結果,請使用 AutocompleteService 類別。AutocompleteService 不會新增任何 UI 控制項。而是會傳回預測物件陣列,每個物件都會包含預測文字、參考資料資訊,以及結果與使用者輸入內容相符結果的詳細資料。如果您想除了上述 AutocompleteSearchBox 提供的使用者介面外,還可以進一步控管使用者介面。

AutocompleteService 會公開下列方法:

  • getPlacePredictions() 會傳回地點預測。注意:&Places 39; Place' 可以是 Places API 定義的地點、地理位置或名勝地點。
  • getQueryPredictions() 會傳回擴充的預測清單,當中可能包含地點 (由 Places API 定義) 和建議搜尋字詞。舉例來說,如果使用者輸入「#39; in new in new'」,選項清單可能包含「' New York, NY'」這個詞組,以及各種披薩店的名稱。

上述兩種方法皆可傳回下列格式的預測物件陣列:

  • description 是相符的預測字串。
  • distance_meters 是與指定 AutocompletionRequest.origin 的地點距離 (單位為公尺)。
  • matched_substrings 提供的說明包含一組子字串,該字串符合使用者輸入內容中的子元素。這有助於在應用程式中醒目顯示這些子字串。在許多情況下,查詢會顯示為說明欄位的子字串。
    • length 是子字串的長度。
    • offset 是字元偏移,從說明字串的開頭開始測量,也就是相符子字串出現的位置。
  • place_id 是用來識別地點的文字 ID。如要擷取地點相關資訊,請在 Place Details 要求placeId 欄位中傳送這個 ID。進一步瞭解如何使用地點 ID 參照地點
  • terms 是包含查詢元素的陣列。以地點來說,每個元素通常都是由地址的一部分組成。
    • offset 是字元偏移,從說明字串的開頭開始測量,也就是相符子字串出現的位置。
    • value 是相符的字詞。

以下範例執行了「##99.披薩'披薩附近」的查詢預測要求,並在清單中顯示結果。

TypeScript

// This example retrieves autocomplete predictions programmatically from the
// autocomplete service, and displays them as an HTML list.
// This example requires the Places library. Include the libraries=places
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">
function initService(): void {
  const displaySuggestions = function (
    predictions: google.maps.places.QueryAutocompletePrediction[] | null,
    status: google.maps.places.PlacesServiceStatus
  ) {
    if (status != google.maps.places.PlacesServiceStatus.OK || !predictions) {
      alert(status);
      return;
    }

    predictions.forEach((prediction) => {
      const li = document.createElement("li");

      li.appendChild(document.createTextNode(prediction.description));
      (document.getElementById("results") as HTMLUListElement).appendChild(li);
    });
  };

  const service = new google.maps.places.AutocompleteService();

  service.getQueryPredictions({ input: "pizza near Syd" }, displaySuggestions);
}

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

JavaScript

// This example retrieves autocomplete predictions programmatically from the
// autocomplete service, and displays them as an HTML list.
// This example requires the Places library. Include the libraries=places
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">
function initService() {
  const displaySuggestions = function (predictions, status) {
    if (status != google.maps.places.PlacesServiceStatus.OK || !predictions) {
      alert(status);
      return;
    }

    predictions.forEach((prediction) => {
      const li = document.createElement("li");

      li.appendChild(document.createTextNode(prediction.description));
      document.getElementById("results").appendChild(li);
    });
  };

  const service = new google.maps.places.AutocompleteService();

  service.getQueryPredictions({ input: "pizza near Syd" }, displaySuggestions);
}

window.initService = initService;

CSS

HTML

<html>
  <head>
    <title>Retrieving Autocomplete 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>
    <p>Query suggestions for 'pizza near Syd':</p>
    <ul id="results"></ul>
    <!-- Replace Powered By Google image src with self hosted image. https://developers.google.com/maps/documentation/places/web-service/policies#other_attribution_requirements -->
    <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 callback 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
     with https://www.npmjs.com/package/@googlemaps/js-api-loader.
    -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initService&libraries=places&v=weekly"
      defer
    ></script>
  </body>
</html>

查看範例

查看範例

工作階段符記

AutocompleteService.getPlacePredictions() 會使用工作階段符記將帳單要求合併為帳單用途。為求計費,工作階段符記會將使用者自動完成搜尋的查詢和選取階段分組為不同的工作階段。工作階段會在使用者開始輸入查詢時開始,並在使用者選取地點時結束。每個工作階段可以有多個查詢,然後再選取一個地點。 工作階段結束後,權杖就不再有效。應用程式必須為各個工作階段產生新的權杖。建議您在所有自動完成工作階段中使用工作階段符記。如未提供 sessionToken 參數,或是重複使用工作階段符記,系統會將工作階段視為未提供工作階段符記,並分開計費。

您可以使用同一個工作階段符記,針對向 AutocompleteService.getPlacePredictions() 呼叫產生的地點發出單一 Place Details 要求。在這種情況下,自動完成要求會與 Place Details 要求相結合,而呼叫會按照一般 Place Details 要求計費。自動完成要求不會產生費用。

請務必為每個新工作階段傳遞不重複的工作階段符記。針對多個 Autocomplete 工作階段使用相同的權杖,會導致這些 Autocomplete 工作階段無效,而系統會透過 Autocomplete Per Request SKU 分別收取無效工作階段中的所有 Autocomplete 要求。進一步瞭解工作階段符記

下列範例說明如何建立工作階段符記,並將其傳入 AutocompleteService (為求簡潔,省略 displaySuggestions() 函式):

// Create a new session token.
var sessionToken = new google.maps.places.AutocompleteSessionToken();

// Pass the token to the autocomplete service.
var autocompleteService = new google.maps.places.AutocompleteService();
autocompleteService.getPlacePredictions({
  input: 'pizza near Syd',
  sessionToken: sessionToken
},
displaySuggestions);

請務必為每個新工作階段傳遞不重複的工作階段符記。如果為多個工作階段使用相同的權杖,將導致每個要求分開計費。

進一步瞭解工作階段符記

設定 Autocomplete 和 SearchBox 小工具樣式

根據預設,AutocompleteSearchBox 提供的 UI 元素會格式化在 Google 地圖上。建議您根據自己的網站調整樣式。您可以使用下列 CSS 類別。下列所有類別都適用於 AutocompleteSearchBox 小工具。

Autocomplete 和 SearchBox 小工具的 CSS 類別圖形插圖
自動完成和 SearchBox 小工具的 CSS 類別
CSS 類別 說明
pac-container 包含「地點自動完成」服務傳回的預測清單的視覺元素。這份清單會以下拉式清單的形式,顯示在 AutocompleteSearchBox 小工具下方。
pac-icon 顯示在預測項目清單中每個項目左側的圖示。
pac-item AutocompleteSearchBox 小工具提供的預測清單中的項目。
pac-item:hover 使用者滑鼠游標停留所在位置的項目。
pac-item-selected 使用者透過鍵盤選取的項目。注意事項:所選項目是這個類別和 pac-item 類別的成員。
pac-item-query pac-item 是預測範圍的主要部分。如為地理位置,則包含地點名稱 (例如 'Sydney') 或街道名稱與號碼 (例如 '10 King Street')。若是以文字進行搜尋,例如 ' New York in New York',其中包含查詢的完整文字。pac-item-query 的預設顏色為黑色,如果 pac-item 中有任何附加文字,則會超出 pac-item-query 並沿用 pac-item 的樣式。在預設情況下會以灰色顯示。其他文字通常是地址。
pac-matched 傳回的預測查詢字串中,與使用者輸入文字相符的部分。根據預設,這項相符文字會以粗體標示。請注意,相符文字可能位於 pac-item 中的任何位置。這不一定是 pac-item-query 的一部分,可能位於 pac-item-query 中,也可能部分包含在 pac-item 的其餘文字中。

地點自動完成最佳化

本節將說明最佳做法,協助您充分運用 Place Autocomplete 服務。

幾項通則如下:

  • 若想開發有效的使用者介面,最快的方法就是使用 Maps JavaScript API Autocomplete 小工具、Places SDK for Android Autocomplete 小工具或 Places SDK for iOS Autocomplete UI Control
  • 從一開始就瞭解重要的 Place Autocomplete 資料欄位
  • 位置偏誤和位置限制欄位為選填欄位,但對自動完成效能可能會有重大影響。
  • 使用錯誤處理機制,確保 API 傳回錯誤時,應用程式優雅降級。
  • 請確保在沒有選取項目的情況下,應用程式會處理,並為使用者提供繼續的方式。

成本最佳化最佳做法

基本費用最佳化

為了最佳化 Place Autocomplete 服務的使用費用,請使用 Place Details 和 Place Autocomplete 小工具中的欄位遮罩,只傳回您需要的地點資料欄位

進階費用最佳化

考慮以程式輔助的方式實作 Place Autocomplete 功能,以存取按請求計費,並針對所選地點 (而不是 Place Details) 要求 Geocoding API 結果。如果同時符合以下兩個條件,則與 Geocoding API 搭配使用的「按要求計費」價格較單次工作階段 (按工作階段) 定價更佳:

  • 如果您只需要使用者所選地點的經緯度,
  • 如果使用者在平均 4 個自動完成預測要求之間選取自動完成預測,則「每個要求」的定價可能會比「按工作階段的定價」更符合成本效益。
如要選取符合您需求的 Place Autocomplete 導入方式,請選取與下列問題答案對應的分頁標籤。

應用程式是否要求所選預測地址的地址和緯度以外的任何資訊?

是,我需要更多詳細資料

搭配工作階段詳細資料使用以工作階段為基礎的 Place Autocomplete 功能。
由於您的應用程式需要地點詳細資料 (例如地點名稱、商家狀態或營業時間),導入 Place Autocomplete 功能時,應使用工作階段符記 (程式輔助或內建於 JavaScriptAndroidiOS 小工具),通常費用為 $0.017 美元每個工作階段,以及適用的 Places Data SKU}}}

小工具實作
工作階段管理會自動內建至
JavaScriptAndroidiOS 小工具中。包含所選預測的 Place Autocomplete 要求和 Place Details 要求。請務必指定 fields 參數,確保只要求所需的地點資料欄位

程式輔助導入
將「工作階段符記」用於 Place Autocomplete 要求。要求所選預測的 Place Details 時,請加入下列參數:

  1. 地點自動完成回應的地點 ID
  2. 「地點自動完成」要求中使用的工作階段符記
  3. fields 參數會指定你需要的地點資料欄位

否,只需要提供地址和位置

視「地點自動完成」使用效能的效能而定,Geocoding API 的應用程式成本可能比「地點詳細資料」更具成本效益。每個應用程式的自動完成效率會因使用者輸入的內容、應用程式使用位置,以及是否導入效能最佳化最佳做法而異。

為了回答以下問題,請先在應用程式中分析使用者輸入的字元平均數量,然後再選取 Place Autocomplete 的預測功能。

平均來說,使用者會在四個或更少的要求中選取 Place Autocomplete 的預測功能?

以程式輔助方式實作 Place Autocomplete 功能,但不含工作階段符記,並在所選地點預測中呼叫 Geocoding API。
Geocoding API 針對要求和經緯度座標提供每個要求 $0.005 美元。發出四個 Place Autocomplete - Per Request 要求的費用為 $0.01132 美元,因此針對四個所選地點預測所發出的 Geocoding API 呼叫總費用為 $0.01632 美元,低於每個工作階段的每工作階段 $0.017 美元1

建議您採用成效最佳做法,讓使用者事半功倍。

搭配工作階段詳細資料使用以工作階段為基礎的 Place Autocomplete 功能。
由於使用者選取 Place Autocomplete 預測所需的平均要求數量,超出了每工作階段的費用,因此導入 Place Autocomplete 要求時,您必須同時使用工作階段符記和相關聯的 Place Details 要求,但每個工作階段的總費用為 $0.017 美元1

小工具實作
工作階段管理會自動內建至 JavaScriptAndroidiOS 小工具中。包含所選預測的 Place Autocomplete 要求和 Place Details 要求。請務必指定 fields 參數,確保您只要求 Basic Data 欄位。

程式輔助導入
將「工作階段符記」用於 Place Autocomplete 要求。要求所選預測的 Place Details 時,請加入下列參數:

  1. 地點自動完成回應的地點 ID
  2. 「地點自動完成」要求中使用的工作階段符記
  3. fields 參數,指定地址和幾何圖形等基本資料欄位

考慮延後 Place Autocomplete 要求
您可以利用策略來延遲 Place Autocomplete 要求,直到使用者輸入前 3 或 4 個半形字元時,再要求應用程式減少要求。舉例來說,在使用者輸入第三個字元「之後」,系統會為每個字元發出 Place Autocomplete 要求;也就是說,如果使用者輸入七個字元,然後選取收到一個 Geocoding API 要求的預測項目後,總費用為 $0.01632 美元 (4 * $0.00283 Autocomplete Per Request + $0.005 Geocoding)。1

如果延遲要求的平均程式輔助要求數量低於四則,請按照使用 Geocoding API 執行 Place Autocomplete 功能的指南操作。請注意,延遲要求可能會讓使用者感到期待,因為使用者可能會期望每次新按鍵都查看預測。

建議您採用效能最佳做法,協助使用者取得較少預測查詢字串。


  1. 這裡列出的費用是以美元計算。如需完整定價資訊,請參閱 Google 地圖平台計費方式頁面。

成效最佳做法

以下指南將說明最佳化 Place Autocomplete 成效的方法:

  • 為「地點自動完成」實作新增國家/地區限制、位置偏誤和 (適用於程式輔助實作) 語言偏好設定。小工具不需要使用者偏好設定,因為系統會從使用者瀏覽器或行動裝置中挑選語言偏好設定。
  • 如果 Place Autocomplete 功能附有地圖,您就可以根據地圖可視區域,偏誤位置。
  • 如果使用者未選擇其中一個自動完成預測功能,一般而言,由於這些預測作業都不是預期的結果地址,您可以重複使用原始使用者輸入內容,取得更相關的搜尋結果:
    • 如果您預期使用者只能輸入地址資訊,請在 Geocoding API 呼叫中重複使用原始的使用者輸入內容。
    • 如果您預期使用者可透過名稱或地址輸入特定地點的查詢內容,請使用「尋找地點」要求。 如果希望只在特定區域取得結果,請使用位置偏誤功能。
    但最適合使用 Geocoding API 的其他情境包括:
    • 使用者輸入澳洲、紐西蘭或加拿大以外的國家/地區。舉例來說,自動完成功能不支援美國地址「123 Bowdoin St #456, Boston MA, USA"」。(自動完成功能僅支援澳洲、紐西蘭和加拿大的子公司位址。這三種國家/地區支援的地址格式包括「91321 Pitt Street, Sydney, New South Wales, Australia」或「14/19 Langana Avenue, Browns Bay, Auckland, New Zealand」或「145-112 Renfrew Dr, Markham, Ontario, Canada&」
    • 使用者輸入的地址含有地址區隔前置字串,例如「11-20 29th St, Queens」(位於紐約市,臺北市中正區或臺北市中正區路四段 47-380 號),這組目的地包括位於夏威夷考奈島 (Kaaiai)。

使用限制和政策

配額

如需配額與定價資訊,請參閱 Places API 的使用情形與帳單說明文件

政策

使用 Places Library、Maps JavaScript API 時,必須遵守 Places API 所製定的政策

根據我們的《服務條款》

顯示必要的
標誌和出處

尊重 Google 的版權與歸因分析。請確保標誌和版權聲明皆可見,並在沒有地圖的情況下使用「由 Google 技術提供」標誌。

瞭解詳情