您已全部設定完成!

若要開始開發,請參閱我們的開發人員文件

啟用 Google Maps JavaScript API

為協助您開始,我們將先引導您使用「Google 開發人員控制台」來執行一些動作:

  1. 建立或選擇專案
  2. 啟用 Google Maps JavaScript API 與相關服務
  3. 建立適當的金鑰
繼續

地方資訊程式庫

總覽

Google Places JavaScript 程式庫中的功能可讓您的應用程式搜尋已定義區域內(例如地圖邊界或固定地點的周圍)包含的地點(在這個 API 中被定義為機構、地理位置或搜尋點)。

Google Places API 提供自動完成功能,可用來讓您的應用程式具備 Google 地圖搜尋欄位的「輸入即開始搜尋」行為。使用者開始輸入地址的時候,自動完成會填入其餘的部分。如需詳細資訊,請參閱自動完成文件

開始使用

在使用 Google Maps JavaScript API 中的「地方資訊」程式庫之前,請先確定已在 Google API Console (您針對 Google Maps JavaScript API 設定的相同專案中)中啟用 Google Places API Web Service。

檢視已啟用的 API 清單:

  1. 前往 Google API Console
  2. 按一下 [Select a project] 按鈕,選取您針對 Google Maps JavaScript API 設定的相同專案,然後按一下 [Open]
  3. 對於 [Dashboard] 上的 API 清單,請搜尋 Google Places API Web Service
  4. 如果您在該清單中看到 API,表示您已設定好。如果列出該 API,請將它啟用:
    1. 在頁面頂端,選取 [ENABLE API] 以顯示 [Library] 標籤。或者,從左側選單,選取 [Library]
    2. 搜尋 Google Places API Web Service,然後從結果清單中選取它。
    3. 選取 [ENABLE]。當此程序完成時,Google Places API Web Service 會出現在 [Dashboard] 上的 API 清單中。

載入程式庫

「地方資訊」服務是一個獨立的程式庫,不在主 Maps JavaScript API 程式碼中。如果要使用此程式庫中所包含的功能,您必須先在 Maps API 啟動程序 URL 中使用 libraries 參數載入它:

<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"></script>

如需詳細資訊,請參閱程式庫總覽

使用限制與政策

配額

Google Places API Web Service 與「地點自動完成」共用使用配額,如在 Google Places API Web Service 的使用限制文件中所述。使用 Places Library in the Google Maps JavaScript API 時亦適用這些使用限制。每日使用量是以用戶端與伺服器端要求的加總來計算的。

政策

使用 Places Library in the Google Maps JavaScript API 時必須符合針對 Google Places API Web Service 描述的政策

地點搜尋

您可以使用 Places 服務執行四類搜尋:

  • 附近地點搜尋會根據使用者的位置傳回附近地點清單。
  • 文字搜尋會根據搜尋字串傳回附近地點清單,例如:「Pizza」。
  • 雷達搜尋會傳回指定搜尋半徑內的大量地點清單,但是它包含的詳細資料比「附近地點搜尋」或「文字搜尋」少。
  • 地點詳細資料要求會傳回特定地點的較詳細相關資訊,包括使用者評論。

傳回的資訊可能包括機構(如餐廳、商店、辦公室),以及能指示地址、政府區域(如鄉鎮和城市)和其他搜尋點的「地理編碼」結果。

附近地點搜尋要求

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

  • LatLngBounds
  • location 屬性之組合所定義的一個圓形區域(指定圓形的中心為 LatLng 物件),以及一個半徑(以公尺為單位)。

「附近地點搜尋」是透過呼叫 PlacesServicenearbySearch() 方法來進行初始化,這將會傳回一個 PlaceResult 物件的陣列。請注意,自版本 3.9 開始,nearbySearch() 方法已取代 search() 方法。

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

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

  • 可以是:
    • bounds,它必須是定義矩形搜尋區域的 google.maps.LatLngBounds 物件;或
    • locationradius,前者使用 google.maps.LatLng 物件,後者使用代表圓形半徑的簡單整數(以公尺為單位)。允許的最大半徑是 50,000 公尺。請注意,當 rankBy 設定為 DISTANCE 時,您必須指定 location,但是不能指定 radiusbounds
  • keyword (選擇性) - 要與所有可用欄位(包括但不限於名稱、類型和地址)比對,以及與客戶評論和其他第三方內容比對的字詞。
  • minPriceLevelmaxPriceLevel (選擇性) - 將結果限制在指定範圍內的地點。有效值的範圍是 0(最負擔得起)到 4(最昂貴),含 0 和 4。
  • name (選擇性) - 要與地點的名稱比對的字詞。結果將僅限於包含所傳遞之 name 值的地點。請注意,地點除了所列的名稱之外,可能還有其他關聯名稱。API 會嘗試將傳遞的 name 值與所有這些名稱做比對,因此,結果中所傳回之地點的「列出」名稱可能與搜尋字詞不相符,但是其關聯名稱相符。
  • openNow (選擇性) - 布林值,指示 Places 服務應該只傳回於傳送查詢時還在營業的地點。如果您在查詢中包括此參數,將不會傳回「Google 地方資訊」資料庫中未指定營業時間的地點。設定 openNowfalse 不會有任何影響。
  • 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 - 將結果限制在與指定類型相符的地點。只能指定一種類型(如果超過一種類型,第一個項目之後的所有類型都會被忽略)。請參閱支援的類型清單
  • types已淘汰) — 包含一或多個支援類型陣列。服務將傳回最符合指定類型集合的一組結果。

您必須也要傳遞回呼方法到 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',
    types: ['store']
  };

  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++) {
      var place = results[i];
      createMarker(results[i]);
    }
  }
}

檢視範例 (place-search.html)

文字搜尋要求

Google Places 文字搜尋服務是一個 Web 服務,它會根據字串(例如「pizza in New York」或「shoe stores near Ottawa」)傳回一組地點的相關資訊。此服務會以與文字字串及任何已設定之位置偏向相符的地點清單做為回應。搜尋回應將包含地點的清單。您可以傳送「地點詳細資料」要求,以取得回應中任何地點的相關詳細資訊。

「文字搜尋」是藉由呼叫 PlacesServicetextSearch() 方法來進行初始化。

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

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

  • query (必要) - 做為搜尋依據的文字字串,例如:「restaurant」。Places 服務將會依據此字串傳回相符的候選項目,並依據所感知的結果相關性排列結果順序。如果搜尋要求中也使用 type 參數,則此參數會成為選用參數。
  • 選擇性參數:
    • openNow - 布林值,指示 Places 服務應該只傳回傳送查詢時還在營業的地點。如果您在查詢中包括此參數,將不會傳回「Google 地方資訊」資料庫中未指定營業時間的地點。設定 openNowfalse 不會有任何影響。
    • minpricemaxprice - 將結果限制在指定價格等級內的地點。有效值的範圍是 0(最負擔得起)到 4(最昂貴),含 0 和 4。
    • 可以是:
      • bounds - 定義要搜尋之矩形區域的 google.maps.LatLngBounds 物件;或
      • locationradius - 您可以透過傳遞 locationradius 參數,將結果偏向指定的圓形範圍。這會將 Places 服務引導成偏好顯示該範圍內的結果。該定義區域外的結果仍然會顯示。「Location」可接受 google.maps.LatLng 物件,而「Radius」可接受代表圓形半徑(以公尺為單位)的簡單整數。允許的最大半徑是 50,000 公尺。
    • type - 將結果限制在與指定類型相符的地點。只能指定一種類型(如果超過一種類型,第一個項目之後的所有類型都會被忽略)。請參閱支援的類型清單
    • types已淘汰) — 包含一或多個支援類型陣列。服務將會傳回符合任何指定類型的結果。

您必須也要傳遞回呼方法到 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]);
    }
  }
}

雷達搜尋要求

「雷達搜尋」可讓您依關鍵字、類型或名稱搜尋指定搜尋半徑內的地點。「雷達搜尋」可傳回比「附近地點搜尋」或「文字搜尋」更多的結果,但是這些結果包含較少的欄位。您可以呼叫 PlacesService.getDetails(),以取得回應中任何地點的相關詳細資訊。

radarSearch() 傳回的 PlaceResult 物件只包含下列屬性:

  • geometry.location
  • place_id
  • reference注意:reference 已被 place_id 取代,如本頁過時通知中的描述)。

Places「雷達搜尋」的初始化是呼叫 PlacesServiceradarSearch() 方法,這將會傳回一個最多 200 個 PlaceResult 物件的陣列。

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

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

  • 可以是:
    • bounds,它必須是定義矩形搜尋區域的 google.maps.LatLngBounds 物件;或
    • locationradius,前者使用 google.maps.LatLng 物件,後者使用代表圓形半徑的簡單整數(以公尺為單位)。允許的最大半徑是 50,000 公尺。
  • 至少下列其中之一:
    • keyword (選擇性) - 要與所有可用欄位(包括但不限於名稱、類型和地址)比對,以及與客戶評論和其他第三方內容比對的字詞。
    • name (選擇性) - 要與地點的名稱比對的字詞。結果將僅限於包含所傳遞之 name 值的地點。請注意,地點除了所列的名稱之外,可能還有其他關聯名稱。API 會嘗試將傳遞的 name 值與所有這些名稱做比對,因此,結果中所傳回之地點的「列出」名稱可能與搜尋字詞不相符,但是其關聯名稱相符。
    • type - 將結果限制在與指定類型相符的地點。只能指定一種類型(如果超過一種類型,第一個項目之後的所有類型都會被忽略)。請參閱支援的類型清單
    • parameter is also used in the search request.types已淘汰) — 包含一或多個支援類型陣列。服務將傳回最符合指定類型集合的一組結果。
  • 選擇性參數:
    • minPriceLevelmaxPriceLevel (選擇性) - 將結果限制在指定價格等級內的地點。有效值的範圍是 0(最負擔得起)到 4(最昂貴),含 0 和 4。
    • openNow - 布林值,指示 Places 服務應該只傳回傳送查詢時還在營業的地點。如果您在查詢中包括此參數,將不會傳回「Google 地方資訊」資料庫中未指定營業時間的地點。設定 openNowfalse 不會有任何影響。

您必須也要傳遞回呼方法到 radarSearch(),以便處理 PlaceResults 物件和 google.maps.places.PlacesServiceStatus

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

var map;
var infoWindow;
var service;

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: -33.867, lng: 151.206},
    zoom: 15,
    styles: [{
      stylers: [{ visibility: 'simplified' }]
    }, {
      elementType: 'labels',
      stylers: [{ visibility: 'off' }]
    }]
  });

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

  // The idle event is a debounced event, so we can query & listen without
  // throwing too many requests at the server.
  map.addListener('idle', performSearch);
}

function performSearch() {
  var request = {
    bounds: map.getBounds(),
    keyword: 'best view'
  };
  service.radarSearch(request, callback);
}

function callback(results, status) {
  if (status !== google.maps.places.PlacesServiceStatus.OK) {
    console.error(status);
    return;
  }
  for (var i = 0, result; result = results[i]; i++) {
    addMarker(result);
  }
}

function addMarker(place) {
  var marker = new google.maps.Marker({
    map: map,
    position: place.geometry.location,
    icon: {
      url: 'https://developers.google.com/maps/documentation/javascript/images/circle.png',
      anchor: new google.maps.Point(10, 10),
      scaledSize: new google.maps.Size(10, 17)
    }
  });

  google.maps.event.addListener(marker, 'click', function() {
    service.getDetails(place, function(result, status) {
      if (status !== google.maps.places.PlacesServiceStatus.OK) {
        console.error(status);
        return;
      }
      infoWindow.setContent(result.name);
      infoWindow.open(map, marker);
    });
  });
}
<div id="map"></div>
/* 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;
}
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=places,visualization" async defer></script>
// 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">

var map;
var infoWindow;
var service;

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: -33.867, lng: 151.206},
    zoom: 15,
    styles: [{
      stylers: [{ visibility: 'simplified' }]
    }, {
      elementType: 'labels',
      stylers: [{ visibility: 'off' }]
    }]
  });

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

  // The idle event is a debounced event, so we can query & listen without
  // throwing too many requests at the server.
  map.addListener('idle', performSearch);
}

function performSearch() {
  var request = {
    bounds: map.getBounds(),
    keyword: 'best view'
  };
  service.radarSearch(request, callback);
}

function callback(results, status) {
  if (status !== google.maps.places.PlacesServiceStatus.OK) {
    console.error(status);
    return;
  }
  for (var i = 0, result; result = results[i]; i++) {
    addMarker(result);
  }
}

function addMarker(place) {
  var marker = new google.maps.Marker({
    map: map,
    position: place.geometry.location,
    icon: {
      url: 'https://developers.google.com/maps/documentation/javascript/images/circle.png',
      anchor: new google.maps.Point(10, 10),
      scaledSize: new google.maps.Size(10, 17)
    }
  });

  google.maps.event.addListener(marker, 'click', function() {
    service.getDetails(place, function(result, status) {
      if (status !== google.maps.places.PlacesServiceStatus.OK) {
        console.error(status);
        return;
      }
      infoWindow.setContent(result.name);
      infoWindow.open(map, marker);
    });
  });
}

檢視範例 (place-radar-search.html)

搜尋回應

狀態碼

PlacesServiceStatus 回應物件包含要求的狀態,也包含可協助您探究地點要求失敗原因的偵錯資訊。可能的狀態值包括:

  • ERROR:聯絡 Google 伺服器時出現問題。
  • INVALID_REQUEST:此要求無效。
  • OK:回應包含有效的結果。
  • OVER_QUERY_LIMIT:網頁已超出要求配額的量。
  • REQUEST_DENIED:網頁不允許使用 PlacesService。
  • UNKNOWN_ERROR:由於發生伺服器錯誤,而無法處理 PlacesService 要求。重新嘗試該要求或許會成功。
  • ZERO_RESULTS:此要求找不到結果。

地點搜尋結果

nearbySearch()textSearch() 函式會傳回一個 PlaceResult 物件的陣列。radarSearch() 函式會傳回 PlaceResult 中欄位的子集,如上面的描述。

個別 PlaceResult 物件可能會包含下列屬性:

  • formatted_address 是一個字串,包含人類看得懂的此地點地址。此地址通常等於「郵政地址」。formatted_address 屬性是只有針對文字搜尋才會傳回的屬性。
  • geometry:地點的幾何相關資訊。這包括:
    • location 提供位置的緯度與經度。
    • viewport 定義檢視此地點時在地圖上的偏好檢視點。
  • html_attributions:顯示搜尋結果時,應該要顯示的資料引用標示陣列。陣列中的每個項目皆包含針對單一資料引用標示的 HTML 文字。注意:這是整個搜尋回應之所有資料引用標示的彙總。因此,回應中的所有 PlaceResult 物件都包含了完全一樣的資料引用標示清單。
  • icon:用來代表此地點類型之影像資源的 URL。
  • id:包含代表此地點的唯一識別碼。此識別碼無法用來擷取此地點的相關資訊,但可用來合併此地點的相關資料,以及在個別的搜尋中驗證地點的識別資訊。由於 ID 可能偶爾會變更,因此建議將儲存的地點 ID 與稍後在「詳細資料」要求中針對此相同地點傳回的 ID 做比較,並視需要加以更新。注意:id 已被 place_id 取代,如本頁過時通知中的描述。
  • name:地點的名稱。
  • opening_hours 可包含下列資訊:
    • open_now 是一個布林值,指出地點目前是否營業中。
  • place_id 是可唯一識別地點的文字型識別碼。如果要擷取地點的相關資訊,請在地點詳細資料要求placeid 欄位中傳遞此識別碼。深入瞭解如何使用地點 ID 參照某個地點
  • rating 包含地點的評分,從 0.0 到 5.0,以加總的使用者評論為依據。
  • reference 包含可用來在未來查詢「詳細資料」服務的語彙基元。此語彙基元可能與對「詳細資料」服務發出的要求中所使用的參照不同。建議定期更新所儲存的地點參照。雖然此權杖可唯一識別此地點,但此地點並不僅限擁有一個權杖:一個地點可能包含許多有效的參照權杖。注意:reference 已被 place_id 取代,如本頁過時通知中的描述。
  • types 此地點的類型陣列(例如,["political", "locality"]["restaurant", "lodging"])。
  • vicinity:地點的簡化地址,包括街道名稱、門牌號碼和郵遞分區,但不包括省/州、郵遞區號或國家/地區。例如,Google 澳洲雪梨辦公室的 vicinity 值為 5/48 Pirrama Road, Pyrmont

存取其他結果

根據預設,每個地點搜尋針對每一查詢最多會傳回 20 個結果。不過,每個搜尋可傳回多達 60 個紀錄,分列於三頁。其他頁面可透過 PlaceSearchPagination 物件取得。為了存取其他頁面,您必須透過回呼函式擷取 PlaceSearchPagination 物件。PlaceSearchPagination 物件定義如下:

  • hasNextPage 是布林值屬性,指出是否提供進一步結果。如果有其他結果頁,則為 true
  • nextPage() 是傳回下一組結果的函式。執行搜尋之後,必須等待兩秒,才能提供下一頁結果。

如果要查看下一組結果,請呼叫 nextPage。每一頁結果必須先顯示,然後才能顯示下一頁結果。請注意,每個搜尋都會被視為一個要求,並計入您的使用限制。

下列範例示範如何修改回呼函式來擷取 PlaceSearchPagination 物件,以便您發出多個搜尋要求。

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

var map;

function initMap() {
  var pyrmont = {lat: -33.866, lng: 151.196};

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

  var service = new google.maps.places.PlacesService(map);
  service.nearbySearch({
    location: pyrmont,
    radius: 500,
    type: ['store']
  }, processResults);
}

function processResults(results, status, pagination) {
  if (status !== google.maps.places.PlacesServiceStatus.OK) {
    return;
  } else {
    createMarkers(results);

    if (pagination.hasNextPage) {
      var moreButton = document.getElementById('more');

      moreButton.disabled = false;

      moreButton.addEventListener('click', function() {
        moreButton.disabled = true;
        pagination.nextPage();
      });
    }
  }
}

function createMarkers(places) {
  var bounds = new google.maps.LatLngBounds();
  var placesList = document.getElementById('places');

  for (var i = 0, place; place = places[i]; i++) {
    var 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)
    };

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

    placesList.innerHTML += '<li>' + place.name + '</li>';

    bounds.extend(place.geometry.location);
  }
  map.fitBounds(bounds);
}
<div id="map"></div>
<div id="right-panel">
  <h2>Results</h2>
  <ul id="places"></ul>
  <button id="more">More results</button>
</div>
/* 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;
}
#right-panel {
  font-family: 'Roboto','sans-serif';
  line-height: 30px;
  padding-left: 10px;
}

#right-panel select, #right-panel input {
  font-size: 15px;
}

#right-panel select {
  width: 100%;
}

#right-panel i {
  font-size: 12px;
}
#right-panel {
  font-family: Arial, Helvetica, sans-serif;
  position: absolute;
  right: 5px;
  top: 60%;
  margin-top: -195px;
  height: 330px;
  width: 200px;
  padding: 5px;
  z-index: 5;
  border: 1px solid #999;
  background: #fff;
}
h2 {
  font-size: 22px;
  margin: 0 0 5px 0;
}
ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  height: 271px;
  width: 200px;
  overflow-y: scroll;
}
li {
  background-color: #f1f1f1;
  padding: 10px;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
li:nth-child(odd) {
  background-color: #fcfcfc;
}
#more {
  width: 100%;
  margin: 5px 0 0 0;
}
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places&callback=initMap" async defer></script>
// 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">

var map;

function initMap() {
  var pyrmont = {lat: -33.866, lng: 151.196};

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

  var service = new google.maps.places.PlacesService(map);
  service.nearbySearch({
    location: pyrmont,
    radius: 500,
    type: ['store']
  }, processResults);
}

function processResults(results, status, pagination) {
  if (status !== google.maps.places.PlacesServiceStatus.OK) {
    return;
  } else {
    createMarkers(results);

    if (pagination.hasNextPage) {
      var moreButton = document.getElementById('more');

      moreButton.disabled = false;

      moreButton.addEventListener('click', function() {
        moreButton.disabled = true;
        pagination.nextPage();
      });
    }
  }
}

function createMarkers(places) {
  var bounds = new google.maps.LatLngBounds();
  var placesList = document.getElementById('places');

  for (var i = 0, place; place = places[i]; i++) {
    var 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)
    };

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

    placesList.innerHTML += '<li>' + place.name + '</li>';

    bounds.extend(place.geometry.location);
  }
  map.fitBounds(bounds);
}

檢視範例 (place-search-pagination.html)

地點詳細資料

除了提供一個區域內的地點清單之外,Places 服務也可以傳回特定地點的詳細資訊。在地點搜尋回應傳回一個地點之後,它的地點 ID 可用來要求該地點的其他詳細資料,例如其完整地址、電話號碼、使用者評分和評論等等。(地點的 reference 也可以用來擷取地點的詳細資料,但是這個欄位已被地點 ID 取代,如本頁過時通知中的描述。)

地點詳細資料要求

您可以呼叫服務的 getDetails() 方法來要求地點詳細資料。

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

這個方法使用包含所需地點之 placeIdreference 的要求。reference 已被 place_id 取代,如本頁過時通知中的描述。深入瞭解如何使用地點 ID 參照某個地點

它也使用回呼方法,該方法需要處理 google.maps.places.PlacesServiceStatus 回應中傳遞的狀態碼以及 google.maps.places.PlaceResult 物件。

var request = {
  placeId: 'ChIJN1t_tDeuEmsRUsoyG83frY4'
};

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.html)

地點詳細資料回應

狀態碼

PlacesServiceStatus 回應物件包含要求的狀態,也包含可協助您探究地點詳細資料要求失敗原因的偵錯資訊。可能的狀態值包括:

  • ERROR:聯絡 Google 伺服器時出現問題。
  • INVALID_REQUEST:此要求無效。
  • OK:回應包含有效的結果。
  • OVER_QUERY_LIMIT:網頁已超出要求配額的量。
  • NOT_FOUND:在 Places 資料庫中找不到所參照的位置。
  • REQUEST_DENIED:網頁不允許使用 PlacesService。
  • UNKNOWN_ERROR:由於發生伺服器錯誤,而無法處理 PlacesService 要求。重新嘗試該要求或許會成功。
  • ZERO_RESULTS:此要求找不到結果。

地點詳細資料結果

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

  • address_components:此地點位置的地址元件集合。請參閱「地理編碼」服務的地址元件類型小節,瞭解更多詳細資訊。
  • formatted_address:地點的完整地址。
  • formatted_phone_number:地點的電話號碼,格式採用號碼的區域慣例
  • geometry:地點的幾何相關資訊。這包括:
    • location 提供位置的緯度與經度。
    • viewport 定義檢視此地點時在地圖上的偏好檢視點。
  • html_attributions:要針對此地點結果顯示的資料引用標示文字。
  • icon:用來代表此地點類型之影像資源的 URL。
  • id:包含代表此地點的唯一識別碼。此識別碼無法用來擷取此地點的相關資訊,但可用來合併此地點的相關資料,以及在個別的搜尋中驗證地點的識別資訊。由於 ID 可能偶爾會變更,因此建議將儲存的地點 ID 與稍後在「詳細資料」要求中針對此相同地點傳回的 ID 做比較,並視需要加以更新。注意:id 已被 place_id 取代,如本頁過時通知中的描述。
  • international_phone_number 包含地點的國際格式電話號碼。國際格式包括國碼,而且前面加上加號 (+)。例如,Google 澳洲雪梨辦公室的 international_phone_number+61 2 9374 4000
  • name:地點的名稱。
  • utc_offset 包含此地點目前時區與 UTC 的時間差(單位為分鐘)。例如,如果是日光節約時間期間內的澳洲雪梨地點,這會是 660 (與 UTC 的時差為 +11 小時),如果是日光節約時間期間外的加州地點,則會是 -480 (與 UTC 的時差為 -8 小時)。
  • opening_hours 包含下列資訊:
    • open_now 是一個布林值,指出地點目前是否營業中。
    • periods[] 是一個從星期天開始、為期七天的營業期間陣列,依時間先後排序。每個期間皆包含:
      • open 包含描述地點何時營業的一組日別和時間物件:
        • day 是 0 到 6 的數字,對應星期幾,從星期天開始。例如,2 代表星期二。
        • time 可包含 24 小時 hhmm 格式的一天時間(值的範圍為 0000 到 2359)。time 將會以該地點的時區報時。
      • close 包含描述地點何時打烊的一組日別和時間物件。注意:如果地點永不打烊,回應中就不會有 close 區段。當 open 期間包含值為 0 的 day 和值為 0000 的 time,而且沒有 close 時,應用程式即確信該地點為永不打烊。
    • weekday_text 是一個 7 個字串的陣列,代表週一到週日每天的營業時數。如果「地點詳細資料」要求中指定了 language 參數,「地方資訊服務」將會以該語言適當地呈現出格式化與當地語系化的營業時間。此陣列中元素的順序視 language 參數而定。某些語言以週一為每週的開始,其他則以週日為開始。
  • permanently_closed:是布林旗標,用來指示地點是否永久關閉(值為 true)。如果地點不是永久關閉,則回應中不會有該旗標存在。
  • photos[]PlacePhoto 物件的陣列。PlacePhoto 可用來搭配 getUrl() 方法以取得相片,或者您可以檢查物件中的下列值:
    • height:影像的高度上限(以像素為單位)。
    • width:影像的寬度上限(以像素為單位)。
    • html_attributions:與此地點相片一起顯示的資料引用標示文字。
  • place_id:唯一識別地點的文字識別碼,可用來透過地點詳細資料要求擷取地點的相關資訊。深入瞭解如何使用地點 ID 參照某個地點
  • rating:地點的評分,從 0.0 到 5.0,以加總的使用者評論為依據。
  • reference 包含可用來在未來查詢「詳細資料」服務的語彙基元。此語彙基元可能與對「詳細資料」服務發出的要求中所使用的參照不同。建議定期更新所儲存的地點參照。雖然此權杖可唯一識別此地點,但此地點並不僅限擁有一個權杖:一個地點可能包含許多有效的參照權杖。注意:reference 已被 place_id 取代,如本頁過時通知中的描述。
  • reviews 是最多可包含五個評論的陣列。每個評論皆由數個元件組成:
    • aspects[] 包含 PlaceAspectRating 物件的陣列,每個物件皆提供該機構單一屬性的評分。陣列中的第一個物件被視為主要觀點。每個 PlaceAspectRating 皆被定義為:
      • type - 所評分之觀點的名稱。支援下列類型:appealatmospheredecorfacilitiesfoodoverallqualityservice
      • rating - 使用者對此特定觀點的評分,從 0 到 3。
    • author_name - 提交評論的使用者名稱。匿名評論會視為由「Google 使用者」提出。如果已設定語言參數,則「Google 使用者」會傳回已當地語系化的字串。
    • author_url - 使用者 Google+ 個人資料(如果有的話)的 URL。
    • language - 指出使用者評論中所使用之語言的 IETF 語言代碼。此欄位只包含主要語言標籤,而不包含指出國家或地區的次要標籤。例如,所有英文評論皆標記為 'en',而不是 'en-AU' 或 'en-UK' 等等。
    • rating - 使用者對此地點的整體評分。這是一個整數,範圍從 1 到 5。
    • text - 使用者的評論。使用 Google Places 來評論位置時,由於文字評論為選擇性的內容,因此此欄位可能空白。
  • types 此地點的類型陣列(例如,["political", "locality"]["restaurant", "lodging"])。
  • url:此地點之官方 Google 頁面的 URL。這是一個由 Google 所擁有,並包含與地點相關之最佳可用資訊的頁面。應用程式必須在對使用者顯示地點相關詳細結果的任何畫面上,連結到此頁面或內嵌此頁面。
  • vicinity:地點的簡化地址,包括街道名稱、門牌號碼和郵遞分區,但不包括省/州、郵遞區號或國家/地區。例如,Google 澳洲雪梨辦公室的 vicinity 值為 5/48 Pirrama Road, Pyrmontvicinity 屬性是只有針對附近地點搜尋才會傳回的屬性。
  • website 會列出此地點的權威網站,例如商家的首頁。

並非所有位置都會有多方面的評分。如果評論數量太少,則詳細資料回應將會包含傳統 0.0 到 5.0 等級的評分(如果可取得),或完全沒有評分。

使用地點 ID 參照一個地點

您可以使用地點的地點 ID 來唯一參照 Google 地圖上的地點。大多數位置都有「地點 ID」,包括商家、地標、公園和十字路口。這些 ID 是固定的,表示一旦您識別了一個位置的地點 ID,下次當您查詢該位置時,就能重複使用該值。

如果要在您的應用程式中使用地點 ID,就必須先找出該 ID。您可以在地點搜尋或詳細資料要求的 PlaceResult 中找到。然後您就可以使用地點 ID 來查詢地點詳細資料,或在已登入的地圖上啟用儲存資料引用標示

地點 ID 不受 Google Maps API 服務條款 10.5.d 節中說明的快取限制規範。因此,您可以無限儲存地點 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);

地點相片

「地方資訊相片」功能可讓您將高品質的相片內容新增到您的網站。「相片」服務可讓您存取儲存於 Places 與 Google+ 當地服務資料庫中的數百萬張相片。當您使用「地點詳細資料」要求取得地點資訊,將會傳回相關相片內容的相片參考資料。「附近地點搜尋」與「文字搜尋」要求也會傳回各地點資訊的單一相片參考資料(如有相關)。使用相片服務,您可以存取參考相片以及將影像調整為符合您應用程式的最佳大小。

PlacePhoto 物件的陣列將會針對 PlacesService 所做的任何 getDetails()textSearch()nearbySearch() 要求,做為 PlaceResult 物件的一部分一起傳回。

注意:傳回的相片數會依要求而不同。

  • 「附近地點搜尋」與「文字搜尋」最多會傳回一個 PlacePhoto 物件。
  • 「雷達搜尋」不會傳回任何相片資訊。
  • 「詳細資料」要求最多會傳回十個 PlacePhoto 物件。

您可以要求關聯影像的 URL,只需呼叫 PlacePhoto.getUrl() 方法並傳遞有效的 PhotoOptions 物件。PhotoOptions 物件可讓您指定影像所需的最大高度和寬度。如果您指定 max_heightmax_width 兩者的值,相片服務會將影像調整成兩個大小中較小的值,同時維持原來的外觀比例。

下列程式碼片段會接受一個地點物件,並新增標記到地圖(如果有相片的話)。預設的標記影像會由較小版本的相片取代。

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

傳送您對下列選項的寶貴意見...

這個網頁
Google Maps JavaScript API
Google Maps JavaScript API
需要協助嗎?請前往我們的支援網頁