在 UWP MapControl 中将点投影到 3D 地形表面

Posted

技术标签:

【中文标题】在 UWP MapControl 中将点投影到 3D 地形表面【英文标题】:Projecting points onto 3D terrain surface in UWP MapControl 【发布时间】:2020-05-29 07:10:15 【问题描述】:

我正在使用 UWP 地图控件 (MapControl) 和基于 this blog post 的墨迹创建 Windows 桌面应用程序。

我有基本的工作。可以在画布上绘制墨水并将它们转换为地图位置,但我无法将点正确投影到地图 3D 表面上。

我正在使用 mapControl.GetLocationFromOffset 将控制空间偏移转换为地图位置,但无论我使用什么 AltitudeReferenceSystem,这些点都在 3D 网格上方或下方偏移。我基本上是在尝试模拟墨迹在内置 Windows 地图应用程序中的工作方式。但由于在绘制每个笔画后都会暂停,我认为它正在对 3D 网格进行一些光线投射。纬度/经度是正确的,但高度有偏移。

Geopoint GeopointFromPoint(Point point)

   Geopoint geoPoint = null;
   this.map.GetLocationFromOffset(point, AltitudeReferenceSystem.Geoid, out geoPoint); // Tried all alt ref systems here
   return (geoPoint);

...
BasicGeoposition curP;
foreach (var segment in firstStroke.GetRenderingSegments())

   curP = GeopointFromPoint(segment.Position).Position;
   geoPoints.Add(curP);

...

这是我在地图应用程序中的一片草地上画的,它确定了正确的高度:

和同一个区域使用Map控件+GetLocationFromOffset,蓝色墨水是标注显示高度偏移:

如何将屏幕/控制空间坐标投影到 UWP Map 控件中的 3D 网格上并获得正确的高度?

编辑:答案是我是个白痴,一直在考虑距离地球中心的米太久,即我认为高度是地图位置的海拔高度,但是不是,是地图上方的点高度。因此,只需将高度设置为零即可。

【问题讨论】:

NP,上次我尝试过,我必须等待 2 天,但显然我现在可以做到 【参考方案1】:

仅将高度设置为零可能仍会产生意想不到的结果。对 GetLocationFromOffset 的调用是您的问题所在。 (您应该真正使用 TryGetLocationFromOffset BTW 并处理失败情况 - 并非总是可以将屏幕偏移映射到某个位置,例如当您在地平线上方单击时)。 您传递的 AltitudeReference 是告诉控件与什么相交。您可以将其视为您在该屏幕像素处向 3D 场景中拍摄的光线。射线将首先与表面相交,然后是地形,然后是大地水准面或椭球,具体取决于您所在的位置。您要求与大地水准面相交,这可能不是您真正想要的。您可能需要与墨箱表面的交点。文档并不清楚此参数的作用以及应该更新的内容。

如果您将所有高度重置为 0,并为您传入的线使用表面的高度参考,它将始终将线放在表面上,但这可能与您的墨水不匹配。

这里实际上可能存在一个错误 - 如果您上面的代码 sn-p 将从 GetLocationFromOffset 返回的 Geopoint 传递给折线,它应该出现在同一个像素处(您应该能够往返值)。这些 GeoPoints 返回的 AltitudeReferenceSystem 和值是什么?

【讨论】:

我尝试了所有不同的参考系统,都给出了相似的结果。我现在正在使用 TryGetLocationFromOffset。是的,使用 GetLocationFromOffset 获取地图位置与从给定参考系统返回高度和绘制标记等之间的预期高度略有差异,您只需提供一个高度,该高度是给定点高度的偏移量 ohhhh 可以将 AltitudeReferenceSystem 传递给 Geopath 构造函数。这按预期工作,但我仍然看到从墨水到地理路径的跳跃几米 Annnd 偏移是因为我的地图控件上方有一个 CommandBar。删除它,以便地图控件使用整个应用程序窗口,并且从 TryGetLocationFromOffset / Surface 返回的坐标与 Geopath /Surface 为 1:1。因此,无论是错误还是我的 xaml 都很麻烦,但它是一个非常简单的 xaml 文件。 听起来像是 XAML 布局问题。传递给 API 的偏移量是相对于地图控件窗口的,因此您的命令栏似乎覆盖了地图控件,导致偏移量与完整控件无关。 我同意这可能是 XAML 问题,但作为测试,我删除了命令栏,只是手动缩小了地图控件并获得了相同的结果。【参考方案2】:

第一个问题是在将墨迹笔划转换为地图多边形时,我没有将 AltitudeReferenceSystem 传递给 Geopath 构造函数。完成此操作后,您可以将 TryGetLocationFromOffset 的结果直接传递给多边形。

第二个可能是地图控件的错误。如果地图控件没有占据主窗口的整个高度,您会看到 TryGetLocationFromOffset 和墨迹笔划绘制位置之间存在像素偏移。

【讨论】:

需要注意的一点是,虽然 MapPolylines 可以正确处理高度,但 MapPolygons 却不能。将始终绘制到地形表面。

以上是关于在 UWP MapControl 中将点投影到 3D 地形表面的主要内容,如果未能解决你的问题,请参考以下文章

在 UWP 应用程序中单击 MapControl 时如何添加 MapIcon

如何从UWP Map上的MapIcon中删除点和尾

鼠标坐标到 3D 世界/投影以进行点碰撞

在OpenCV中将二维码投影到摄像头时,出现错误

如何在 uwp 中将图标添加到菜单栏

使用 PlatformConfiguration (Xamarin.Forms 2.3.3) 在 UWP 中将工具栏移动到底部