3D 地圖最佳做法

本指南將詳細介紹 3D 地圖網頁元件,以及整合至應用程式時的注意事項。

地點搜尋和路線查詢的實務應用範例。
地點搜尋和路線查詢範例。

效能注意事項

為確保互動和視覺元素能提供流暢且反應靈敏的體驗,請考慮下列方法。

載入地圖

3D 地圖的初始載入和算繪設定結合了瀏覽器設定技術和 UI 最佳做法,可提供最佳使用者體驗。

  • API 載入:使用 3D 地圖非同步動態載入,在初始網頁載入時載入 Maps JavaScript API。
  • 程式庫:視需要以程式輔助方式載入程式庫,例如 google.maps.importLibrary("maps3d")。或者,如果您在 HTML 網頁中直接使用 <gmp-map-3d> 等網頁元件,並直接載入指令碼,系統會在適當時間自動載入程式庫
  • 管理基本地圖功能:使用自訂 mapId 篩選基本地圖搜尋點 (混合模式),並控管搜尋點密度,特別是當應用程式有自己的自訂元素集 (例如標記或折線) 時。這樣可避免視覺混亂和潛在重疊。或者,您也可以停用底圖向量圖塊功能,例如搜尋點、道路折線、路名、街名 (衛星模式)。
  • 事件:監聽 gmp-steadystategmp-error 事件,建構後續邏輯,例如載入標記、為攝影機製作動畫。
地圖載入順序
背景畫布 > 縮小圖塊 > 地形網格 > 表面網格 (例如:建築物) > 搜尋點和道路標籤,並行載入自訂元素 (標記、3D 模型等)
  • 使用者互動:等待 gmp-steadystate 事件,再變更地圖內容。如果使用者在初始 gmp-steadystate 事件觸發前開始與地圖互動 (平移、縮放),則事件只會在使用者停止互動後觸發。避免在使用者平移或縮放地圖時顯示或更新疊加層內容 (例如標記或多邊形),請監聽 gmp-centerchangegmp-headingchangegmp-rangechangegmp-rollchangegmp-tiltchange,避免顯示或更新疊加層內容 (例如標記或多邊形)。

  • 使用 requestAnimationFrame() (rAF) 持續更新,並嚴格區分密集計算和繪圖呼叫。

    • 使用 rAF:將更新與瀏覽器的顯示速率同步,以實現流暢的 60 FPS 動畫,並降低耗電量。
    • 避免大量繪圖作業:在最後更新期間,請勿執行大量非繪圖工作。
    • 分離邏輯:在 rAF 迴圈中進行最少的網頁元件更新呼叫之前,請先執行所有密集邏輯。
  • 初始場景設定<gmp-map-3d> 傾斜等攝影機設定會影響載入速度。場景縮放或傾斜的程度越大,顯示的詳細多邊形就越多,需要載入的資料也越多。詳細程度也會因地點而異 (例如:建築物林立的城市與只有自然地貌的鄉村)。

    • 建議使用縮放程度較小 (高海拔)、傾斜度較小或沒有傾斜的檢視畫面。
    • 在地圖中新增界線 (範例),讓使用者專注於特定區域,並完整載入圖塊。
  • 預先載入器視覺效果<gmp-map-3d> 的載入速度極快,但對於使用低階裝置 (GPU 效能較低) 或頻寬較慢 (4G 速度較慢) 的使用者來說,可能需要一段時間才能以完整解析度顯示。在本例中,您可以建立預先載入器,其中包含圖片、動畫或文字,而 3D 場景會在背景載入。請參閱下方可用的重要事件:

友善載入器範例
預先載入器範例
// create the map in the background and wait for gmp-steadystate event
async function initMap() {
    await google.maps.importLibrary("maps3d");
    const map = document.querySelector('gmp-map-3d');
    const div = document.querySelector('div'); // preloader "
    map.addEventListener('gmp-steadystate', ({isSteady}) => {
        if (isSteady) {
            div.style.display = 'none';
        }
    });
}
initMap();
  • 2D 地圖:
    • 系統可以向這些使用者提供替代的 2D 地圖 (衛星),同時仍會納入標記等地理資料。
衛星地圖範例
  • 或者,您也可以在載入期間顯示互補的 2D 靜態地圖,讓使用者以衛星模式查看特定地點。

視覺元素成效與管理

3D 地圖提供多種方式來顯示標記、折線、折線和 3D 模型等視覺元素,即使是大量視覺元素,也能以最佳效能和最短時間完成算繪。

標記

標記載入範例
情境範例:載入 300 個標記,其中包含 41 種不同的 SVG 標記字形,需時 150 到 300 毫秒 (現代筆電:macOS M3 Pro、Chrome)
  • 最佳自訂選項
    • PinElement:如要變更基本標記 (顏色、比例、邊框、文字字形),請使用 <gmp-pin> 元素或 PinElement 類別。這是效能最佳的自訂方法。
    • 謹慎使用 HTMLImageElement 或 SVGElement 標記:用於更多自訂項目,例如新增透明度或將圖片 (例如圖示) 插入 SVGElement (需要 base64 編碼)。這些圖片會在載入時點陣化,並造成效能負擔。HTMLImageElement 和 SVGElement 必須先包裝在 <template> 元素中,才能指派給 Marker3DElement 的預設 slot。
    • 目前無法新增純 HTML 或 CSS。
  • 管理衝突行為:善用標記的 collisionBehavior 屬性。如要讓重要標記一律顯示,請據此設定行為。對於重要性較低的標記,允許隱藏這些標記,以維持更乾淨、更整潔的地圖體驗,尤其是在高縮放等級下。
  • 僅限重要興趣點:只有在標記必須穿透建築物或地形顯示時 (例如救援目標、埋設的公用事業管線或使用者虛擬人偶),才使用 drawsWhenOccluded (或以程式輔助方式設定屬性)。
  • 測試遮蔽:由於地圖是 3D,標記可能會被建築物或地形遮蔽。測試不同的攝影機角度和標記高度,確保重要興趣點保持可見,或實作邏輯,在興趣點遭到遮蔽時調整可見度和高度。
  • 運用高度:在 3D 地圖中,標記應使用具有高度值的位置。如要將標記與地形或建築物建立關聯,請使用 altitudeMode: 'RELATIVE_TO_GROUND'、'RELATIVE_TO_MESH' 或類似設定,確保地圖傾斜或旋轉時,標記能正確錨定。

多邊形和折線

多邊形載入範例
範例情境:載入 1000 個多邊形需要 100 到 150 毫秒 (新式筆電:macOS M3 Pro、Chrome)
  • 簡化幾何圖形:在算繪路徑資料前,先套用簡化演算法。這項功能可減少頂點數量,同時保留一般形狀,大幅提升算繪速度,特別是複雜的邊界或路線。
  • 依縮放層級減少資料量:如果是非常龐大的資料集,建議只在使用者放大區域時載入詳細程度較高的幾何圖形。在低縮放層級,只需要折線或多邊形的高度簡化版本。
  • 預先計算凸出多邊形:如果多邊形是凸出 (extruded: true),路徑資料會定義 3D 體積 (網格)。處理複雜的高頂點多邊形需要大量運算資源。 確保多邊形的來源資料盡可能簡單。
  • 測試折線和多邊形效能:新增大量或複雜的折線/多邊形時,尤其是擠出 3D 效果時,請確保不會導致影格速率下降。如有需要,請限制頂點數量或使用簡化演算法。
  • 更新形狀時,請在單一作業中修改整個路徑陣列,而不是迴圈和修改個別元素。單一指派作業 (例如 polyline.path = newPathArray;) 的效率遠高於多次疊代更新。
  • 避免使用擠出多邊線 (盡可能):多邊線可使用海拔高度值放置在 3D 空間中,但擠出多邊線 (例如提供筆觸寬度和較大的海拔高度範圍) 可能會耗用大量圖形資源。請盡可能使用地面上的 2D 折線 (RELATIVE_TO_GROUND) 或最小筆觸寬度,以提升效能。
  • 僅針對重要路徑元素使用 drawsOccludedSegments。如果是背景或脈絡形狀,請允許地圖的 3D 幾何圖形自然遮蔽這些形狀。顯示非重要隱藏幾何圖形會增加不必要的算繪複雜度。

3D 模型

<gmp-map-3d> 可快速算繪 3D 模型 .glb,並提供 gmp-click 事件等互動功能。

3D 模型載入範例
情境範例:顯示 1000 個沿路徑移動的燈光 3D 模型 (200 KB) 大約需要 2 秒。(現代筆電:macOS M3 Pro、Chrome)
  • 壓縮檔案以縮減大小:為確保快速載入,特別是在行動網路上,請將複雜的 .glb 模型檔案大小控制在 5MB 以下 (最好更小)。主要方法是在 .glb 檔案中的網格資料上套用 Draco 壓縮,這樣就能大幅縮減檔案大小 (通常可減少 50% 以上),同時將視覺品質損失降到最低。
  • 將模型原點置中:確認 3D 建模軟體匯出模型時,原點 (0, 0, 0 點) 位於模型底部的中心。這可簡化地圖上的定位和旋轉作業,確保模型正確錨定至經緯度座標。
  • 管理 CORS:如果模型檔案與網頁應用程式託管於不同網域或 CDN,您必須設定主機伺服器,加入必要的跨來源資源共用 (CORS) 標頭 (例如Access-Control-Allow-Origin: *)。否則地圖無法載入模型。