【问题标题】:PHP Looping through a GPX to calculate total ascent/descent of a trackPHP循环通过GPX以计算轨道的总上升/下降
【发布时间】:2015-08-02 20:26:05
【问题描述】:

我想通过一个 gpx 文件循环并计算总上升和下降。我有一个函数可以计算两组经纬度点之间的高程差异,并且我设置了 simplexml 来读取和循环遍历 gpx 文件 trkseg 点。

问题是,这并不准确(实际上并不准确)。

这两条线会导致不同的上升和下降,就像在现实生活中一样:

$total_ascent += ($val - $last_elevation);
$total_descent += ($val - $last_elevation);

有人知道,如何更准确地计算轨道的总上升和下降?

这是我当前的代码 sn-p 来计算它($track_elevations 是一个具有整个轨道高程的数组):

if (!empty($track_elevations)) {
        $total_ascent = $total_descent = 0
        $lowest_elevation = $highest_elevation = $last_elevation = null;

        foreach ($track_elevations as &$val) {
            if (!is_null($last_elevation)) {
                if ($last_elevation < $val) {
                    $total_ascent += ($val - $last_elevation);
                }
                elseif ($last_elevation > $val) {
                    $total_descent += ($last_elevation - $val);
                }
            }

            if (is_null($lowest_elevation) or $lowest_elevation > $val) {
                $lowest_elevation = $val;
            }

            if (is_null($highest_elevation) or $highest_elevation < $val) {
                $highest_elevation = $val;
            }

            $last_elevation = $val;
        }
    }

$track_elevations 数组示例:

$track_elevations = array(
    327.46,
    328.27,
    329.32,
    330.11,
    329.46,
    329.39,
    329.68,
    331.04,
    333.23,
    333.46,
    332.97,
    332.88,
    332.99,
    332.75,
    332.74,
    334.01,
    333.62
)

实际上,我在平坦的道路上骑自行车。但是我的代码 sn-p 会计算,我已经上升和下降了几米。也许我应该在连续两个高程之间添加一些精度限制......

我想要达到的目标:

我会尝试更好地解释它 - 当我骑 f.e.在平坦的道路上行驶 20 公里(几乎没有上升和下降),上升和下降的总和应该接近 0。但是当我总结 $track_elevations(就像我的代码中的 sn-p 一样)时,我会进入 $total_ascent$total_descentfe 500米……因为$track_elevations中的每个阵元之间相差几厘米,但我还是骑在平坦的路上……而且总和会聚集到大量米……希望现在更清楚了。

【问题讨论】:

  • 您能否为track_elevations 数组提供一些示例值?
  • 我可能误解了这个问题,但看起来您确实上升和下降了几米(基于提供的阵列)。你到底想计算什么?
  • 我会尝试更好地解释它 - 当我骑 f.e.在平坦的道路上行驶 20 公里(几乎没有上升和下降),总上升和下降应该接近 0。但是当我总结 $track_elevations(就像我的代码的 sn-p 中一样)时,我会进入 $total_ascent$total_descentfe 500米……因为$track_elevations中的每个阵元之间相差几厘米,但我还是骑在平坦的路上……而且总起来会聚集到大量的米……希望现在更清楚了。
  • 所以要明确一点——你想知道你从原始起始位置的整体上升或下降,还是所有上升和下降的总和?例如如果您从 100m 开始,上升 10、下降 9、上升 5 和下降 6 - 您希望总上升计算为 15 还是 0?
  • 是的,但我认为,我应该使用一些精度,因为当我在平坦的道路上行驶时,海拔仍然是 349.0 m - 351.0 m,它会返回 f.e.经过 20 公里的总上升和下降约 500 米,但当然,这不是真的,它只是逐个计算大约几厘米的差异......

标签: php gpx elevation


【解决方案1】:

问题是,如果您为 ascentet 计算 $lastHeight - $track_elevations[$i],您会得到低于 0 的值,这就是为什么您会在 $total_asc$total_desc 之间得到很大差异。

<?php
$track_elevations = array(
    327.46,
    328.27,
    329.32,
    330.11,
    329.46,
    329.39,
    329.68,
    331.04,
    333.23,
    333.46,
    332.97,
    332.88,
    332.99,
    332.75,
    332.74,
    334.01,
    333.62
);

$lastHeight = $track_elevations[0];
$total_ascent = 0;
$total_descent = 0;
for ($i=1;$i<count($track_elevations);$i++) {
    if ($track_elevations[$i] > $lastHeight) {
        $total_ascent += -1 * ($lastHeight - $track_elevations[$i]);
    }
    else {
        $total_descent += ($lastHeight - $track_elevations[$i]);
    }
    $lastHeight = $track_elevations[$i];
}
echo $total_ascent ."\n";
echo $total_descent . "\n\n--\n";
echo $total_ascent  - $total_descent . "\n";

--

$ php -f gpx.php
8.1
1.94

--
6.16

-- 手动计算值:

Ascent:
0.81
1.05
0.79
0.29
1.36
2.19
0.23
0.11
1.27
---
8.1

Descent:
0.65
0.07
0.49
0.09
0.24
0.01
0.39
---
1.94    

【讨论】:

  • 我的代码 sn-p 永远不会得到低于 0 的值...当你升序时 - if ($last_elevation &lt; $val) {,比这个 $total_ascent += ($val - $last_elevation); 将大于 0;当你下降时 - elseif ($last_elevation &gt; $val) {,比这个 $total_descent += ($last_elevation - $val); 将大于 0。顺便说一句:我在 calc 函数的末尾使用 abs 函数。但这仍然不能解决问题,它与现实生活中的不同......
  • 当我用你的示例数据运行你的代码时,我得到$total_descent = -1.94。我已经手动计算了您的示例数据并将其添加到我的答案中。
  • 是的,我知道。但这不是问题 - $total_ascent$total_descent 之间的区别。 AD1:我用的是abs(),所以它会大于0。 AD2:在我的例子中只有很少的海拔,通常有1000个海拔左右,总共上升和下降约500米。但正如我所说,我在平坦的道路上骑自行车 20 公里,所以总上升和下降应该只有几米(例如 5 - 10,而不是 500)。这是我的问题的真正问题......在我提供的这几个海拔高度,我肯定没有上升 9.1 m,但可能只有 50 cm......
【解决方案2】:

你确定这是“平面”吗? 能否提供完整的数据集?此外,我认为这不是 PHP 的精度问题。您的数据点只有两位数的精度。也许传感器正在四舍五入?

【讨论】:

  • 这不是 PHP 的问题。传感器四舍五入它有点奇怪。它仍然在 328 - 334 m 之间,但道路平坦。我只是问,如果我应该使用一些精度,不计算海拔的微小变化......
【解决方案3】:

即使您骑在完全平坦的道路上,从 GPS 收集的海拔数据也总会上下波动。即使在完美的条件下,GPS 的高度也不是很准确。

如果您使用原始 GPS 输入来计算攀爬/下降的总量,这些小错误将很快与每个点相加,并给出完全不切实际的结果。

有许多选项可以获得更好的结果,但它们或多或少都比较复杂: 您可以使用适当的算法“平滑”高程曲线。 您可以丢弃 GPS 高度数据,并将其替换为地球上所有坐标的预先记录的高度数据(称为 SRTM 数据)。
您可以使用 SRTM 数据并将其与您自己的 GPS 数据智能混合。

无论如何,获得适当的高度值是一个困难的话题。您可以尝试不计算 10m 以下的差异的简单方法,但它很可能不会产生好的结果。

【讨论】:

    猜你喜欢
    • 2015-03-23
    • 2011-09-01
    • 1970-01-01
    • 2012-01-31
    • 2013-11-20
    • 2020-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多