Я хочу зациклить файл gpx и вычислить общее восхождение и спуск. У меня есть функция, которая может вычислить разницу в высоте между двумя наборами длинных точек широты, и я настроил Simplexml для чтения & цикл через точки gpx файла trkseg.
Проблема в том, что это не точно (на самом деле не так, как на самом деле).
Эти две линии приведут к различным подъемам и спускам, как в реальной жизни:
$total_ascent += ($val - $last_elevation);
$total_descent += ($val - $last_elevation);
Кто-нибудь знает, как более точно рассчитать общий подъем и спуск трека?
Это мой текущий фрагмент кода для его расчета ($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
)
На самом деле я катался на велосипеде по ровной дороге. Но мой фрагмент кода будет рассчитывать, я поднялся и спустился на пару метров. Может быть, я должен добавить некоторое ограничение точности между двумя отметками подряд …
Чего я хочу добиться:
Я постараюсь объяснить это лучше — когда я катаюсь, например. 20 км по ровной дороге (почти без подъема и спуска), общий подъем и спуск должны быть близки к 0. Но когда я суммирую $track_elevations
(как в моем фрагменте кода), я буду в $total_ascent
а также $total_descent
F.E. 500 метров … Это из-за между каждым элементом массива в $track_elevations
Разница в пару сантиметров, но я все еще еду по ровной дороге … И в общей сумме она соберется на большое количество метров … Надеюсь, теперь это более понятно.
Проблема в том, что если вы рассчитываете $lastHeight - $track_elevations[$i]
для Ascentet вы получаете значения ниже 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
Вы уверены, что это «квартира»? Можете ли вы предоставить полный набор данных? Также я не думаю, что это проблема точности из PHP. Точки данных имеют точность только двух цифр. Может быть, датчик округляется?
Даже если вы едете по совершенно ровной дороге, данные о высоте, полученные с помощью GPS, всегда будут немного увеличиваться и уменьшаться. GPS не очень точен с высотой, даже в идеальных условиях.
Если вы используете необработанный ввод GPS для расчета общего количества подъема / спуска, эти маленькие ошибки будут быстро суммироваться с каждой точкой и давать совершенно нереальные результаты.
Есть несколько вариантов получения лучших результатов, но все они более или менее сложны:
Вы можете «сгладить» кривую высот с помощью правильных алгоритмов.
Вы можете отбросить данные о высоте GPS и заменить их предварительно записанными данными о высоте для всех координат на земле (так называемые данные SRTM).
Вы можете использовать данные SRTM и разумно смешивать их с собственными данными GPS.
В любом случае, получение правильных значений высоты — сложная тема. Вы можете попробовать простой способ не считать различия ниже 10 м или что-то подобное, но это, скорее всего, не приведет к хорошим результатам.