了解 3D 地图中的海拔模式和功能

为 3D 地图上的要素(例如线条、多边形、模型或标记)指定海拔高度时,有多种因素可能会影响这些要素的放置位置,包括在场景中的位置以及场景的渲染方式与相应要素的互动方式。本文档介绍了如何在 3D 地图上使用 AltitudeMode 以及如何管理地图项的高度。

以下展示了如何将 AltitudeMode 与多种特征类型搭配使用:

如何在 3D 环境中使用海拔高度

在 3D 场景中放置点时,其最终位置会受到捕获的 3D 建筑物或树木等对象的影响。务必了解以下两个关键概念:

  • 数字地形模型 (DTM):表示“裸地”海拔。您可以将其视为没有任何建筑物、树木或其他结构的自然地貌。所有区域均以 DTM 为基础,而 DTM 构成了地球海拔高度的基础(使用 EGM96 计算)。
  • 数字表面模型 (DSM):表示“顶面”高程,包括建筑物、树木和其他结构。在已拍摄到地貌特征的区域(尤其是建筑物占据大部分视野的城市环境),可见地表将高于基本地形。

DTM 和 DSM 之间的区别对于了解不同的海拔模式如何与这些数字高程模型 (DEM) 互动至关重要,因为地表模型可能会遮挡或影响地物的放置位置。下图显示了这些差异:

一张 3D 地图,显示了数字地形模型 (DTM) 和数字地表模型 (DSM) 之间的区别。

当要素缺少海拔数据时

如果您的数据缺少海拔高度测量值,或者您使用的是来自其他 Google 服务(例如路线或地点服务)的数据,那么返回的几何图形中通常不会提供任何海拔高度。在这种情况下,将功能放置在场景中需要您仔细选择 AltitudeMode

  • 固定到地面:最简单的方法,功能将自动与地形保持一致。此模式使用 DTM 模型。
  • 为其指定任意海拔高度 + 相对模式:您可以指定所选海拔高度,然后使用 RELATIVE_TO_GROUND(将要素放置在相对于 DTM 模型的位置)或 RELATIVE_TO_MESH(将要素放置在 DSM 模型上方)。
  • 使用其他服务获取海拔高度:如需获取地物位置的精确 DTM 海拔高度,您可以使用 Google Maps Platform Elevation API 等服务。 如果是线或多边形,您需要对构成线或多边形的每个点执行此操作。

AltitudeMode 选项的含义以及何时使用这些选项?

定义功能时,您可以指定以下四种 AltitudeMode 选项:

绝对

假设一架飞机在海平面以上特定高度(例如 10,000 英尺)飞行。无论是在山顶还是在山谷中飞行,其高度都是固定的。

使用方法:对象海拔高度以相对于平均海平面(使用 EGM96 计算)的高度表示。相应功能的海拔高度坐标会被解读为高于平均海平面的精确海拔高度。

何时使用:对于具有已知精确海拔高度的要素,例如飞行路线、具有精确深度的水下物体或固定点科学仪器。

CLAMP_TO_GROUND

想象一下,您将野餐毯直接铺在山坡上。无论山坡有多陡峭或平缓,毯子始终平铺在可见表面上。

使用方法:对象海拔高度以直接放置在地面上为准。无论提供任何海拔高度值,它们都将保持在地面高度,并随地形变化而变化。系统会忽略该要素的高度坐标,并将其直接投影到地形表面 (DTM)。

何时使用:对于应始终与地形保持一致的要素,例如道路、围栏、小径、地界或建筑物底部。

RELATIVE_TO_GROUND

想象一下,热气球始终保持在下方自然地面海拔高度 (DTM) 上方 100 米处。如果地面上升,气球也会随之上升,始终与“裸露地面”保持 100 米的距离。

使用方法:对象海拔高度以相对于地面(数字地形模型 [DTM])的高度表示。相应功能的海拔高度坐标会被解读为相对于其水平位置的地形海拔高度的偏移量。

使用场景:对于需要保持高于自然地形的恒定高度的对象,例如农村地区的通信塔或架空线路。

RELATIVE_TO_MESH

这就像无人机在飞越任何物体(无论是裸露的地面、建筑物屋顶还是树顶)时都保持固定的高度。它会调整为最高可见表面 (DSM)。

使用方法:对象海拔高度是相对于地面+建筑物+水面(数字表面模型 [DSM])的最高点来表示的。相应要素的海拔高度坐标被解读为与 DSM 海拔高度的偏移量。

使用场景:对于需要悬浮在任何实际存在的事物(数字地形模型、建筑物、水)上方一定高度的对象,此模式非常有用,可用于屋顶上的标记或可根据可见场景动态调整的要素。

如需了解详情,请参阅 AltitudeMode 常量的文档。

直观示例和实际应用

这些示例使用特定位置(巨石阵)来说明不同的 AltitudeMode 选项如何影响功能放置。这些示例首先介绍了位置标记,然后介绍了线条和区域,这两者有一些不同的注意事项。

位置标记

假设放置的图钉标记如下所示:

const markerLocation = { lat: 51.1789, lng: -1.8262, altitude: 102.23 };

您可以在下方的场景中看到这个白色图钉:

一个带有白色图钉标记的 3D 地图场景,用于说明标记的默认放置位置。

现在,请看下图,其中显示了使用不同海拔高度模式定位的各种颜色的图钉。

一个 3D 地图场景,显示了使用不同海拔模式定位的多个图钉(白色、紫色、橙色、蓝色),所有图钉都以巨石阵为中心。

我们来看看不同的 AltitudeMode 如何影响标记的定位(按海拔升序排列)。

CLAMP_TO_GROUND(紫色图钉)

此图钉会忽略海拔高度值,并附着到最近的地面海拔高度。您可以在白色图钉下方看到它,它会有效地“夹紧”地形。

从技术上讲,此模式会忽略实际海拔高度,并将图钉固定到最近的 DTM 高度。

ABSOLUTE(白色针)

此图钉使用确切的海拔值 (102.23 米) 将标记放置在高于海平面 (EGM96) 的该高度,并按照其提供的海拔高度显示在巨石阵的其中一块石头上。

从技术上讲,此模式使用实际提供的高度值将图钉放置在指定的海拔高度,在此示例中,该高度是巨石阵的位置,但位于其中一块巨石的顶部。

RELATIVE_TO_GROUND(橙色针脚)

此图钉以地面 (DTM) 为基础,放置在地面上方 102.23 米处,看起来像是漂浮在巨石阵中巨石下方的天然地面上。

从技术上讲,此模式会将基准设置为地面上实际 DTM 的高度,然后将图钉放置在高于该基准 102.23 米的位置。

RELATIVE_TO_MESH(蓝色图钉)

此图钉使用可见表面 (DSM) 作为其基础,并放置在该表面上方 102.23 米处。此模式会在测量中纳入球杆头的高度,使其略高于橙色球杆。

从技术上讲,此模式使用网格 (DSM) 作为基础,并将位置放置在高于该基础的指定海拔高度。由于 DSM 位于立石的顶部,因此此图钉在确定其相对高度时会在测量中包含此额外高度,从而使其略高于 RELATIVE_TO_GROUND 图钉。

定位线条和区域

对于线和面,特征内点的高度(无论是否指定)和所用的 AltitudeMode 都至关重要。我们来检查一下沿巨石阵的一条线,并指定以下高度:

const lineCoords = [
   { lat: 51.1786, lng : -1.8266, altitude: 101.36 },
   { lat: 51.1787, lng : -1.8264, altitude: 101.18 },
   { lat: 51.178778, lng : -1.826354, altitude: 104.89 },
   { lat: 51.178815, lng : -1.826275, altitude: 107.55 },
   { lat: 51.178923, lng : -1.825980, altitude: 105.53 },
   { lat: 51.1791, lng : -1.8258, altitude: 100.29 },
   { lat: 51.1792, lng : -1.8257, altitude: 100.29 }
];

您可以在下图中使用绝对定位的白色线条看到这条线。

一张 3D 地图,显示了使用绝对定位功能在巨石阵周围放置的一条白线。

下图再次展示了使用不同海拔模式绘制的线条。 下面我们从最低到最高依次讨论每种级别。

一张 3D 地图,显示了使用不同海拔模式在巨石阵周围放置的多条彩色线条(紫色、白色、橙色、蓝色)。

CLAMP_TO_GROUND(紫线)

此行会忽略每个点指定的海拔高度,而是将线路直接“覆盖”在下方的地面 (DTM) 上。它会跟随地形,忽略其上方的任何地貌特征(例如建筑物或石头)。

从技术上讲,此模式会忽略实际海拔高度值,并使线路覆盖在 DTM 上,遵循下方的地形,忽略上方的要素网格。

绝对(白线)

此线条使用每个点的确切海拔高度,导致线条越过了一些石头。它通过直线连接各个点,如果点不够密集,有时会显得穿过物体。

从技术上讲,此模式会遵循每个点指定的海拔高度,并用直线将它们连接起来,这意味着如果海拔高度值指示,它可以穿过网格(例如石头)。本教程的后续部分将介绍此使用场景。

RELATIVE_TO_GROUND(橙线)

此线以自然地面 (DTM) 为基础,并将每个点放置在高于该地面高度的指定海拔高度。

从技术上讲,此模式使用 DTM 作为基础,并将线路位置放置在相对于 DTM 的所列海拔高度处。

RELATIVE_TO_MESH(蓝线)

此线使用包括建筑物和石头在内的可见表面作为其基础。然后,它会将每个点放置在网格上方指定的海拔高度,从而有效地复制相对于可见景观的线条形状。

从技术上讲,此模式使用网格 (DSM) 作为基础,并将位置放置在指定海拔高度之上,具体取决于网格,线路可能会因地面上的不同特征而发生变化。

未为线路指定海拔高度时

现在,我们来考虑相同的线路坐标,但指定任何海拔高度:

const lineCoords = [
   { lat: 51.1786, lng : -1.8266 },
   { lat: 51.1787, lng : -1.8264 },
   { lat: 51.178778, lng : -1.826354 },
   { lat: 51.178815, lng : -1.826275 },
   { lat: 51.178923, lng : -1.825980 },
   { lat: 51.1791, lng : -1.8258 },
   { lat: 51.1792, lng : -1.8257 }
];

在这种未提供海拔高度的情况下,线条通常会显示在相似的位置。白色、橙色和紫色线条可能会合并为一条线条(橙色,因为通常最后绘制的是橙色线条),因为它们默认都采用类似的地平面定位。您可以在下方看到此信息:

一张 3D 地图,显示了巨石阵周围的多条彩色线条(橙色、蓝色),其中白色和紫色线条因缺少海拔数据而合并。

蓝线 (RELATIVE_TO_MESH) 再次使用网格 (DSM) 作为基础。 由于未指定海拔高度,因此它只是将点直接叠加在网格之上。请务必注意,它不会在网格上绘制线条,而是通过直线连接网格上指定的点。虽然在某些示例中,这种做法看起来可以接受,但如果被其他功能覆盖,可能会导致可见性问题。下一部分将介绍此问题。

网格和线条的互动。 现在,我们可以看看另一条折线。此图片与上图位于同一区域,但地面覆盖范围更广(或 DTM 顶部的 DSM 包含更多细节)。

const lineCoords = [
    { lat: 51.188404, lng: -1.779059, altitude: 70.69 },
    { lat: 51.187955, lng: -1.780143, altitude: 77.25 },
    { lat: 51.187658, lng: -1.781552, altitude: 68.97 },
    { lat: 51.187376, lng: -1.782447, altitude: 99.02 },
    { lat: 51.186912, lng: -1.783692, altitude: 104.35 },
    { lat: 51.185855, lng: -1.788368, altitude: 86.91 },
];

如果我们使用与之前相同的方法(和颜色)来表示,则会得到以下视图:

一张 3D 地图,显示了树木和海拔高度各异的地形上方的多条彩色线条(紫色、白色、橙色、蓝色)。

紫色是 CLAMP_TO_GROUND,您可以看到它沿着地面移动。白色是绝对位置,您可以看到直线连接了空间中的绝对位置点。由于橙色和蓝色是与地表(DTM)或网格(DSM)相关的相对版本,因此请注意,由于下方地貌的高度,蓝线的形状略有不同。

同样,我们可以注意到,由于直线是通过直线将点连接在一起而创建的,因此直线会穿过网格。这种情况可能会导致无法看到线条,因此您可以将 drawsOccludedSegments 设置为 true,以确保线条能够透过树木显示,如下面的图片所示,穿过网格的线条仍然可见。

一幅 3D 地图,显示穿过树木的线条,其中被遮挡的线段会显示出来,以说明线段的遮挡情况:true。

空间中定位的性质意味着点可能位于网格内,连接点的线也可能位于网格内,从而可能导致视觉伪影。在下文中,我们可能会看到如何尽可能改进此类制品。

解决线条与地形之间的互动问题

在另一个示例中,在同一区域,我们可以看到一些其他伪影,在使用特定高度模式时必须注意这些伪影。

这里有一个相对平坦的区域,主要位于 DTM 级别,网格中高于该级别的额外细节有限。如果某个区域的地形模型上方没有 3D 覆盖范围,也会出现这种情况。我们来看一下以下位置(如下所示):

const lineCoords = [
   { lat: 51.194642, lng: -1.782636, altitude: 99.10 },
   { lat: 51.193974, lng: -1.783952, altitude: 99.86 },
   { lat: 51.192203, lng: -1.787175, altitude: 96.14 },
   { lat: 51.190024, lng: -1.790250, altitude: 105.92 },
   { lat: 51.187491, lng: -1.793580, altitude: 102.60 },
   { lat: 51.183690, lng: -1.798745, altitude: 95.69 },
];

如图所示,各条线的颜色表示与之前相同:(白色:ABSOLUTE,蓝色:RELATIVE_TO_MESH,紫色:CLAMP_TO_GROUND,橙色:RELATIVE_TO_GROUND)。

一张 3D 地图,显示了相对平坦的地形上各种颜色的线条(白色、蓝色、紫色、橙色),突出显示了线条消失在地下的视觉伪影。

在这里,我们可以看到一些伪影,首先是由于缺少表面覆盖,橙色 (RELATIVE_TO_GROUND) 和蓝色 (RELATIVE_TO_MESH) 线位于(大部分)同一位置(蓝色线最后绘制,因此显示出来)。

我们还可以看到,紫色(CLAMP_TO_GROUND)线沿着地面,可以在山丘上看到,而白色(ABSOLUTE)线似乎消失在山丘中,因为只有点连接在一起,直线穿过地面。

当紫色线条被隐藏时,您可以在此图片中看到这一点。

一张 3D 地图,显示了消失在山丘中的白色和蓝色线条,以及隐藏的紫色线条,用于说明绝对线条和相对于网格的线条的视觉伪影。

因此,这可能会导致一些奇怪的视觉伪影,即当点之间的线只是沿着直线路径移动时,可以看到该线消失在地面下(甚至穿过网格)。您或许可以通过使用插值方法在这些线条之间添加更多点来改善此类线条的视觉显示效果,但这种做法对视觉效果的影响将再次取决于所用的方法:

  • 对于相对测量(RELATIVE_TO_GROUND 或 RELATIVE_TO_MESH):使用相对海拔高度值时,沿直线或多边形创建更多点将有助于将功能放置在更合适的高度,从而更好地符合海拔高度剖面。如果您的数据中没有这些中间点,您可以使用插值函数(例如 Google Maps Platform Geometry 库中的 Interpolate 函数)来添加它们。然后,可以为这些新点指定相对值,这些值将放置在相关海拔剖面图上方,然后限制连接这些点的任何线的长度,从而改进视觉呈现效果。
  • 对于绝对特征 (ABSOLUTE):对于绝对特征,需要更多点具有实际海拔高度值。在现有绝对值之间进行插值不会得到能准确反映网格上方任何值的点,因为这只会是点 A 和点 B 之间的平均值。

摘要

希望本文档能让您全面了解写实 3D 地图中的 AltitudeMode 选项,详细说明 ABSOLUTE、CLAMP_TO_GROUND、RELATIVE_TO_GROUND 和 RELATIVE_TO_MESH 如何影响标记、线条和多边形等各种要素的放置和渲染。

了解这些模式如何与基础数字地形模型 (DTM) 和数字地表模型 (DSM) 协同工作,对于创建准确且具有视觉吸引力的 3D 地图表示形式(同时最大限度地减少视觉伪影)至关重要。

我们希望您能在自己的项目中尝试这些海拔模式,充分发挥 3D 地图的潜力,为用户打造引人入胜的沉浸式体验,并提供反馈。

贡献者

Matt Toon | 地理位置开发者解决方案工程师