2015-05-21 2 views
8

Я хочу, чтобы петля, хотя gpx-файл, и вычислил общее восхождение и спуск. У меня есть функция, которая может вычислять разницу в высоте между двумя наборами длинных точек lat, и я установил simplexml для чтения цикла & через точки trkseg файла gpx.PHP Цитирование через GPX для вычисления общего восхождения/спуска дорожки

Проблема в том, что это неточно (действительно неточно, как в реальном).

Эти две линии приведет к различным подъема и спуска, как это происходит в реальной жизни:

$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 
) 

В реале я ездил на велосипеде по ровной дороге. Но мой фрагмент кода рассчитан, я поднялся и спустился на пару метров. Может быть, я должен добавить туда некоторые ограничения точности между двумя высотами подряд ...

То, что я хочу добиться:

Я попытаюсь объяснить это более лучше - когда я еду F.E. 20 км по ровной дороге (почти без подъема и спуска), общее восхождение и спуск должны быть близки к 0. Но когда я суммирую $track_elevations (как в моем фрагменте кода), я получу $total_ascent и $total_descent f.e. 500 метров ... Из-за того, что между каждым элементом массива в $track_elevations есть разница в сантиметрах, но я все еще еду по плоской дороге ... И в общей сумме он будет собираться на большое количество метров ... Надеюсь сейчас это более понятно.

+0

Вы можете указать некоторые значения для массива 'track_elevations'? – Stephen

+0

@Stephen обновлен. – Legionar

+0

Я, вероятно, неправильно понял вопрос, но похоже, что вы поднялись и спустились на пару метров (на основе массива). Что именно вы хотите рассчитать? – Ynhockey

ответ

1

Проблема в том, что если вы вычислите $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  
+0

Мой фрагмент кода никогда не получит значения ниже 0 ... Когда вы восходите - 'if ($ last_elevation <$ val) {', чем этот '$ total_ascent + = ($ val - $ last_elevation);' будет больше 0; когда вы спускаетесь - 'elseif ($ last_elevation> $ val) {', чем этот '$ total_descent + = ($ last_elevation - $ val);' будет больше 0. Также btw: я использую 'abs' функцию в конец моей функции calc. Но это все равно не решит проблему, что она отличается, как в реальной жизни ... – Legionar

+0

Когда я запускал ваш код с вашими данными примера, я получаю '$ total_descent = -1.94'. Я вычислил данные вашего примера вручную и добавил его к моему ответу. – take

+0

Да, я знаю. Но это не проблема - разница между '$ total_ascent' и' $ total_descent'. AD1: Я использую 'abs()', поэтому он будет больше 0. AD2: в моем примере есть только несколько высот, обычно около 1000 возвышений, а общее восхождение и спуск составляет около 500 метров. Но, как я уже сказал, я ехал на велосипеде на 20 километров по ровной дороге, поэтому общее восхождение и спуск должно составлять всего пару метров (т. Е. 5-10, а не 500). Это реальная проблема моего вопроса ... И в этой парах возвышений я предусмотрел, я точно не поднялся на 9,1 м, но, может быть, только на 50 см ... – Legionar

1

Вы уверены, что это "плоский"? flat? Можете ли вы предоставить полный набор данных? Также я не думаю, что это проблема с PHP. Ваши данные имеют только двузначную точность. Может быть, датчик округляется?

+0

Это не проблема в PHP. Датчик округляет его как-то странно. Его все еще между 328 - 334 м, но дорога была ровной. Я просто спрашиваю, если я должен использовать некоторую прецизию, чтобы не считать небольшие изменения высоты ... – Legionar

1

Даже если вы путешествуете по абсолютно ровной дороге, данные о высоте, собранные с помощью GPS, всегда будут подниматься и опускаться. GPS не очень точен с высотой даже в идеальных условиях.

Если вы используете необработанный GPS-вход для расчета общего количества восхождения/нисхождения, эти небольшие ошибки будут быстро суммироваться с каждой отдельной точкой и дать совершенно нереалистичные результаты.

Существует несколько вариантов получения лучших результатов, но они все более или менее сложны: Вы можете «сгладить» кривую высоты с помощью соответствующих алгоритмов. Вы можете отбросить данные о высоте GPS и заменить их предварительно записанными данными о высоте для всех координат на земле (называемые SRTM-данными).
Вы можете использовать данные SRTM и разумно смешивать их с собственными данными GPS.

В любом случае получение правильных значений высоты является трудной темой. Вы можете попробовать простой способ не учитывать различия ниже 10 м или некоторые такие, но это, скорее всего, не приведет к хорошим результатам.