1
votes

Trying to calculate from a .gpx file the distance between each gps points. I have tried 2 different formulas. This one should be more accurate: dist = 6378.388 * acos(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(lon2 - lon1))

This one should also work for short distances: distance = sqrt(dx * dx + dy * dy)

The distance between each point is max. 100 m. I calculated the distance with my program and got 26.8 km. Then I have imported the .gpx file into goole earth and I have got a distance of 21 km. I do not know why these values differ so much. Maybe you could help me.

Here comes the code (just the relevant fragments) to calculate the distance from the gpx file:

...
$xml = file_get_contents($file);
$doc = new DOMDocument();
$doc->loadXML($xml);
$track = array();

/* get the elevation for each gps point */
...

/* get the time for each gps point */
...

/* get the position for each gps point*/                                
$trkpts = $doc->getElementsByTagName('trkpt');
$i=0;
foreach ($trkpts as $trkpt) {
   $track[$i]['position']   = array();
   $track[$i]['position']['lon']    = $trkpt->getAttribute('lat');
   $track[$i]['position']['lat']    = $trkpt->getAttribute('lon');
   $i++;
}

/* calculate the distance for each gps point */
ini_set('precision', '50');
for($i2=0;$i2<($i);$i2++){
    if($i2==0){
      $track[$i2]['distance'] = 0;
      /* get first point */
      $lastlat  = deg2rad($track[$i2]['position']['lat']);
      $lastlon  = deg2rad($track[$i2]['position']['lon']);
      $lastele  = $track[$i2]['ele'];
    }
    else{

       $aktlat = deg2rad($track[$i2]['position']['lat']);
       $aktlon  = deg2rad($track[$i2]['position']['lon']);
       $aktele  = $track[$i2]['ele'];

       /* if coordinates differ calculate distance */                   
       if(($aktlat-$lastlat)!=0 || ($aktlon-$lastlon)!=0){
            $track[$i2]['distance'] = acos(sin($lastlat)*sin($aktlat)+cos($lastlat)*cos($aktlat)*cos($aktlon-$lastlon));

            $track[$i2]['distance'] = $track[$i2]['distance'] * 6378137;

            /* calculate the elevation difference */
            $track[$i2]['distance'] = sqrt(pow($track[$i2]['distance'],2)+pow(($aktele-$lastele),2));

       }
       else{
           $track[$i2]['distance'] = 0;
       }
       /* save act point as last point */
       $lastlat                 = deg2rad($aktlat);
       $lastlon                 = deg2rad($aktlon);
       $lastele             = $aktele;
    }
}

Here is the gpx file for everyone who wants to check: http://mein-sporttagebuch.de/userfiles/tempfiles/runtastic_20130825_1054_Radfahren.gpx

Thanks for any advices.

EDIT Here comes the code for getting the elevation (from elevation I calculate some more measures like highest and deepest point):

$eles = $doc->getElementsByTagName('ele');
$i=0;
$minheight  = 0;
$maxheight  = 0;
$asc        = 0;
$desc       = 0;
$lastheight = 0;
foreach ($eles as $ele) {
   if($i>0){
      if($lastheight<$ele->nodeValue){
         $asc +=  $ele->nodeValue-$lastheight;
      }
      else{
         $desc +=  $lastheight-$ele->nodeValue;
      }
   }
   $track[$i] = array();
   $track[$i]['ele'] = $ele->nodeValue;
   if($minheight>$ele->nodeValue || $i==0){
      $minheight = $ele->nodeValue;
   }
   if($maxheight<$ele->nodeValue){
      $maxheight = $ele->nodeValue;
   }

   $lastheight = $ele->nodeValue;
   $i++;
}
2
It's a bit odd that you're fetching the ele data in a separate loop from the positions. Would like to see that code too, if you have the elevation data wrong it could cause this problem.bazzargh
@bazzargh: I have added the relevant code.zuluk

2 Answers

1
votes

There's a bug in the code at the end of the loop.

   /* save act point as last point */
   $lastlat                 = deg2rad($aktlat);
   $lastlon                 = deg2rad($aktlon);

But aktlat/lon were defined as:

   $aktlat = deg2rad($track[$i2]['position']['lat']);
   $aktlon  = deg2rad($track[$i2]['position']['lon']);

... you've done the deg2rad conversion twice. It should be:

   /* save act point as last point */
   $lastlat                 = $aktlat;
   $lastlon                 = $aktlon;

Not sure if that's exactly what's causing your error but it can't help! You also use a different radius for the earth in your code from the formula at the top, but that makes very little difference at all.

0
votes

As i see, you take elevations in your calculations. Probably, google maps doesn't count elevations in their formula. Have you tried to calculate your distance for "flat" square?