GPS 编程和开发历险记:地理空间教程

已发表: 2022-03-11

这一切都始于 10 多年前的 Zbevnica 徒步旅行。 我有我的新 GPS,我的一个朋友有一个连接到 Windows ME 手机的 GPS。 徒步旅行很棒,但是当我们回到车上时,我们惊讶地发现一个 GPS 声称我们已经走了 6.2 公里,而另一个报告了 6.7 公里。 一个人声称我们的海拔增加(即我们徒步旅行的所有上坡部分的总和)是 300m,而另一个人报告它是 500m。

作为一名程序员(最终成为一名 GIS 程序员),我立即对这个问题产生了兴趣。 我对自己说,“用一个简单的脚本来解决这个问题应该不难。” 毕竟,GPS 轨迹只是(latitude, longitude, elevation)形式的元组列表,对吧?

嗯,不是真的。

于是我开始了对 GPS 轨迹、跟踪错误以及更普遍的 GIS 编程的迷人世界的游览。

地理空间信息系统 (GIS) 是一个庞大而复杂的领域,包括地图投影和大地基准))、光栅和矢量数据处理以及遥感。 对该领域的全面介绍将远远超出本文的范围。 由于专注于特定问题通常是一种将自己介绍给新领域的有用方式,因此我将介绍一些我遇到的特定 GIS 挑战和一些可能的解决方案; 即:

  • 如何识别、理解和以编程方式纠正 GPS 跟踪错误
  • 如何从 GPS 轨迹中计算和获取额外的有用信息

对于初学者来说,GPS 轨迹不仅仅是一系列(纬度、经度、海拔)元组。 许多支持 GPS 的设备还将提供时间、心率等元数据。 一些 GPS 设备甚至会提供有关数据准确性的信息; 又名“精度稀释”。 但是,不幸的是,大多数 GPS 设备——尤其是主导市场的低端设备——不会提供这些信息,我们面临着自行推断设备准确性的挑战(理想情况下,在可能的情况下进行相应的校正) )。

让我们从一种可能的算法开始,以检测通常具有低质量 GPS 数据的低端 GPS 设备(如大多数智能手机)。

海拔错误和特质

如果您居住在世界的某些地方,当您使用智能手机记录轨迹时,您可能会注意到 GPS 海拔精度的一些奇怪之处。 当您检查高程时,它们始终被记录为高于或低于正确的高程(按恒定值)。 例如,我住在 Višnjan(克罗地亚),我的 Android 一直告诉我,我比实际海拔高大约 35-40 米。

例如,这是我几个月前进行的一次短途徒步旅行的 GPS 海拔图:

该图展示了 GIS 编程中 GPS 高程精度的问题。

这里需要注意两点。

首先,第一部分记录的GPS数据中的“山丘”完全是设备捏造出来的。 虽然图表似乎表明我们徒步旅行的最高点距离起点只有几百米,但实际上它是在大约 4 公里之后。

其次,也许更重要(并且在图表上可见)是整个图表是不准确的。 高度值一直被报告为比实际高出大约 30-40 米,我们将在本文中进一步详细讨论。

当我们可以检测到轨道有这些错误时,我们可以推断该设备可能是一个低质量的GPS。

这些都是廉价 GPS 设备可能发生的事情。 当我们可以检测到轨道有这些错误时,我们可以推断该设备可能是一个低质量的 GPS,因此可以预期还会有其他错误——不仅仅是海拔错误——这些都是此类设备常见的错误。

启动海拔错误

GPS 设备主要采用两种技术来确定海拔:“GPS 高度”(由 GPS 卫星系统向设备报告)和“气压高度”(由设备根据气压读数计算得出)。 两者都不完美。

GPS 高度值可能有许多小误差(通常在 +/- 10m 范围内),如果我们稍后决定计算累积高度增益,这可能会特别成问题。 另一方面,气压高度不仅对高度敏感,而且对天气条件也很敏感,这可能会引入其自身的一系列不准确性。

因此,一些设备采用混合方法,使用气压读数来记录海拔,但使用 GPS 读数来帮助(重新)校准这些值,以帮助解释天气(压力)变化等。 使用这样的设备,在开始跟踪时,气压高度可能完全错误,但是通过使用越来越多的 GPS 卫星数据重新校准,高度数据变得更加可靠。 因此,此类设备遇到我们之前在高程图中观察到的“假山”启动错误类型并不少见。

持续的 GPS 海拔不准确

为了解释高度报告中的一贯错误,我们需要回到我们的小学地理。 地理老师通常会解释说地球不是一个球体而是一个椭球体。 如果这是,事实上,严格正确,高度将很容易数学计算。 但事实并非如此。 地球是不规则的; 实际上,它更像是一个类似于椭球的马铃薯,而不是一个完美的椭球,这意味着对于 GIS 开发,您需要地球上几乎每个点的详细高度数据集。 在大地测量学中,这个参考椭球体(又名基准面)是一个数学定义的表面,它近似于大地水准面,即地球的“更真实”图形。

此外,重要的是要认识到,即使这些基准也只是地球表面实际形状的近似值。 有些在世界的某些地方工作得更好,而另一些在其他地方工作得更好。 例如,下图(使用我的 Ruby 库生成)显示了地球与最常用的椭球模型之一(WGS84 基准面)的不同之处。 黑色部分代表地球上方的部分,白色代表下方地球的部分,理想的椭球体(大陆和岛屿轮廓以红色显示)。

该图表描绘了地球表面,由用于地理空间和 GIS 编程的 Ruby 库生成。

您可以看到印度位于 WGS84 椭球下方,南部是绝对最小值(几乎 -100 米!),而欧洲位于其上方。

由于低质量的 GPS 设备不使用任何此类数据,它们实际上只是在假设一个完美的椭球体的情况下计算高程。 因此,它们始终不准确。

检测和纠正 GPS 高度误差

在 GPS 应用程序开发中,可以使用地球引力模型 EGM2008 数据集(有时也称为“大地水准面波动”数据集)来检测记录我们轨迹的设备是否存在这些类型的错误。 使用 EGM2008,我们可以逼近实际地球表面与理想椭球体之间的差异。

使用 EGM2008,我们可以逼近实际地球表面与理想椭球体之间的差异。

但是要知道我们的GPS 轨迹是否有这个错误,我们还需要一件事——真正的海拔。 航天飞机雷达地形任务 (SRTM) 是一个可以对此有所帮助的公共数据库。 SRTM 是一个基于栅格的数据库,它以大约每 30m(赤道)为美国和世界其他地区每 90m 的分辨率提供高程值。 例如,当计算上述轨迹中点的 SRTM 值时,会出现不同的图形(蓝线):

GPS 应用程序开发的一个很好的工具是 GIS 高程值的 SRTM 数据库。

这里的一个小烦恼是图形的粗糙边缘,但这很容易平滑。 请注意,通过平滑,我们几乎不会损失(如果有的话)精度,因为 SRTM 本身仅在等距位置提供离散点,在任何情况下我们都需要在这些位置之间进行插值。 这是上图的一个版本,上面的红线覆盖表示平滑的 SRTM 数据:

这是来自 SRTM 数据库的平滑 GPS 高程数据图表。

顺便说一句,使用我的 GPS Python 库,所有这些都可以轻松完成:

  • srtm.py:航天飞机雷达地形任务(SRTM)高程数据的python解析器
  • gpxpy:一个用于解析和操作GPX文件的简单python库(GPX,GPS交换格式,是一种用于GPS数据的轻量级XML数据格式)

对于 Ruby 用户,还有我的 Geoelevations.rb 解析器库,用于 SRTM 和 EGM2008 波动。

检测到这些异常后,根据我们使用的软件类型,我们可以 (a) 自行自动更正错误,或 (b) 简单地通知用户在其高程数据中检测到不准确之处。

此外,由于有不同的算法可用于以编程方式纠正这些 GPS 海拔误差,我们可能希望让用户选择使用哪种算法(例如,用户是否希望我们只使用平滑的 SRTM 数据“按原样”或用户是否希望我们使用 SRTM 数据来帮助纠正设备报告的高度)。

平滑轨迹并去除异常值

如果一名足球运动员佩戴 GPS 设备并记录比赛,那么由此产生的赛道将会一团糟。 比赛场地将密密麻麻地布满一条由许多急转弯、加速和减速组成的赛道。

幸运的是,人们使用 GPS 的大多数情况不会有这种相同的模式——GPS 轨迹线(和加速度)会相对平滑。 在这种情况下,可以假定我们轨迹中的不稳定点是由误差引起的,因此可以使用平滑函数合理地去除这些异常值。

作为 GIS 开发人员,平滑最常见的方法是遍历点并根据相邻坐标的值更改坐标。 例如,我们可以使用如下算法更改每个纬度和经度:

 points[n].latitude = points[n-1].latitude * 0.3 + points[n].latitude * .4 + points[n+1].latitude * .3 points[n].longitude = points[n-1].longitude * 0.3 + points[n].longitude * .4 + points[n+1].longitude * .3

系数越大,对应的相邻点对当前点修改位置的影响越大。 我在本例中使用的系数(0.3、0.4、0.3)有些随意,但在大多数情况下,您希望它们的总和等于 1.0。 (例如,更复杂的方法是使用点之间的距离,然后,点越近,相应的系数就越大。)

这是一个有很多随机错误的轨道示例:

GIS 开发中最大的 GPS 跟踪挑战之一是存在大量随机错误的轨道。

请注意,赛道没有很好地跟随路径,有很多急转弯和锯齿状转弯,有时会完全偏离预期的路径。

经过几次“平滑”迭代后,这条相同的轨道被转换为:

消除跟踪误差后,该程序中的 GPS 跟踪仍然不完善,但更好。

虽然这要好得多,但它仍然是不完美的。 请注意,仍有一些地方(特别是在路径中间附近)轨道仍然偏离道路。

您还可以尝试其他方法。 在某些地区,对于某些 GPS 应用,您还可以使用 OpenStreetMap (OSM) 数据尝试猜测正确的路径,然后将这些点“捕捉”到这条新线路。 虽然这通常很有帮助,但它也可能不完美,例如在 OSM 数据包含两条平行线(例如高速公路和附近的道路)或许多近距离路径的情况下。

如果我们可以推断出这条路线是一条远足路线,并且可以选择捕捉到高速公路或附近的小路,我们可以有把握地假设远足是沿着小路而不是高速公路。

在这种情况下,一种可能的解决方案是尝试使用本文中进一步讨论的一些技术来检测活动的类型。 例如,如果我们可以推断出这条路线是一条远足路线,并且可以选择捕捉到高速公路或附近的小路,我们可以安全地假设远足是沿着小路而不是高速公路。

另请注意,虽然此示例演示了表面坐标(即经度/纬度)的平滑,但平滑可以是一种同样有效的技术,用于消除海拔或时间数据,甚至心率和自行车节奏数据中的偏差。

平滑的其他好处和用途的示例可能包括:

  • 计算总海拔增益。 要计算轨道中的总海拔增益,仅将所有小的“跳跃”上坡相加是不够的,因为它们通常包含小错误。 在求和之前平滑高程通常可以帮助缓解这个问题。
  • 异常值去除。 “平滑”后,距离轨道太远的点更容易被检测到。 这些通常可以被认为是异常值,并且可以提示用户询问是否应该删除它们。

该算法存在一种不足的问题:在某些情况下,GPS 会记录一条平滑的路径,但路径会在某个方向上“移动”一个恒定的差异。 在这种情况下,平滑可能会进一步平滑线,但不会纠正此移位错误。

我们描述的简单平滑技术的另一个不太明显但重要的问题是,变换会修改路径中的所有(或几乎所有)点,即使是那些可能没有错误的点。 虽然这种更简单的方法对于普通 GPS 用户来说往往是一个合理的解决方案,但更复杂的平滑算法肯定可以在 GIS 编程中使用。 在某些情况下,根据用户、设备和应用程序,简单地删除异常值而不执行任何平滑可能会更好。

检测最大速度

如果我们有路线上所有点的坐标和时间戳,那么检测轨道的最大速度是相当简单的。 只需计算点之间的速度并找到最大值。 看起来很简单。

但请记住,我们正在处理低端 GPS 设备,我们并不完全信任数据,这可能会对我们的计算产生重大影响。 如果一个设备每 5 米记录一次位置,并且在某一点由于将点错位 10 米而出错,那么该部分的轨道似乎比原来快 3 倍!

GIS 开发领域的一种常见方法是提取点之间的所有速度,然后只删除前 5%(即使用第 95 个百分位数),希望删除的 5% 代表大部分错误。 但这无疑是不科学的,也不能保证正确的结果。 在我对这种技术的试验中,我尝试了不同的百分位数值,发现有些值适用于一个 GPS 设备,有些适用于其他设备。 有些适合远足,有些适合骑自行车。 但在大多数情况下,结果对我来说并不合适。

在尝试了许多算法之后,对有用的很简单:添加另一个过滤器来去除极端,不​​仅是速度,还有距离,如下所示:

  1. 按邻居之间的距离对点进行排序并删除前 5%。
  2. (可选:)平滑轨道(水平和/或垂直)。
  3. 按邻居之间的速度对点进行排序并删除前 5%。
该算法产生了相当可靠的结果,即使对于来自具有随机错误的廉价 GPS 设备的轨迹也是如此。

根据我的经验,这种算法产生了相当可靠的结果,即使对于来自具有随机错误的廉价 GPS 设备的轨迹也是如此。

推断活动类型

在许多情况下,平均速度足以确定活动类型。 例如,如果平均时速为 5kmh,则可能是步行/远足道,而如果平均时速为 30kmh,则可能是自行车道,依此类推。

但如果平均时速为 12kmh,则无法确定用户是骑山地车还是跑步。 在这种情况下,最大速度有时可以帮助区分两种类型的活动。 具体来说,我们可以利用跑步者的速度很少超过平均速度两倍的事实,而骑自行车的人则经常这样做(例如,在不太具有挑战性的路径上下坡时)。

因此,平均时速为12kmh,最高时速为18kmh的赛道可能是在跑步时记录的,而平均时速为12kmh,最高时速为30kmh的赛道可能是在山地自行车时记录的。 (当然,我们必须确保我们计算的最大速度是正确的,这样才能可靠地工作。)

可见天空的百分比:GPS 错误检测的巧妙代理

每次 GPS 测量的精度(即纬度、经度和海拔)很大程度上取决于记录时可见的卫星数量。 因此,如果我们能够以某种方式确定每次记录时“视野内”有多少卫星,我们就可以用它来估计记录的准确性。 例如,如果我们以某种方式知道所有需要的 GPS 卫星都在视野范围内,我们可以假设相应 GPS 数据具有高度的准确性。 相反,如果我们以某种方式知道视野中没有 GPS 卫星,我们可以假设数据容易出错。

但在您过于兴奋之前,请考虑尝试解决此类 GIS 问题的复杂性。 首先,您需要知道您的设备能够与哪个 GPS 卫星系统进行通信。 有最初的美国全球定位系统、欧洲的伽利略系统和俄罗斯的 GLONASS 系统。 一些设备适用于所有这些卫星类型,但许多设备不适用。 许多设备甚至不报告他们使用的系统。

但是有一种巧妙的方法可以规避这种复杂性,并粗略估计可见卫星的数量:使用可见天空的百分比作为可见卫星数量的代理。 不可见的天空意味着我们的 GPS 可以被更少的卫星“看到”(或被看到)。 但是我们如何计算地球上任何一点上可见天空的百分比呢? 解决方案实际上非常简单:我们可以使用前面讨论的 SRTM 数据计算我们周围的地平线。

例如,如果您在使用 SRTM 计算的 Triglav(斯洛文尼亚的最高峰)下方的山谷中,这就是地平线:

特里格拉夫下方山谷的地平线图像,使用 GIS 代码创建。

(对于那些感兴趣的人,可以在这里找到我创建此图像的代码。)

该图像基本上由从中心点看到的等距高程图层组成。 蓝色区域越深,高程层越远; 蓝色区域越浅,距离高程层越近。 绘制的最高点代表地平线。 如果 GPS 卫星位于天空中这条线以下,我们的设备可能无法看到(或被它看到)。 (但请注意,尽管图像被绘制为扁平矩形,但实际上您需要一些球面几何的基本知识才能正确计算地平线以下的区域。)

这种方法在登山等情况下很有帮助,您可能会从深峡谷(GPS 接收不良)到山脊(接收更好)。 这可能是一个有用的指标,表明您的轨道的哪些部分可能更容易出错。

要记住的另一件事是,这不是检测 GPS 高度误差的灵丹妙药。 首先,地球的大部分地区都不是山区,即使是山区,我们的心理也会高估海拔。 在绝大多数有人居住的地区,可见天空的实际百分比大于75% 。 但尽管如此,这种方法在某些情况下可能会有所帮助,例如登山时,您可能会从深峡谷(GPS 接收不良)到山脊(卫星接收可能要好得多)。 虽然这种方法不能绝对衡量轨道有多少错误,但它可以作为一个有用的指标,表明轨道的哪些部分可能比其他部分更容易出错。

包起来

我们已经讨论了低端 GPS 设备可能出现的一些更常见的 GPS 跟踪错误类型。 我们提供了对导致它们的原因的理解,以及一些用于纠正它们的 GIS 编程技术。

在某些情况下,我们可以高度自信地纠正轨迹。 在其他情况下,我们至少可以提醒用户注意曲目中出现问题的部分。 在我们不确定的情况下,始终可以选择让用户自己修复轨道,借助航拍图像和地图。 我们的概率猜测可以帮助突出显示我们检测到错误概率较高的轨道部分。

在许多情况下,我们概述的技术可以成为令人满意的“80% 解决方案”,为低端 GPS 设备的用户提供合理水平的 GPS 轨迹准确性自动改进。