BasicPlaceAutocompleteElement
會建立文字輸入欄位、在 UI 選單中提供地點預測結果,以及傳回所選地點的地點 ID。
PlaceAutocompleteElement
不同的是,簡化的 Basic Place Autocomplete 元素會在使用者選取地點預測結果時清除輸入欄位,並傳回只包含地點 ID 的 Place 物件,而非
PlacePrediction
物件。搭配 Places UI Kit Details 元素使用這個地點 ID,即可取得其他地點詳細資料。必要條件
如要使用 Basic Place Autocomplete 元素,請務必在 Google Cloud 專案中啟用「Places UI Kit」。詳情請參閱「開始使用」一文。
新增基本地點自動完成元素
Basic Place Autocomplete 元素會建立文字輸入欄位、在 UI 選單中提供地點預測結果,以及透過 gmp-select
事件傳回 Place ID 以回應使用者選取。本節說明如何在網頁或地圖中加入基本 Autocomplete 元素。
在網頁中加入基本 Autocomplete 元素
如要在網頁中加入 BasicAutocomplete 元素,請建立新的 google.maps.places.BasicPlaceAutocompleteElement
,然後附加至網頁,如以下範例所示:
// Request needed libraries. const {BasicPlaceAutocompleteElement} = await google.maps.importLibrary('places'); // Create the input HTML element, and append it. const placeAutocomplete = new BasicPlaceAutocompleteElement(); document.body.appendChild(placeAutocomplete);
在地圖中加入基本 Autocomplete 元素
如要在地圖中加入基本 Autocomplete 元素,請建立新的 BasicPlaceAutocompleteElement
執行個體,將其附加至 div
,然後推送至地圖做為自訂控制項,如以下範例所示:
const placeAutocomplete = new google.maps.places.BasicPlaceAutocompleteElement(); placeAutocomplete.id = 'place-autocomplete-input'; placeAutocomplete.locationBias = center; const card = document.getElementById('place-autocomplete-card'); card.appendChild(placeAutocomplete); map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);
限制 Autocomplete 預測結果
根據預設,Basic Place Autocomplete 會顯示所有地點類型 (優先顯示使用者所在位置附近的預測結果)。您可以限制或自訂調整結果,將
BasicPlaceAutocompleteElementOptions
設為顯示更相關的預測結果。
限制結果後,Basic Autocomplete 元素會略過超出限制區域的所有結果。常見做法是將結果限制在地圖範圍內。自訂調整結果會讓 BasicAutocomplete 元素顯示指定區域內的結果,但有些相符項目可能會超出這個區域。
如未提供任何邊界或地圖可視區域,API 就會嘗試根據使用者的 IP 位址偵測所在位置,然後針對該位置調整結果。請盡可能設定邊界,否則不同使用者可能會收到不同的預測結果。此外,為了改善整體預測結果,請務必提供合理的可視區域,例如您透過平移或縮放地圖設定的可視區域,或是開發人員根據裝置位置和半徑設定的可視區域。如果沒有設定半徑,系統會將 5 公里視為 Basic Place Autocomplete 元素的合理預設值。請勿將可視區域設為下列值:半徑為零 (單一點)、範圍僅有幾公尺 (小於 100 公尺),或是橫跨全球。
按國家/地區限制 Place Search
如要將 Place Search 限制在一或多個特定國家/地區,請使用 includedRegionCodes
屬性指定國家/地區代碼,如以下程式碼片段所示:
const pac = new google.maps.places.BasicPlaceAutocompleteElement({ includedRegionCodes: ['us', 'au'], });
將 Place Search 限制在地圖邊界內
如要將 Place Search 限制在地圖邊界內,請使用 locationRestrictions
屬性新增邊界,如以下程式碼片段所示:
const pac = new google.maps.places.BasicPlaceAutocompleteElement({ locationRestriction: map.getBounds(), });
限制地圖範圍時,請務必新增事件監聽器,在範圍變更時加以更新:
map.addListener('bounds_changed', () => { autocomplete.locationRestriction = map.getBounds(); });
如要移除 locationRestriction
,請設為 null
。
自訂調整 Place Search 結果
使用 locationBias
屬性並傳遞半徑,將 Place Search 結果自訂調整為僅限某個圓形區域,如下所示:
const autocomplete = new google.maps.places.BasicPlaceAutocompleteElement({ locationBias: {radius: 100, center: {lat: 50.064192, lng: -130.605469}}, });
如要移除 locationBias
,請設為 null
。
將 Place Search 結果限制為特定類型
使用 includedPrimaryTypes
屬性並指定一或多個類型,將 Place Search 結果限制為特定類型的地點,如下所示:
const autocomplete = new google.maps.places.BasicPlaceAutocompleteElement({ includedPrimaryTypes: ['establishment'], });
如需支援類型的完整清單,請參閱地點類型表 A 和 B。
取得 Place Details
如要取得所選地點的 Place ID,請在 PlaceAutocompleteElement
中加入 gmp-select
事件監聽器,如以下範例所示:
// Add the gmp-select listener, and display the results. placeAutocomplete.addEventListener('gmp-select', async ({ place }) => { await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'] }); selectedPlaceTitle.textContent = 'Selected Place:'; selectedPlaceInfo.textContent = JSON.stringify(place.toJSON(), /* replacer */ null, /* space */ 2); });
在上例中,事件監聽器會傳回 Place 類別的物件。呼叫 place.fetchFields()
即可取得應用程式所需的 Place Details 資料欄位。
下例中的事件監聽器會要求地點資訊,並將這項資訊顯示在地圖上。
// Add the gmp-placeselect listener, and display the results on the map. //@ts-ignore placeAutocomplete.addEventListener('gmp-select', async ({ place }) => { await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'] }); // If the place has a geometry, then present it on a map. if (place.viewport) { map.fitBounds(place.viewport); } else { map.setCenter(place.location); map.setZoom(17); } let content = '<div id="infowindow-content">' + '<span id="place-displayname" class="title">' + place.displayName + '</span><br />' + '<span id="place-address">' + place.formattedAddress + '</span>' + '</div>'; updateInfoWindow(content, place.location); marker.position = place.location; });
本例顯示如何在 Google 地圖中加入 Basic Autocomplete 元素。
JavaScript
const mapContainer = document.getElementById("map-container"); const autocompleteElement = document.querySelector('gmp-basic-place-autocomplete'); const detailsElement = document.querySelector('gmp-place-details-compact'); const mapElement = document.querySelector('gmp-map'); const advancedMarkerElement = document.querySelector('gmp-advanced-marker'); let center = { lat: 40.749933, lng: -73.98633 }; // New York City async function initMap() { //@ts-ignore const { BasicPlaceAutocompleteElement, PlaceDetailsElement } = await google.maps.importLibrary('places'); //@ts-ignore const { AdvancedMarkerElement } = await google.maps.importLibrary('marker'); //@ts-ignore const { LatLngBounds } = await google.maps.importLibrary('core'); // Set the initial map location and autocomplete location bias mapElement.center = center; autocompleteElement.locationBias = center; // Get the underlying google.maps.Map object to add listeners const map = mapElement.innerMap; // Add the listener tochange locationBias to locationRestriction when the map moves map.addListener('bounds_changed', () => { autocompleteElement.locationBias = null; autocompleteElement.locationRestriction = map.getBounds(); console.log("bias changed to restriction"); }); // Add the listener to update the Place Request element when the user selects a prediction autocompleteElement.addEventListener('gmp-select', async (event) => { const placeDetailsRequest = document.querySelector('gmp-place-details-place-request'); placeDetailsRequest.place = event.place.id; }); // Add the listener to update the marker when the Details element loads detailsElement.addEventListener('gmp-load', async () => { const location = detailsElement.place.location; detailsElement.style.display = "block"; advancedMarkerElement.position = location; advancedMarkerElement.content = detailsElement; if (detailsElement.place.viewport) { map.fitBounds(detailsElement.place.viewport); } else { map.setCenter(location); map.setZoom(17); } }); } initMap();
CSS
html, body { height: 100%; margin: 0; padding: 0; } #map-container { display: flex; flex-direction: row; height: 100%; } #gmp-map { height: 100%; } gmp-basic-place-autocomplete { position: absolute; height: 50px; top: 10px; left: 10px; z-index: 1; box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.2); color-scheme: light; border-radius: 10px; } gmp-place-details-compact { width: 360px; max-height: 300px; border: none; padding: 0; margin: 0; position: absolute; transform: translate(calc(-180px), calc(-215px)); box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.2); color-scheme: light; } /* This creates the pointer attached to the bottom of the element. */ gmp-place-details-compact::after { content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); width: 0; height: 0; border-left: 16px solid transparent; border-right: 16px solid transparent; border-top: 20px solid var(--gmp-mat-color-surface, light-dark(white, black)); }
HTML
<html> <head> <title>Place Autocomplete map</title> <link rel="stylesheet" type="text/css" href="./style.css" /> <script type="module" src="./index.js"></script> </head> <body> <div id="map-container"> <gmp-basic-place-autocomplete></gmp-basic-place-autocomplete> <gmp-place-details-compact orientation="horizontal"> <gmp-place-details-place-request></gmp-place-details-place-request> <gmp-place-all-content></gmp-place-all-content> </gmp-place-details-compact> <gmp-map zoom="14" map-id="DEMO_MAP_ID"> <gmp-advanced-marker></gmp-advanced-marker> </gmp-map> </div> <!-- 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: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</script> </body> </html>