3D 地图最佳实践

本指南详细介绍了 3D 地图 Web 组件,以及在与应用集成时需要考虑的事项。

地点搜索和路线查找的示例使用情形。
地点搜索和路线查找示例。

性能考虑因素

为确保互动和视觉元素提供流畅且响应迅速的体验,请考虑以下方法。

加载地图

3D 地图的初始加载和渲染设置结合了浏览器配置技术和界面最佳实践,以实现最佳用户体验。

  • API 加载:使用 3D 地图异步动态加载,以便在初始网页加载时加载 Maps JavaScript API。
  • :根据需要以编程方式加载库,例如 google.maps.importLibrary("maps3d")。���者,如果您在 HTML 页面中直接使用 Web 组件(例如 <gmp-map-3d>)并使用直接 脚本 加载, 则库会在适当的时间自动加载
  • 管理基本地图功能 :使用自定义 mapId 过滤基本地图 POI(混合模式),并控制其密度,尤其是在应用有自己的一组自定义元素(例如标记或多段线)的情况下。这样可以防止视觉杂乱和潜在的重叠。或者,您可以停用基本地图矢量图块功能,例如 POI、道路多段线、道路名称、街道名称(卫星模式)。
  • 事件:监听 gmp-steadystategmp-error 事件,以构建后续逻辑,例如加载标记、为相机添加动画效果。
地图加载顺序
背景画布 > 缩减大小的图块 > 地形网格 > 表面网格(例如建筑物)> 地图注点和道路标签,并行加载自定义元素(标记、3D 模型等)
  • 用户互动:等待 gmp-steadystate 事件,然后再更改地图的内容。如果用户在初始 gmp-steadystate 事件之前开始 与地图互动(平移、缩放),则该事件仅在用户停止互动后触发。避免在用户平移或缩放地图时显示或更新叠加层内容(例如标记或多边形) ,避免通过监听 gmp-centerchangegmp-headingchange gmp-rangechange gmp-rollchange gmp-tiltchange来显示或更新叠加层内容(例如标记或多边形)。

  • 使用 requestAnimationFrame() (rAF) 进行持续更新,并 严格将密集型计算与绘制调用分开。

    • 使用 rAF:将更新与浏览器的显示速率同步,以实现流畅的 60FPS 动画并降低功耗。
    • 避免密集型绘制工作:请勿在最终更新期间执行繁重的非绘制任务。
    • 分离逻辑:在 rAF 循环中进行最少的 Web 组件更新调用之前,执行所有密集型逻辑。
  • 初始场景设置<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 的默认插槽。
    • 目前无法添加纯 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 模型(200KB)大约需要 2 秒。(现代笔记本电脑:macOS M3 Pro、Chrome)
  • 通过压缩最大限度地减小文件大小:为确保快速加载,尤其是在 移动网络上,请将复杂的 .glb 模型文件保持在 5MB 以下(最好更小)。 实现此目的的主要方法是对 .glb 文件中的网格数据应用 Draco 压缩,这样可以显著减小文件大小(通常超过 50%),同时视觉质量损失极小。
  • 模型原点居中 :确保 3D 建模软件导出模型时,其原点(0, 0, 0 点)位于模型底部中心。这样可以简化地图上的定位和旋转,确保模型正确锚定到纬度、经度坐标。
  • 管理 CORS:如果您的模型文件托管在与 Web 应用不同的网域或 CDN 上,则必须配置托管服务器以包含必要的跨源资源共享 (CORS) 标头(例如,Access-Control-Allow-Origin: *)。否则,地图无法加载模型。