Place Autocomplete (舊版)
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
歐洲經濟區 (EEA) 開發人員
注意:伺服器端程式庫
本頁面說明 Maps JavaScript API 提供的用戶端程式庫。如要在伺服器上使用 Places API 網路服務,請參閱「Google 地圖服務適用的 Node.js 用戶端」一文。該連結中的頁面也會介紹 Google 地圖服務適用的 Java 用戶端、Python 用戶端和 Go 用戶端。
簡介
「自動完成」是 Maps JavaScript API Places Library 的功能。您可以運用自動完成功能,在應用程式中提供 Google 地圖搜尋欄位的預先輸入搜尋行為。「自動完成」服務可比對完整字詞和子字串,解析地點名稱、地址和 Plus Codes。因此,應用程式可在使用者輸入內容時傳送查詢,即時提供地點預測結果。如 Places API 所定義,「地點」可以是建築物、地理位置或重要搜尋點。
開始使用
請先到 Google Cloud 控制台,確認同一個針對 Maps JavaScript API 設定的專案已啟用 Places API,然後再開始使用 Maps JavaScript API Places Library。
constcenter={lat:50.064192,lng:-130.605469};// Create a bounding box with sides ~10km away from the center pointconstdefaultBounds={north:center.lat+0.1,south:center.lat-0.1,east:center.lng+0.1,west:center.lng-0.1,};constinput=document.getElementById("pac-input")asHTMLInputElement;constoptions={bounds:defaultBounds,componentRestrictions:{country:"us"},fields:["address_components","geometry","icon","name"],strictBounds:false,};constautocomplete=newgoogle.maps.places.Autocomplete(input,options);
constcenter={lat:50.064192,lng:-130.605469};// Create a bounding box with sides ~10km away from the center pointconstdefaultBounds={north:center.lat+0.1,south:center.lat-0.1,east:center.lng+0.1,west:center.lng-0.1,};constinput=document.getElementById("pac-input");constoptions={bounds:defaultBounds,componentRestrictions:{country:"us"},fields:["address_components","geometry","icon","name"],strictBounds:false,};constautocomplete=newgoogle.maps.places.Autocomplete(input,options);
functionfillInAddress(){// Get the place details from the autocomplete object.constplace=autocomplete.getPlace();letaddress1="";letpostcode="";// 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/3l5i5Mrfor(constcomponentofplace.address_componentsasgoogle.maps.GeocoderAddressComponent[]){// @ts-ignore remove once typings fixedconstcomponentType=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")asHTMLInputElement).value=component.long_name;break;case"administrative_area_level_1":{(document.querySelector("#state")asHTMLInputElement).value=component.short_name;break;}case"country":(document.querySelector("#country")asHTMLInputElement).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();}
functionfillInAddress(){// Get the place details from the autocomplete object.constplace=autocomplete.getPlace();letaddress1="";letpostcode="";// 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/3l5i5Mrfor(constcomponentofplace.address_components){// @ts-ignore remove once typings fixedconstcomponentType=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;
// Listen for the event fired when the user selects a prediction and retrieve// more details for that place.searchBox.addListener("places_changed",()=>{constplaces=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.constbounds=newgoogle.maps.LatLngBounds();places.forEach((place)=>{if(!place.geometry||!place.geometry.location){console.log("Returned place contains no geometry");return;}consticon={url:place.iconasstring,size:newgoogle.maps.Size(71,71),origin:newgoogle.maps.Point(0,0),anchor:newgoogle.maps.Point(17,34),scaledSize:newgoogle.maps.Size(25,25),};// Create a marker for each place.markers.push(newgoogle.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);});
// Listen for the event fired when the user selects a prediction and retrieve// more details for that place.searchBox.addListener("places_changed",()=>{constplaces=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.constbounds=newgoogle.maps.LatLngBounds();places.forEach((place)=>{if(!place.geometry||!place.geometry.location){console.log("Returned place contains no geometry");return;}consticon={url:place.icon,size:newgoogle.maps.Size(71,71),origin:newgoogle.maps.Point(0,0),anchor:newgoogle.maps.Point(17,34),scaledSize:newgoogle.maps.Size(25,25),};// Create a marker for each place.markers.push(newgoogle.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);});
// 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">functioninitService():void{constdisplaySuggestions=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)=>{constli=document.createElement("li");li.appendChild(document.createTextNode(prediction.description));(document.getElementById("results")asHTMLUListElement).appendChild(li);});};constservice=newgoogle.maps.places.AutocompleteService();service.getQueryPredictions({input:"pizza near Syd"},displaySuggestions);}declareglobal{interfaceWindow{initService:()=>void;}}window.initService=initService;
// 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">functioninitService(){constdisplaySuggestions=function(predictions,status){if(status!=google.maps.places.PlacesServiceStatus.OK||!predictions){alert(status);return;}predictions.forEach((prediction)=>{constli=document.createElement("li");li.appendChild(document.createTextNode(prediction.description));document.getElementById("results").appendChild(li);});};constservice=newgoogle.maps.places.AutocompleteService();service.getQueryPredictions({input:"pizza near Syd"},displaySuggestions);}window.initService=initService;
<html>
<head>
<title>Retrieving Autocomplete Predictions</title>
<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 script to execute after the full HTML
document has been parsed. For non-blocking uses, avoiding race conditions,
and consistent behavior across browsers, consider loading using Promises. See
https://developers.google.com/maps/documentation/javascript/load-maps-js-api
for more information.
-->
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initService&libraries=places&v=weekly"
defer
></script>
</body>
</html>
您應使用同一個工作階段符記,針對呼叫 AutocompleteService.getPlacePredictions() 取得的地點提出一項 Place Details 要求。在這種情況下,自動完成要求會與 Place Details 要求合併,而呼叫會按照一般 Place Details 要求收費。系統不會針對自動完成要求收費。如果要求未使用工作階段符記,系統會同時收取自動完成要求和 Place Details 要求的費用。
// Create a new session token.varsessionToken=newgoogle.maps.places.AutocompleteSessionToken();// Pass the token to the autocomplete service.varautocompleteService=newgoogle.maps.places.AutocompleteService();autocompleteService.getPlacePredictions({input:'pizza near Syd',sessionToken:sessionToken},displaySuggestions);
為了讓 Place Autocomplete (舊版) 服務費用發揮最大效益,請使用 Place Details (舊版) 和 Place Autocomplete (舊版) 小工具中的欄位遮罩,只傳回所需的 Place Autocomplete (舊版) 資料欄位。
進階費用最佳化
建議您透過程式輔助方式導入 Place Autocomplete (舊版),採用 SKU:Autocomplete - Per Request 定價,並要求已選地點 (而非 Place Details (舊版)) 的相關 Geocoding API 結果。如果同時符合以下兩項條件,搭配 Geocoding API 使用「按要求」計價會比使用「按工作階段」(以工作階段為準) 計價更具成本效益:
如果您只需要針對使用者選取的地點取得經緯度或地址,透過 Geocoding API 擷取這項資訊,支付的費用會比使用 Place Details (舊版) 呼叫更低。
如果使用者在平均四次以內的 Place Autocomplete (舊版) 預測要求選取了自動預測結果,則「按要求」計價可能會比「按工作階段」計價更符合成本效益。
如要選擇最符合應用程式成本效益的 Place Autocomplete (舊版) 導入方式,請在下表中找出符合應用程式需求的資料列。
對您的應用程式而言,Geocoding API 可能比 Place Details (舊版) 更符合成本效益,視 Place Autocomplete (舊版) 使用效能而定。每個應用程式的 Place Autocomplete (舊版) 效率各不相同,可能取決於使用者輸入的內容、使用應用程式的位置,以及是否採用效能最佳化最佳做法。
如要找出表格的平均要求數,請分析使用者在應用程式中選取 Place Autocomplete (舊版) 預測結果前,平均輸入的字元數量。
以工作階段為準的 Place Autocomplete (舊版) 搭配 Place Details (舊版)
搭配 Place Details (舊版) 使用以工作階段為準的 Place Autocomplete (舊版)。
由於您的應用程式需要 Place Details (舊版),例如地點名稱、商家狀態或營業時間,因此在導入 Place Autocomplete (舊版) 時,應使用每個工作階段的工作階段符記 (透過程式輔助或內建於 JavaScript、Android 或 iOS 小工具),以及適用的地點資料 SKU (視您要求的地點資料欄位而定)。1
透過小工具導入 JavaScript、Android 或 iOS 小工具自動內建工作階段管理功能,其中包含對已選取的預測結果提出的 Place Autocomplete (舊版) 要求和 Place Details (舊版) 要求。請務必指定 fields 參數,確保只要求所需的 Place Autocomplete (舊版) 資料欄位。
透過程式輔助方式導入
搭配 Place Autocomplete (舊版) 要求使用工作階段符記。要求所選預測結果的相關 Place Details (舊版) 時,請加入下列參數:
透過程式輔助方式導入 Place Autocomplete (舊版),但不使用工作階段符記,並針對已選取的地點預測結果呼叫 Geocoding API。
Geocoding API 提供地址和經緯度座標。
提出四次 Autocomplete - Per Request 要求,加上所選地點預測結果的相關 Geocoding API 呼叫,費用低於 Place Autocomplete (舊版) 的每個工作階段費用1。
搭配 Place Details (舊版) 使用以工作階段為準的 Place Autocomplete (舊版)。
由於您預期在使用者選取 Place Autocomplete (舊版) 預測結果前,平均發出的要求數量超過按工作階段計價的費用,因此在導入 Place Autocomplete (舊版) 時,應針對 Place Autocomplete (舊版) 要求和相關聯的 Place Details (舊版) 要求,使用按工作階段計價的工作階段符記。
1
透過小工具導入 JavaScript、Android 或 iOS 小工具自動內建工作階段管理功能,其中包含對已選取的預測結果提出的 Place Autocomplete (舊版) 要求和 Place Details (舊版) 要求。請務必指定 fields 參數,確保只要求需要的欄位。
透過程式輔助方式導入
搭配 Place Autocomplete (舊版) 要求使用工作階段符記。
要求所選預測結果的相關 Place Details (舊版) 時,請加入下列參數:
考慮延後 Place Autocomplete (舊版) 要求
您可以運用一些策略,例如將 Place Autocomplete (舊版) 要求延後到使用者輸入三或四個字元時再開始,藉此減少應用程式提出要求數量。舉例來說,如果使用者輸入第三個字元後,系統針對每個字元提出 Place Autocomplete (舊版) 要求,則當使用者輸入七個字元,然後選取預測結果,您提出一項 Geocoding API 要求時,總費用會是 4 次 Place Autocomplete (舊版) 按要求計價 + 地理編碼。1