使用 Places UI Kit 建構互動式店家搜尋器

目標

本文將逐步說明如何使用 Google 地圖平台 (特別是 Maps JavaScript API 和 Places UI Kit:地點詳細資料元素),開發互動式商店搜尋器應用程式。您將瞭解如何建立地圖來顯示商店位置、動態更新可見商店清單,以及顯示每間商店的豐富地點資訊。

必要條件

建議您先熟悉下列項目:

在專案中啟用 Maps JavaScript APIPlaces UI Kit

開始前,請確認您已載入 Maps JavaScript API,並匯入進階標記Places UI Kit 的必要程式庫。本文也假設您具備網頁開發工作知識,包括 HTML、CSS 和 JavaScript。

初始設定

第一步是在網頁中加入地圖。這張地圖會用來顯示與商店位置相關的圖釘。

在網頁中加入地圖的方式有兩種:

  1. 使用 gmp-map HTML 網頁元件
  2. 使用 JavaScript

請選擇最適合您用途的方法。本指南適用於這兩種地圖實作方式。

示範

這個示範影片顯示商店定位器運作的範例,顯示灣區的 Google 辦公室位置。系統會針對每個地點顯示 Place Details 元素,以及一些範例屬性。

載入並顯示商店位置

在本節中,我們會在 Google 地圖上載入並顯示商店資料。本指南假設您已擁有現有商店的資訊存放區,可從中提取資料。商店資料可來自各種來源,例如資料庫。在這個範例中,我們假設有一個本機 JSON 檔案 (stores.json),其中包含商店物件的陣列,每個物件代表一個商店位置。每個物件至少應包含 namelocation (含 latlng) 和 place_id

如果還沒有商店地點的 Place ID,可以透過多種方式擷取。詳情請參閱地點 ID 說明文件

stores.json 檔案中的商店詳細資料項目範例如下: 包含名稱、位置 (緯度/經度) 和地點 ID 欄位。有一個物件可保存商店營業時間 (已截斷)。此外,還有兩個布林值可協助說明商店位置的專屬功能。

{
  "name": "Example Store Alpha",
  "location": { "lat": 51.51, "lng": -0.12 },
  "place_id": "YOUR_STORE_PLACE_ID",
  "opening_hours": { "Monday": "09:00 - 17:00", "...": "..." },
  "new_store_design": true,
  "indoor_seating": false
}

在 JavaScript 程式碼中,擷取商店位置的資料,並在地圖上為每個位置顯示圖釘。

以下是操作範例。這個函式會接收包含商店詳細資料的物件,並根據每個商店的位置建立標記。

function displayInitialMarkers(storeLocations) {
    if (!AdvancedMarkerElement || !LatLng || !mapElement) return;
    storeLocations.forEach(store => {
        if (store.location) {
            const marker = new AdvancedMarkerElement({
                position: new LatLng(store.location.lat, store.location.lng),
                title: store.name
            });
            mapElement.appendChild(marker);
        }
    });
}

載入商店並在地圖上顯示代表商店位置的圖釘後,請使用 HTML 和 CSS 建立側欄,顯示個別商店的詳細資料。

這個階段的商店定位器可能如下所示:

圖片

監聽地圖可視區域變更

為提升效能和使用者體驗,請更新應用程式,只在相應位置位於可視地圖區域 (可視區域) 內時,才在側欄中顯示標記和詳細資料。這包括監聽地圖檢視區塊的變更、清除這些事件,然後只重新繪製必要的標記。

將事件監聽器附加至地圖的閒置事件。任何平移或縮放作業完成後,系統就會觸發這個事件,為您的計算提供穩定的檢視區塊。

map.addListener('idle', debounce(updateMarkersInView, 300));

上述程式碼片段會監聽 idle 事件,並呼叫 debounce 函式。使用防反彈函式可確保標記更新邏輯只會在使用者停止與地圖互動一小段時間後執行,進而提升效能。

function debounce(func, delay) {
    let timeoutId;
    return function(...args) {
        const context = this;
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => {
            func.apply(context, args);
        }, delay);
    };
}

上述程式碼是防反彈函式範例。這個函式會採用函式和延遲引數,這些引數會傳遞至閒置監聽器。300 毫秒的延遲時間足以等待地圖停止移動,不會對 UI 造成明顯延遲。這個逾時時間到期後,系統會呼叫傳遞的函式 (在本例中為 updateMarkersInView)。

updateMarkersInView 函式應執行下列動作:

清除地圖上的所有現有標記

檢查商店位置是否位於目前的地圖範圍內,例如:

if (map.getBounds().contains(storeLatLng)) {
  // logic
}

在上述 if 陳述式中,編寫程式碼來顯示標記,並在側邊欄中顯示商店詳細資料 (如果商店位置位於地圖檢視區塊內)。

使用地點詳細資料元素顯示豐富的地點詳細資料

在這個階段,應用程式會顯示所有商店位置,使用者可以根據地圖檢視區塊篩選商店。為強化這項功能,系統會使用 Place Details 元素,新增各商店的詳細資料,例如相片、評論和無障礙資訊。本範例特別使用地點詳細資料精簡元素

資料來源中的每個商店位置都必須有對應的地點 ID。這個 ID 是 Google 地圖上地點的專屬 ID,也是擷取地點詳細資料的必要條件。您通常會事先取得這些地點 ID,並針對每個商店記錄儲存這些 ID。

在應用程式中整合 Place Details Compact 元素

如果系統判斷商店位於目前的地圖檢視區塊內,且正在側欄中算繪,您可以動態建立並插入該商店的「地點詳細資料精簡元素」。

針對目前處理的商店,從資料中擷取地點 ID。地點 ID 用來控制元素顯示的地點。

在 JavaScript 中,動態建立 PlaceDetailsCompactElement 的例項。系統也會建立新的 PlaceDetailsPlaceRequestElement,並將地點 ID 傳遞至該物件,然後附加至 PlaceDetailsCompactElement。最後,使用 PlaceContentConfigElement 設定元素要顯示的內容。

下列函式會假設必要的 Place UI Kit 程式庫已匯入,且可在呼叫此函式的範圍中使用,並將 storeData 傳遞至函式包含 place_id

這個函式會傳回元素,呼叫程式碼則負責將元素附加至 DOM。

function createPlaceDetailsCompactElement(storeData) {
    // Create the main details component
    const detailsCompact = new PlaceDetailsCompactElement();
    detailsCompact.setAttribute('orientation', 'vertical'); // Or 'horizontal'

    // Specify the Place ID
    const placeRequest = new PlaceDetailsPlaceRequestElement();
    placeRequest.place = storeData.place_id;
    detailsCompact.appendChild(placeRequest);

    // Configure which content elements to display
    const contentConfig = new PlaceContentConfigElement();
    // For this example, we'll render media, rating, accessibility, and attribution:
    contentConfig.appendChild(new PlaceMediaElement({ lightboxPreferred: true }));
    contentConfig.appendChild(new PlaceRatingElement());
    contentConfig.appendChild(new PlaceAccessibleEntranceIconElement());
    // Configure attribution
    const placeAttribution = new PlaceAttributionElement();
    placeAttribution.setAttribute('light-scheme-color', 'gray');
    placeAttribution.setAttribute('dark-scheme-color', 'gray');
    contentConfig.appendChild(placeAttribution);
    detailsCompact.appendChild(contentConfig);
    // Return the element
    return detailsCompact;
}

在上方的範例程式碼中,元素已設定為顯示地點相片、評論評分和無障礙資訊。您可以新增或移除其他可用的內容元素,藉此自訂這項功能。如要瞭解所有可用選項,請參閱 PlaceContentConfigElement 說明文件。

Place Details Compact 元素支援透過 CSS 自訂屬性設定樣式。您可以自訂外觀 (顏色、字型等),配合應用程式的設計。在 CSS 檔案中套用這些自訂屬性。如需支援的 CSS 屬性,請參閱PlaceDetailsCompactElement參考說明文件。

此階段的應用程式範例:

圖片

強化商店搜尋器

您已為商店搜尋器應用程式奠定穩固基礎。現在,請考慮幾種擴充功能的方法,打造更豐富、更以使用者為中心的體驗。

新增自動完成

整合搜尋輸入內容與 Place Autocomplete,讓使用者更容易找到要搜尋商店的區域。當使用者輸入地址、鄰近地區或搜尋點,並選取建議時,請將地圖程式設為自動以該地點為中心,觸發附近商店的更新。方法是在輸入欄位中附加 Place Autocomplete 功能。選取建議後,地圖可以將該點置中。請記得設定偏好或限制結果的作業區域。

偵測位置

導入偵測使用者目前地理位置的功能,為使用者提供即時相關性,尤其是行動裝置使用者。取得瀏覽器權限以偵測使用者位置後,自動將地圖中心設為使用者所在位置,並顯示最近的商店。使用者在尋找即時選項時,非常重視這項「附近的」功能。新增按鈕或初始提示,要求存取位置資訊。

顯示距離和路線

使用者找到感興趣的商店後,整合 Routes API 即可大幅提升使用者體驗。針對列出的每間商店,計算並顯示與使用者目前位置或搜尋位置的距離。此外,請提供按鈕或連結,使用 Routes API 從使用者位置產生前往所選商店的路徑。然後在地圖上顯示這條路線,或連結至 Google 地圖進行導航,讓使用者從尋找商店到實際抵達目的地,都能順利完成。

導入這些擴充功能後,您就能運用 Google 地圖平台更多功能,打造更全面且便利的商店定位器,直接滿足常見的使用者需求。

結論

本指南已說明如何建構互動式商店搜尋器。您已瞭解如何使用 Maps JavaScript API 在地圖上顯示自己的商店位置、根據可視區域的變化動態更新顯示的商店,以及如何與 Places UI Kit 一併顯示自己的商店資料。使用 Place Details 元素搭配現有商店資訊 (包括地點 ID),即可為每個地點提供豐富的標準化詳細資料,為方便使用的店家搜尋器奠定穩固基礎。

試試 Maps JavaScript APIPlaces UI Kit,運用強大的元件式工具,快速開發精密的定位應用程式。結合這些功能,即可為使用者打造引人入勝的實用體驗。

貢獻者

Henrik Valve | DevX 工程師