本指南详细介绍了 3D 地图 Web 组件以及与应用集成时的注意事项。
性能考虑因素
为确保互动和视觉元素提供流畅且响应迅速的体验,请考虑以下方法。
加载地图
3D 地图的初始加载和渲染设置结合了浏览器配置技术和界面最佳实践,可提供最佳用户体验。
- API 加载:使用 3D 地图异步动态加载,在初始网页加载时加载 Maps JavaScript API。
- 库:在需要时以编程方式加载库,例如
google.maps.importLibrary("maps3d")。或者,如果您通过直接脚本加载在 HTML 页面中直接使用<gmp-map-3d>等 Web 组件,这些库会在适当的时间自动加载 - 管理底图地图项:使用自定义 mapId 过滤底图地图注点(混合模式),并控制其密度,尤其是在应用有自己的一组自定义元素(例如标记或多段线)时。这样可以避免视觉混乱和潜在的重叠。或者,您也可以停用基本地图矢量图块功能,例如地图注点、道路多段线、道路名称、街道名称(卫星模式)。
- 事件:监听 gmp-steadystate 或 gmp-error 事件,以构建后续逻辑,例如加载标记、为镜头添加动画效果。
用户互动:等待 gmp-steadystate 事件发生,然后再更改地图内容。如果用户在初始 gmp-steadystate 事件发生之前开始与地图互动(平移、缩放),则该事件仅在用户停止互动后触发。避免在用户平移或缩放地图时显示或更新叠加层内容(例如标记或多边形),避免通过监听 gmp-centerchange、gmp-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 地图 (SATELLITE),其中仍包含您的地理数据(例如标记)。
- 或者,您也可以在卫星模式下显示一个辅助 2D 静态地图,以便用户在加载时直观地查看给定地点。
视觉元素效果和管理
3D 地图提供了多种方式来显示标记、多段线和 3D 模型等视觉元素,即使视觉元素数量较多,也能以最佳性能和最短渲染时间显示。
标记
- 最佳自定义选项:
- PinElement:对于基本标记更改(颜色、缩放比例、边框、文本字形),请使用
<gmp-pin>元素或PinElement类。这是性能最佳的自定义方法。 - 谨慎使用 HTMLImageElement 或 SVGElement 标记:用于进行更多自定义,例如添加透明度或将图标等图片注入 SVGElement(需要 base64 编码)。它们会在加载时进行光栅化,并涉及性能开销。HTMLImageElement 和 SVGElement 必须封装在
<template>元素中,然后才能分配给 Marker3DElement 的默认槽。 - 目前无法添加纯 HTML 或 CSS。
- PinElement:对于基本标记更改(颜色、缩放比例、边框、文本字形),请使用
- 管理冲突行为:利用标记的 collisionBehavior 属性。对于必须始终可见的关键标记,请相应地设置行为。对于不太重要的标记,允许其隐藏,以保持更简洁、更清晰的地图体验,尤其是在高缩放级别下。
- 仅限关键地图注点:仅对绝对必须透过建筑物或地形看到的标记(例如救援目标、埋藏的公用设施管线或用户头像)使用 drawsWhenOccluded(或以编程方式设置该属性)。
- 测试遮挡:由于地图是 3D 的,标记可能会被建筑物或地形遮挡。测试不同的相机角度和标记海拔高度,以确保关键地图注点始终可见,或实现相关逻辑,以便在被遮挡时调整可见性和海拔高度。
- 利用海拔高度:在 3D 地图中,标记应使用具有海拔高度值的位置。对于与地形或建筑物关联的标记,请使用 altitudeMode: 'RELATIVE_TO_GROUND'、'RELATIVE_TO_MESH' 或类似设置,以确保在地图倾斜或旋转时标记能正确锚定。
多边形和多段线
- 简化几何图形:在渲染之前,对路径数据应用简化算法。这样可以减少顶点数量,同时保留大致形状,从而大幅提高渲染速度,尤其是在处理复杂的边界或路线时。
- 按缩放级别抽取:对于非常大的数据集,请考虑仅在用户放大到相应区域时加载更详细的几何图形。在低缩放级别下,只需使用高度简化的多段线或多边形。
- 针对拉伸多边形进行预计算:如果多边形是拉伸 (
extruded: true) 的,则路径数据会定义一个三维体积(网格)。处理复杂的多顶点多边形需要消耗大量计算资源。 确保多边形的源数据尽可能简单。 - 测试多段线和多边形性能:添加大量或复杂的多段线/多边形时,尤其是在为 3D 效果进行拉伸时,请确保它们不会导致帧速率下降。限制顶点数量,或在必要时使用简化算法。
- 更新形状时,请在单次操作中修改整个路径数组,而不是循环修改各个元素。单次赋值操作(例如 polyline.path = newPathArray;)比多次迭代更新要高效得多。
- 避免使用挤出多段线(尽可能):虽然多段线可以使用高度值放置在 3D 空间中,但挤出多段线(例如,为其指定描边宽度和较大的高度跨度)可能会占用大量图形资源。尽可能使用地面上的 2D 多段线 (RELATIVE_TO_GROUND) 或最小描边宽度,以获得更好的性能。
- 仅对关键路线元素使用 drawsOccludedSegments。对于背景或上下文形状,允许它们被地图的 3D 几何图形自然遮挡。显示非关键隐藏几何图形会增加不必要的渲染复杂性。
3D 模型
在 <gmp-map-3d> 中,3D 模型 .glb 渲染和互动(例如 gmp-click 事件)非常快。
- 通过压缩尽可能缩减文件大小:为确保快速加载(尤其是在移动网络上),请将复杂的 .glb 模型文件的大小控制在 5MB 以下(最好更小)。 实现此目标的主要方法是对 .glb 文件中的网格数据应用 Draco 压缩,这样可以显著减小文件大小(通常超过 50%),同时最大限度地减少视觉质量损失。
- 将模型原点居中:确保 3D 建模软件在导出模型时,将原点(0、0、0 点)置于模型底部的中心位置。这样可以简化地图上的定位和旋转,确保模型正确锚定到纬度、经度坐标。
- 管理 CORS:如果您的模型文件托管在与 Web 应用不同的网域或 CDN 上,则必须配置托管服务器,使其包含必要的跨域资源共享 (CORS) 标头(例如 Access-Control-Allow-Origin: *)。否则,地图将无法加载模型。