Places Library

總覽

透過 Maps JavaScript API Places Library 中的函式,應用程式可以搜尋位於指定區域的地點。例如在地圖邊界內或定點周圍,尋找建築物、地理位置或重要搜尋點 (此為本 API 對於「地點」的定義)。

Places API 提供自動完成功能,應用程式導入後,即可在 Google 地圖搜尋欄位預先完成查詢字串。使用者只要輸入地址開頭,自動完成功能便會填入剩餘部分。詳情請參閱自動完成說明文件

開始使用

如果您不熟悉 Maps JavaScript API 或 JavaScript,建議先瞭解 JavaScript 及取得 API 金鑰,再開始使用。

啟用 API

請先到 Google Cloud 控制台,確認同一個針對 Maps JavaScript API 設定的專案已啟用 Places API,然後再開始使用 Maps JavaScript API Places Library。

如要查看已啟用的 API 清單,請按照下列步驟操作:

  1. 前往 Google Cloud 控制台
  2. 按一下「Select a project」(選取專案) 按鈕,選取您為 Maps JavaScript API 設定的同一專案,然後點選「Open」(開啟)
  3. 在「Dashboard」(資訊主頁) 的 API 清單中,找出 Places API
  4. 如果 Places API 顯示在清單中,就表示已啟用。如果「沒有」看到這個 API,請按照下列步驟啟用:
    1. 選取頁面頂端的「ENABLE APIS AND SERVICES」(啟用 API 和服務),即會顯示「Library」(程式庫) 分頁。您也可以從左側選單中選取「Library」(程式庫)
    2. 搜尋「Places API」,然後從結果清單中選取該 API。
    3. 選取「ENABLE」(啟用)。這個程序完成後,「Dashboard」(資訊主頁) 的 API 清單就會顯示「Places API」

載入程式庫

地點介面集服務是獨立程式庫,不包含在主要的 Maps JavaScript API 程式碼。如要使用這個程式庫中的功能,您必須先在 Maps API Bootstrap 網址中使用 libraries 參數載入程式庫:

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

詳情請參閱「程式庫總覽」一文。

將 Places API 加進 API 金鑰的 API 限制清單

金鑰套用 API 限制後,只有特定幾個 API 或 SDK 可以使用 API 金鑰。如果接收要求的 API 或 SDK 與 API 金鑰相關聯,系統就會處理要求。如果接收要求的 API 或 SDK 與 API 金鑰沒有關聯,要求就會失敗。如要將 API 金鑰設為只能搭配 Maps JavaScript API Places Library 使用,請按照下列步驟操作:
  1. 前往 Google Cloud 控制台
  2. 按一下專案下拉式選單,然後選取要鎖定的 API 金鑰所屬的專案。
  3. 按一下選單按鈕 ,然後依序選取「Google Maps Platform」(Google 地圖平台) >「Credentials」(憑證)
  4. 在「Credentials」(憑證) 頁面上,按一下要保護的 API 金鑰名稱。
  5. 在「Restrict and rename API key」(限制並重新命名 API 金鑰) 頁面上設定限制:
    • API 限制
      • 選取「Restrict key」(限制金鑰)
      • 按一下「Select APIs」(選取 API),然後同時選取「Maps JavaScript API」和「Places API」
        (如果選單未列出您需要的 API,請啟用該 API。)
  6. 按一下「SAVE」(儲存)

用量限制和政策

配額

如同 Places API 的「用量限制」說明文件所述,Places Library 會與 Places API 共用用量配額。

政策

使用 Maps JavaScript API Places Library 時,必須遵守 Places API 適用的現行政策

地點搜尋

您可以透過地點介面集服務執行以下類型的搜尋:

傳回的資訊可以是建築物 (例如餐廳、商店和辦公室),以及「地理編碼」結果,也就是地址、行政區域 (市區鄉鎮) 和其他搜尋點。

Find Place 要求

Find Place 要求可讓您透過文字查詢或電話號碼搜尋地點。Find Place 要求分為兩種類型:

透過查詢尋找地點

「透過查詢尋找地點」會根據文字輸入內容傳回地點。輸入內容可以是任何類型的地點資料,例如商家名稱或地址。如要提出「透過查詢尋找地點」要求,請呼叫 PlacesServicefindPlaceFromQuery() 方法,該方法會採用下列參數:

  • query (必要):要搜尋的文字字串,例如「餐廳」或「中正路 123 號」。這必須是地點名稱、地址或建築物類別。任何其他類型的輸入內容都可能會產生錯誤,不保證會傳回有效的結果。Places API 會根據這個字串傳回候選相符項目,並會依據觀察到的關聯性排序結果。
  • fields (必要):一或多個欄位,用於指定要傳回的地點資料類型。
  • locationBias (選用):用於定義搜尋區域的座標,可以是下列其中一項:

您也必須傳遞回呼方法至 findPlaceFromQuery(),以便處理結果物件和 google.maps.places.PlacesServiceStatus 回應。

下例是對 findPlaceFromQuery() 的呼叫,搜尋的是「澳洲當代藝術博物館」,且包含 namegeometry 欄位。

var map;
var service;
var infowindow;

function initMap() {
  var sydney = new google.maps.LatLng(-33.867, 151.195);

  infowindow = new google.maps.InfoWindow();

  map = new google.maps.Map(
      document.getElementById('map'), {center: sydney, zoom: 15});

  var request = {
    query: 'Museum of Contemporary Art Australia',
    fields: ['name', 'geometry'],
  };

  var service = new google.maps.places.PlacesService(map);

  service.findPlaceFromQuery(request, function(results, status) {
    if (status === google.maps.places.PlacesServiceStatus.OK) {
      for (var i = 0; i < results.length; i++) {
        createMarker(results[i]);
      }
      map.setCenter(results[0].geometry.location);
    }
  });
}
敬上 查看範例

透過電話號碼尋找地點

「透過電話號碼尋找地點」需要採用電話號碼並傳回地點。如要提出「透過電話號碼尋找地點」要求,請呼叫 PlacesServicefindPlaceFromPhoneNumber() 方法,該方法會採用下列參數:

  • phoneNumber (必要):電話號碼,格式為 E.164
  • fields (必要):一或多個欄位,用於指定要傳回的地點資料類型。
  • locationBias (選用):用於定義搜尋區域的座標,可以是下列其中一項:

您也必須傳遞回呼方法至 findPlaceFromPhoneNumber(),以便處理結果物件和 google.maps.places.PlacesServiceStatus 回應。

欄位 (Find Place 方法)

使用 fields 參數指定要傳回的地點資料類型陣列,例如:fields: ['formatted_address', 'opening_hours', 'geometry']。指定複合值時,請使用半形句號,例如:opening_hours.weekday_text

欄位會與 Place Search 結果相對應,並分為三種計費類別:「Basic」、「Contact」和「Atmosphere」。「Basic」欄位以基本費率計費,不會產生額外費用。「Contact」和「Atmosphere」欄位會以較高的費率計費。詳情請參閱價目表。無論是否要求作者資訊欄位,每次呼叫一律都會傳回作者資訊 (html_attributions)。

Basic

「Basic」類別包含下列欄位:
business_statusformatted_addressgeometryiconicon_mask_base_uriicon_background_colornamepermanently_closed (已淘汰)、photosplace_idplus_codetypes

Contact

「Contact」類別包含以下欄位: opening_hours
(已於 Maps JavaScript API Places Library 中淘汰。請使用 Place Details 要求取得 opening_hours 結果)。

Atmosphere

「Atmosphere」類別包含下列欄位: price_levelratinguser_ratings_total

findPlaceFromQuery()findPlaceFromPhoneNumber() 方法都採用同一組欄位,且可能會在各自的回應中傳回相同欄位。

位置自訂調整設定 (Find Place 方法)

使用 locationBias 參數,即可讓 Find Place 優先顯示特定區域中的結果。您可以按照下列方式設定 locationBias

針對特定區域調整結果:

locationBias: {lat: 37.402105, lng: -122.081974}

定義要搜尋的矩形區域:

locationBias: {north: 37.41, south: 37.40, east: -122.08, west: -122.09}

您也可以使用 LatLngBounds

定義要搜尋的半徑 (以公尺為單位),以特定區域為中心:

locationBias: {radius: 100, center: {lat: 37.402105, lng: -122.081974}}

「搜尋附近」要求

「搜尋附近」可讓您依照關鍵字或類型,搜尋指定區域內的地點。「搜尋附近」必須一律包含位置,可透過以下任一方法指定:

  • LatLngBounds
  • 使用 location 屬性 (將圓心指定為 LatLng 物件) 與半徑 (以公尺為單位) 的組合定義圓形區域。

如要啟動「附近地點」搜尋,您必須呼叫 PlacesServicenearbySearch() 方法,傳回 PlaceResult 物件的陣列。請注意,自 3.9 版起,nearbySearch() 方法會取代 search() 方法。

service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, callback);

這個方法可接收包含下列欄位的要求:

  • 下列任一項:
    • bounds,必須是 定義矩形的 google.maps.LatLngBounds 物件 搜尋區域邊界支援的最長對角線距離 大約有 100,000 公尺
    • locationradius:前者需要採用 google.maps.LatLng 物件,後者需要採用簡單整數,代表圓形的半徑 (以公尺為單位)。最大值 允許的半徑為 50,000 公尺請注意,當 rankBy 設為 DISTANCE 時,您必須指定 location,但無法指定 radiusbounds
  • keyword (選用):要與所有可用欄位比對的字詞,包括但不限於名稱、類型、地址、客戶評論以及其他第三方內容。
  • minPriceLevelmaxPriceLevel (選用):限制系統只傳回指定範圍內的結果。有效值介於 0 (最便宜) 和 4 (最昂貴),含首尾兩值。
  • name:已淘汰,等同於 keyword。這個欄位的值會與 keyword 欄位的值合併,並做為同一個搜尋字串的一部分傳送。
  • openNow (選用):是一個布林值,表示地點介面集服務只能傳回在查詢當下營業中的地點。如果您在查詢中加入這個參數,系統就不會傳回未於 Google 地點介面集資料庫中指定營業時間的地點。將 openNow 設為 false 不會產生任何影響。
  • rankBy (選用):指定結果的排列順序。可能的值包括:
    • google.maps.places.RankBy.PROMINENCE (預設)。這個選項會根據重要性排列結果。系統會優先列出指定半徑範圍內的知名地點,而非相符但較不知名的附近地點。知名度可能會受到 Google 索引中的地點排名、全球熱門程度和其他因素影響。如果指定 google.maps.places.RankBy.PROMINENCE,則必須提供 radius 參數。
    • google.maps.places.RankBy.DISTANCE:這個選項會依照地點與指定 location (必要) 之間的距離,以遞增順序排列結果。請注意,如果指定 RankBy.DISTANCE,則無法指定自訂 bounds 和/或 radius。如果指定 RankBy.DISTANCE,則必須提供一或多個 keywordnametype
  • type:讓系統在結果中只顯示符合指定類型的地點。您只能指定一種類型 (如果提供多種類型,系統會忽略第一種類型之後輸入的所有類型)。請參閱支援類型清單

您也必須傳遞回呼方法至 nearbySearch(),以便處理結果物件和 google.maps.places.PlacesServiceStatus 回應。

var map;
var service;
var infowindow;

function initialize() {
  var pyrmont = new google.maps.LatLng(-33.8665433,151.1956316);

  map = new google.maps.Map(document.getElementById('map'), {
      center: pyrmont,
      zoom: 15
    });

  var request = {
    location: pyrmont,
    radius: '500',
    type: ['restaurant']
  };

  service = new google.maps.places.PlacesService(map);
  service.nearbySearch(request, callback);
}

function callback(results, status) {
  if (status == google.maps.places.PlacesServiceStatus.OK) {
    for (var i = 0; i < results.length; i++) {
      createMarker(results[i]);
    }
  }
}

查看範例

「搜尋文字」要求

Google 地點介面集「搜尋文字」服務是一項網路服務,可根據字串 (例如「台南魯肉飯」或「西門町附近的鞋店」) 傳回一組地點。這項服務會傳回與文字字串和任何位置自訂調整設定相符的地點清單。搜尋回應會包含一份地點清單。您可以傳送 Place Details 要求,索取回應中任何地點的詳細資訊。

如要啟動「搜尋文字」,您必須呼叫 PlacesServicetextSearch() 方法。

service = new google.maps.places.PlacesService(map);
service.textSearch(request, callback);

這個方法可接收包含下列欄位的要求:

  • query (必要):要搜尋的文字字串,例如「餐廳」或「中正路 123 號」。這必須是地點名稱、地址或建築物類別。任何其他類型的輸入內容都可能會產生錯誤,不保證會傳回有效的結果。地點介面集服務會根據這個字串傳回候選相符項目,並會依據觀察到的關聯性排序結果。如果搜尋要求中也使用 type 參數,這個參數會成為選用項目。
  • 可選用:
    • openNow:是一個布林值,表示地點介面集服務只能傳回在查詢當下營業中的地點。如果您在查詢中加入這個參數,系統就不會傳回未於 Google 地點介面集資料庫中指定營業時間的地點。將 openNow 設為 false 不會產生任何影響。
    • minPriceLevelmaxPriceLevel:限制系統只傳回指定價格範圍內的地點。有效值介於 0 (最便宜) 和 4 (最昂貴),含首尾。
    • 下列任一項:
      • bounds,必須是 定義矩形的 google.maps.LatLngBounds 物件 搜尋區域邊界支援的最長對角線距離 大約有 100,000 公尺
      • locationradius:您可以傳送 locationradius 參數,針對特定圓形範圍調整結果。這樣就能指示地點介面集服務優先顯示該圓形範圍內的結果。不過,系統還是有可能會顯示定義區域外的結果。位置需要採用 google.maps.LatLng 物件,半徑需要採用簡單整數,代表圓形的半徑 (以公尺為單位)。允許的最大半徑為 50,000 公尺。
    • type:讓系統在結果中只顯示符合指定類型的地點。您只能指定一種類型 (如果提供多種類型,系統會忽略第一種類型之後輸入的所有類型)。請參閱支援類型清單

您也必須傳遞回呼方法至 textSearch(),以便處理結果物件和 google.maps.places.PlacesServiceStatus 回應。

var map;
var service;
var infowindow;

function initialize() {
  var pyrmont = new google.maps.LatLng(-33.8665433,151.1956316);

  map = new google.maps.Map(document.getElementById('map'), {
      center: pyrmont,
      zoom: 15
    });

  var request = {
    location: pyrmont,
    radius: '500',
    query: 'restaurant'
  };

  service = new google.maps.places.PlacesService(map);
  service.textSearch(request, callback);
}

function callback(results, status) {
  if (status == google.maps.places.PlacesServiceStatus.OK) {
    for (var i = 0; i < results.length; i++) {
      var place = results[i];
      createMarker(results[i]);
    }
  }
}

搜尋回應

狀態碼

PlacesServiceStatus 回應物件除了內含要求的狀態之外,還可能包含偵錯資訊,方便您追查地點搜尋要求失敗的原因。可能的狀態值如下:

  • INVALID_REQUEST:這個要求無效。
  • OK:回應包含有效的結果。
  • OVER_QUERY_LIMIT:網頁超出要求配額。
  • REQUEST_DENIED:不允許這個網頁使用 PlacesService。
  • UNKNOWN_ERROR:發生伺服器錯誤,無法處理 PlacesService 要求。如果再試一次,要求可能會成功。
  • ZERO_RESULTS:找不到這項要求的結果。

Place Search 結果

findPlace()nearbySearch()textSearch() 函式會傳回 PlaceResult 物件的陣列。

每個 PlaceResult 物件可能都包含下列屬性:

  • business_status 表示地點的營業狀態 (如果地點為商家),且可能包含下列其中一個值:
    • OPERATIONAL
    • CLOSED_TEMPORARILY
    • CLOSED_PERMANENTLY
    如果沒有任何資料,則不會傳回 business_status
  • formatted_address 字串包含這個地點的清楚易懂地址。只有「搜尋文字」要求才會傳回 formatted_address 屬性。

    這個地址通常等於郵寄地址。請注意,由於授權上的限制,部分國家/地區 (例如英國) 不允許散布真實的郵寄地址。

    理論上,格式化地址是由一或多個「地址元件」組成。舉例來說,「111 8th Avenue, New York, NY」這個地址包含以下元件:「111」(門牌號碼)、「8th Avenue」(路名)、「New York」(城市) 和「NY」(美國州名)。

    請勿以程式輔助方式剖析格式化地址。建議您改用個別地址元件,API 回應除了包含格式化地址欄位之外,也會包含這些元件。

  • geometry:地點的幾何圖形相關資訊,包括:
    • location 會提供地點的經緯度。
    • viewport 會定義查看這個地點時,地圖上優先使用的可視區域。
  • permanently_closed (已淘汰) 是一個布林值標記,指出地點是永久或暫時關閉 (值 true)。請勿使用 permanently_closed,建議改用 business_status 取得商家的營業狀態。
  • plus_code (請參閱「Open Location Code」和「Plus Codes」) 是經過編碼的位置參照,衍生自經緯度座標,表示面積不超過 1/8000 度 x 1/8000 度 (在赤道區約 14 公尺 x 14 公尺) 的區域。對於沒有詳細地址的地點,Plus Codes 可用於取代街道地址,例如無編號的建築物或無名街道。

    Plus Code 格式包含全球代碼和複合代碼:

    • global_code 是 4 個字元的區碼,加上 6 個字元以上的當地代碼 (849VCWC8+R9)。
    • compound_code 是 6 個字元以上的當地代碼,加上明確的位置 (CWC8+R9, Mountain View, CA, USA)。請勿以程式輔助方式剖析這個內容。
    系統通常會同時傳回全球代碼和複合代碼。不過,如果結果是在偏遠位置 (例如海洋或沙漠),系統可能只會傳回全球代碼。
  • html_attributions:顯示搜尋結果時,您應一併顯示的作者資訊陣列。陣列中的每個項目都包含以 HTML 文字呈現的單一作者資訊。注意:這是整個搜尋回應的所有作者資訊匯總結果。因此回應中的所有 PlaceResult 物件皆包含相同的作者資訊清單。
  • icon 會傳回 71 像素 x 71 像素 PNG 彩色圖示的網址。
  • icon_mask_base_uri 會傳回非彩色圖示的基準網址 (刪除 .svg 或 .png 副檔名)。
  • icon_background_color 會傳回地點類別的預設十六進位顏色代碼。
  • name:地點的名稱。
  • opening_hours 可能包含下列資訊:
    • open_now 是一個布林值,指出地點目前是否營業中 (在 Maps JavaScript API Places Library 中已淘汰,請改用 utc_offset_minutes)。
  • place_id 是用來識別特定地點的文字 ID。如要擷取地點資訊,請在 Place Details 要求中傳遞這個 ID。進一步瞭解如何使用地點 ID 參照地點
  • rating 包含地點評分 (0.0 到 5.0,根據綜合使用者評論計算)。
  • types:這個地點的類型陣列 (例如 ["political", "locality"]["restaurant", "lodging"])。這個陣列可能包含多個值,也可能為空白。我們可能會在未事先通知的情況下導入新值。請參閱支援類型清單。
  • vicinity:地點的簡化地址,包括街道名稱、門牌號碼和縣市,但不含省/州、郵遞區號或國家/地區。舉例來說,Google 澳洲雪梨辦公室的 vicinity 值為 5/48 Pirrama Road, Pyrmont

取得其他結果

根據預設,每次搜尋地點時,每項查詢最多只能傳回 20 筆結果。不過,每次搜尋能傳回多達 60 筆結果,分別顯示在三個網頁中。您可以透過 PlaceSearchPagination 物件查看其他網頁。如要存取其他網頁,您必須透過回呼函式擷取 PlaceSearchPagination 物件。PlaceSearchPagination 物件的定義為:

  • hasNextPage 是一個布林值屬性,指出是否還有其他結果。有其他結果網頁時,值為 true
  • nextPage() 是會傳回下一組結果的函式。執行搜尋後,請等候兩秒鐘,系統才會顯示下一頁的結果。

如要查看下一組結果,請呼叫 nextPage。系統必須先顯示目前這一頁的結果,才能顯示下一頁的結果。請注意,每次搜尋都會計為用量限制中的一次要求。

以下示範如何更改回呼函式來擷取 PlaceSearchPagination 物件,以便發出多項搜尋要求。

TypeScript

// 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 initMap(): void {
  // Create the map.
  const pyrmont = { lat: -33.866, lng: 151.196 };
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      center: pyrmont,
      zoom: 17,
      mapId: "8d193001f940fde3",
    } as google.maps.MapOptions
  );

  // Create the places service.
  const service = new google.maps.places.PlacesService(map);
  let getNextPage: () => void | false;
  const moreButton = document.getElementById("more") as HTMLButtonElement;

  moreButton.onclick = function () {
    moreButton.disabled = true;

    if (getNextPage) {
      getNextPage();
    }
  };

  // Perform a nearby search.
  service.nearbySearch(
    { location: pyrmont, radius: 500, type: "store" },
    (
      results: google.maps.places.PlaceResult[] | null,
      status: google.maps.places.PlacesServiceStatus,
      pagination: google.maps.places.PlaceSearchPagination | null
    ) => {
      if (status !== "OK" || !results) return;

      addPlaces(results, map);
      moreButton.disabled = !pagination || !pagination.hasNextPage;

      if (pagination && pagination.hasNextPage) {
        getNextPage = () => {
          // Note: nextPage will call the same handler function as the initial call
          pagination.nextPage();
        };
      }
    }
  );
}

function addPlaces(
  places: google.maps.places.PlaceResult[],
  map: google.maps.Map
) {
  const placesList = document.getElementById("places") as HTMLElement;

  for (const place of places) {
    if (place.geometry && place.geometry.location) {
      const image = {
        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),
      };

      new google.maps.Marker({
        map,
        icon: image,
        title: place.name!,
        position: place.geometry.location,
      });

      const li = document.createElement("li");

      li.textContent = place.name!;
      placesList.appendChild(li);

      li.addEventListener("click", () => {
        map.setCenter(place.geometry!.location!);
      });
    }
  }
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;
敬上

JavaScript

// 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 initMap() {
  // Create the map.
  const pyrmont = { lat: -33.866, lng: 151.196 };
  const map = new google.maps.Map(document.getElementById("map"), {
    center: pyrmont,
    zoom: 17,
    mapId: "8d193001f940fde3",
  });
  // Create the places service.
  const service = new google.maps.places.PlacesService(map);
  let getNextPage;
  const moreButton = document.getElementById("more");

  moreButton.onclick = function () {
    moreButton.disabled = true;
    if (getNextPage) {
      getNextPage();
    }
  };

  // Perform a nearby search.
  service.nearbySearch(
    { location: pyrmont, radius: 500, type: "store" },
    (results, status, pagination) => {
      if (status !== "OK" || !results) return;

      addPlaces(results, map);
      moreButton.disabled = !pagination || !pagination.hasNextPage;
      if (pagination && pagination.hasNextPage) {
        getNextPage = () => {
          // Note: nextPage will call the same handler function as the initial call
          pagination.nextPage();
        };
      }
    },
  );
}

function addPlaces(places, map) {
  const placesList = document.getElementById("places");

  for (const place of places) {
    if (place.geometry && place.geometry.location) {
      const image = {
        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),
      };

      new google.maps.Marker({
        map,
        icon: image,
        title: place.name,
        position: place.geometry.location,
      });

      const li = document.createElement("li");

      li.textContent = place.name;
      placesList.appendChild(li);
      li.addEventListener("click", () => {
        map.setCenter(place.geometry.location);
      });
    }
  }
}

window.initMap = initMap;
敬上
查看範例

測試範例程式碼

Place Details

除了提供某區域內的地點清單之外,地點介面集服務也會傳回特定地點的詳細資訊。Place Search 回應中傳回地點後,您就可以使用其中的地點 ID 來要求該地點的其他詳細資料,例如完整地址、電話號碼、使用者評分和評論等。

Place Details 要求

如要提出 Place Details 要求,您必須呼叫服務的 getDetails() 方法。

service = new google.maps.places.PlacesService(map);
service.getDetails(request, callback);

這個方法可接收要求,其中包含所需地點的 placeId,以及用於指出要傳回哪幾類地點資料的欄位。進一步瞭解如何使用地點 ID 參照地點

這個方法也接受回呼方法,這需要處理 google.maps.places.PlacesServiceStatus 回應中所傳遞的狀態碼,以及 google.maps.places.PlaceResult 物件。

var request = {
  placeId: 'ChIJN1t_tDeuEmsRUsoyG83frY4',
  fields: ['name', 'rating', 'formatted_phone_number', 'geometry']
};

service = new google.maps.places.PlacesService(map);
service.getDetails(request, callback);

function callback(place, status) {
  if (status == google.maps.places.PlacesServiceStatus.OK) {
    createMarker(place);
  }
}

查看範例

欄位 (Place Details)

fields 參數需要採用字串陣列 (欄位名稱)。

使用 fields 參數指定要傳回的地點資料類型陣列,例如:fields: ['address_components', 'opening_hours', 'geometry']。指定複合值時,請使用半形句號,例如:opening_hours.weekday_text

欄位會與 Place Details 結果相對應,並分為三種計費類別:「Basic」、「Contact」和「Atmosphere」。「Basic」欄位以基本費率計費,不會產生額外費用。「Contact」和「Atmosphere」欄位會以較高的費率計費。詳情請參閱價目表。無論是否要求作者資訊欄位,每次呼叫一律都會傳回作者資訊 (html_attributions)。

Basic

「Basic」類別包含下列欄位:
address_componentsadr_addressbusiness_statusformatted_addressgeometryiconicon_mask_base_uriicon_background_colornamepermanently_closed (已淘汰)、photoplace_idplus_codetypeurlutc_offset (在 Maps JavaScript API Places Library 中已淘汰)、utc_offset_minutesvicinity

Contact

「Contact」類別包含下列欄位:
formatted_phone_numberinternational_phone_numberopening_hourswebsite

Atmosphere

「Atmosphere」類別包含下列欄位:price_levelratingreviewsuser_ratings_total

進一步瞭解地點欄位。如要進一步瞭解地點資料要求的計費方式,請參閱「用量與計費」一文。

Place Details 回應

狀態碼

PlacesServiceStatus 回應物件除了內含要求的狀態之外,還可能包含偵錯資訊,方便您追查 Place Details 要求失敗的原因。可能的狀態值如下:

  • INVALID_REQUEST:這個要求無效。
  • OK:回應包含有效的結果。
  • OVER_QUERY_LIMIT:網頁超出要求配額。
  • NOT_FOUND:在地點介面集資料庫中找不到參照的位置。
  • REQUEST_DENIED:不允許這個網頁使用 PlacesService。
  • UNKNOWN_ERROR:發生伺服器錯誤,無法處理 PlacesService 要求。如果再試一次,要求可能會成功。
  • ZERO_RESULTS:找不到這項要求的結果。

Place Details 結果

如果 getDetails() 呼叫成功,會傳回 PlaceResult 物件,且包含下列屬性:

  • address_components:這個陣列包含這個地址適用的各種元件。

    每個地址元件通常會包含下列欄位:

    • types[] 是一個陣列,用來指出地址元件的「類型」。請參閱支援類型清單。
    • long_name 是地理編碼器所傳回地址元件的完整文字說明或名稱。
    • short_name 是地址元件的縮寫文字名稱 (如有)。舉例來說,阿拉斯加州地址元件的 long_name 可能為「Alaska」,而 short_name 則為 2 個字母的郵政簡碼「AK」。

    address_components[] 陣列的注意事項如下:

    • 地址元件陣列包含的元件可能比 formatted_address 更多。
    • 除了 formatted_address 中所含的政治實體以外,這個陣列不一定會納入內含地址的所有政治實體。如要擷取包含特定地址的所有政治實體,建議您使用反向地理編碼,將地址的經緯度做為參數傳遞至要求。
    • 兩次要求之間的回應格式不一定相同。特別是,address_components 的數量會因要求的地址而異,對於同一個地址,數量也可能會隨時間改變。元件在陣列中的位置可能會變更。元件類型也可能會變更。後續回應中可能會缺少特定元件。
  • business_status 表示地點的營業狀態 (如果地點為商家),且可能包含下列其中一個值:
    • OPERATIONAL
    • CLOSED_TEMPORARILY
    • CLOSED_PERMANENTLY
    如果沒有任何資料,則不會傳回 business_status
  • formatted_address:這個地點清楚易懂的地址。

    這個地址通常等於郵寄地址。請注意,由於授權上的限制,部分國家/地區 (例如英國) 不允許散布真實的郵寄地址。

    理論上,格式化地址是由一或多個「地址元件」組成。舉例來說,「111 8th Avenue, New York, NY」這個地址包含以下元件:「111」(門牌號碼)、「8th Avenue」(路名)、「New York」(城市) 和「NY」(美國州名)。

    請勿以程式輔助方式剖析格式化地址。建議您改用個別地址元件,API 回應除了包含格式化地址欄位之外,也會包含這些元件。

  • formatted_phone_number:地點的電話號碼,格式取決於號碼的地方慣例
  • geometry:地點的幾何圖形相關資訊,包括:
    • location 會提供地點的經緯度。
    • viewport 會定義查看這個地點時,地圖上優先使用的可視區域。
  • permanently_closed (已淘汰) 是一個布林值標記,指出地點是永久或暫時關閉 (值 true)。請勿使用 permanently_closed,建議改用 business_status 取得商家的營業狀態。
  • plus_code (請參閱「Open Location Code」和「Plus Codes」) 是經過編碼的位置參照,衍生自經緯度座標,表示面積不超過 1/8000 度 x 1/8000 度 (在赤道區約 14 公尺 x 14 公尺) 的區域。對於沒有詳細地址的地點,Plus Codes 可用於取代街道地址,例如無編號的建築物或無名街道。

    Plus Code 格式包含全球代碼和複合代碼:

    • global_code 是 4 個字元的區碼,加上 6 個字元以上的當地代碼 (849VCWC8+R9)。
    • compound_code 是 6 個字元以上的當地代碼,加上明確的位置 (CWC8+R9, Mountain View, CA, USA)。請勿以程式輔助方式剖析這個內容。
    系統通常會同時傳回全球代碼和複合代碼。不過,如果結果是在偏遠位置 (例如海洋或沙漠),系統可能只會傳回全球代碼。
  • html_attributions:這個地點結果所要顯示的作者資訊文字。
  • icon:可用來代表這個地點類型的圖片資源網址。
  • international_phone_number 包含地點的電話號碼 (國際格式)。國際電話號碼格式包含國碼,且前置字元為加號 (+)。舉例來說,Google 澳洲雪梨辦公室的 international_phone_number+61 2 9374 4000
  • name:地點的名稱。
  • utc_offset:在 Maps JavaScript API Places Library 中已淘汰,請改用 utc_offset_minutes
  • utc_offset_minutes 包含地點目前時區與世界標準時間之間相差的分鐘數。舉例來說,澳洲雪梨當地在日光節約時間應該是 660 (世界標準時間 +11 個小時),而美國加州當地非日光節約時間應該是 -480 (世界標準時間 -8 個小時)。
  • opening_hours 包含下列資訊:
    • open_now (在 Maps JavaScript API Places Library 中已淘汰,請改用 opening_hours.isOpen(),如要瞭解如何搭配 Place Details 使用 isOpen,請觀看這部影片) 是一個布林值,指出地點目前是否營業中。
    • periods[] 是涵蓋 7 天的營業時段陣列,從週日開始,按時間順序排列。每個時段都包含:
      • open 包含一組日期和時間物件,用來描述地點的營業時間:
        • day 是從 0 到 6 之間的數字,分別代表星期幾 (以週日做為每週起始日)。例如,2 表示週二。
        • time 可能包含 24 小時 hhmm 格式的時間 (值的範圍從 0000 到 2359)。系統回報的 time 是以地點的時區為準。
      • close 可能包含一組日期和時間物件,用來描述地點的休息時間。注意:如果地點全年無休,回應中會缺少 close 部分。如果應用程式要表示「全年無休」,可以將 open 時間中 day 的值設為 0,time 的值設為 0000,且不含 close
    • weekday_text 是包含七個字串的陣列,以特定格式表示一週內每天的營業時間。如果 Place Details 要求中指定 language 參數,則地點介面集服務會配合該語言調整營業時間格式,並將時間本地化。這個陣列中的元素順序取決於 language 參數。有些語言是以週一做為每週起始日,有些則是週日。
  • permanently_closed (已淘汰) 是一個布林值標記,指出地點是永久或暫時關閉 (值 true)。請勿使用 permanently_closed,建議改用 business_status 取得商家的營業狀態。
  • photos[]PlacePhoto 物件的陣列。您可以透過 getUrl() 方法使用 PlacePhoto 取得相片,也可以檢查物件是否具有以下值:
    • height:圖片的高度上限,以像素為單位。
    • width:圖片的寬度上限,以像素為單位。
    • html_attributions:要在這張地點相片中顯示的作者資訊文字。
  • place_id:用來識別特定地點的文字 ID,並可用於透過 Place Details 要求擷取地點資訊。進一步瞭解如何使用地點 ID 參照地點
  • rating:地點評分 (0.0 到 5.0,根據綜合使用者評論計算)。
  • reviews 最多包含 5 則評論的陣列。每則評論包含數個元件,如下所示:
    • aspects[] 包含 PlaceAspectRating 物件陣列,每個物件都提供該場所單一屬性的評分。陣列中的第一個物件會視為主要指標。每個 PlaceAspectRating 的定義為:
      • type:要評分的指標名稱。支援的類型如下:appealatmospheredecorfacilitiesfoodoverallqualityservice
      • rating:使用者針對特定指標的評分 (從 0 到 3)。
    • author_name:提交評論的使用者名稱。匿名評論會歸類為「Google 使用者」。如果設定語言參數,「Google 使用者」一詞就會傳回經過本地化的字串。
    • author_url:使用者 Google+ 個人資料的網址 (如有)。
    • language:網際網路工程任務組 (IETF) 語言代碼,指出使用者評論所使用的語言。這個欄位只包含主要語言標記,不含表示國家/地區或區域的次要標記。舉例來說,所有英文評論都會標示為「en」,而非「en-AU」或「en-UK」等等。
    • rating:使用者給予這個地點的整體評分 (從 1 到 5 的整數)。
    • text:使用者的評論。在 Google 地點介面集中評論地點時,使用者不一定要填寫文字評論,因此這個欄位可能會空白。
  • types:這個地點的類型陣列 (例如 ["political", "locality"]["restaurant", "lodging"])。這個陣列可能包含多個值,也可能為空白。我們可能會在未事先通知的情況下導入新值。請參閱支援類型清單。
  • url:這個地點的 Google 官方頁面網址。這是 Google 自有的頁面,內含該地點的實用資訊。在向使用者顯示地點詳細結果的任何畫面上,應用程式必須連結或嵌入這個頁面。
  • vicinity:地點的簡化地址,包括街道名稱、門牌號碼和縣市,但不含省/州、郵遞區號或國家/地區。舉例來說,Google 澳洲雪梨辦公室的 vicinity 值為 5/48 Pirrama Road, Pyrmont。只有「搜尋附近」要求才會傳回 vicinity 屬性。
  • website 列出這個地點的官方網站,例如商家的首頁。

注意:並不是所有地點都提供多面向的評分。如果評論太少,則 Place Details 回應會包含 0.0 到 5.0 分的傳統評分 (如有),或不包含任何評分。

使用地點總覽元件

注意:這個範例使用開放原始碼程式庫。如需程式庫相關的支援以及意見回饋,請參閱 README

試用網頁元件。使用 Place Overview 網頁元件會以視覺化方式呈現地點詳細資料。

這張圖片顯示
    根據使用者輸入的大小欄位顯示地點總覽元件。
圖 1:包含五種尺寸變化的地點詳細資訊

使用地點 ID 參照地點

地點 ID 是地點在 Google 地圖上的專屬參照。大多數地點 (包括商家、地標、公園和十字路口) 都有地點 ID,

如要在應用程式中使用地點 ID,您必須先查詢 ID,這項資訊可在 Place Search 或 Place Details 要求的 PlaceResult 中找到。接著,您就可以使用這個地點 ID 來查詢 Place Details

地點 ID 不受《Google 地圖平台服務條款》第 3.2.3(b) 節的快取限制約束。因此,您可以儲存地點 ID 值供日後使用。如需有關儲存地點 ID 的最佳做法,請參閱地點 ID 總覽

var map;

function initialize() {
  // Create a map centered in Pyrmont, Sydney (Australia).
  map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: -33.8666, lng: 151.1958},
    zoom: 15
  });

  // Search for Google's office in Australia.
  var request = {
    location: map.getCenter(),
    radius: '500',
    query: 'Google Sydney'
  };

  var service = new google.maps.places.PlacesService(map);
  service.textSearch(request, callback);
}

// Checks that the PlacesServiceStatus is OK, and adds a marker
// using the place ID and location from the PlacesService.
function callback(results, status) {
  if (status == google.maps.places.PlacesServiceStatus.OK) {
    var marker = new google.maps.Marker({
      map: map,
      place: {
        placeId: results[0].place_id,
        location: results[0].geometry.location
      }
    });
  }
}

google.maps.event.addDomListener(window, 'load', initialize);

地點相片

「地點相片」功能可讓您在網站中加入高品質的相片內容。您可以透過「地點相片」服務,存取數百萬張儲存在地點介面集和 Google+ 在地服務資料庫中的相片。使用 Place Details 要求取得地點資訊時,系統會傳回相片參照,提供您相關的影像內容。此外,「搜尋附近」和「搜尋文字」要求也會視情況傳回每個地點的單一相片參照。之後,您可以使用「地點相片」服務存取參照的相片,並配合應用程式將圖片調整至最佳尺寸。

針對 PlacesService 發出的任何 getDetails()textSearch()nearbySearch() 要求,系統會在 PlaceResult 物件中傳回 PlacePhoto 物件陣列。

注意:系統傳回的相片數量會因要求而異。

  • 「搜尋附近」和「搜尋文字」要求最多會傳回一個 PlacePhoto 物件。
  • Place Details 要求最多會傳回十個 PlacePhoto 物件。

您可以呼叫 PlacePhoto.getUrl() 方法並傳遞有效的 PhotoOptions 物件,以要求相關圖片的網址。PhotoOptions 物件可讓您指定所需的圖片高度和寬度上限。如果同時指定 maxHeightmaxWidth 的值,「地點相片」服務會將圖片調整為兩種尺寸中的較小尺寸,並保留原始的顯示比例。

下列程式碼片段會接受地點物件,如果有相關相片,會在地圖上加入標記。預設的標記圖片會替換為較小尺寸的相片。

function createPhotoMarker(place) {
  var photos = place.photos;
  if (!photos) {
    return;
  }

  var marker = new google.maps.Marker({
    map: map,
    position: place.geometry.location,
    title: place.name,
    icon: photos[0].getUrl({maxWidth: 35, maxHeight: 35})
  });
}

「地點相片」服務傳回的相片取自各種地點,包括業主和使用者提供的相片。在大多數情況下,使用這些相片時可以不包含作者資訊,圖片本身也可能已加入必要的作者資訊。不過,如果傳回的 photo 元素在 html_attributions 欄位中包含值,您每次顯示圖片時就必須在應用程式中另外加入作者資訊。