lat); if ($count>200) { $f = round($count/200); if ($f>1) for($i=$count;$i>0;$i--) if ($i % $f != 0) { unset($points->lat[$i]); unset($points->lon[$i]); unset($points->ele[$i]); unset($points->dist[$i]); unset($points->speed[$i]); unset($points->hr[$i]); unset($points->cad[$i]); } } } return $points; } function parseXml($filePath, $gpxOffset) { $points = null; $points->lat = array(); $points->lon = array(); $points->ele = array(); $points->dist = array(); $points->speed = array(); $points->hr = array(); $points->cad = array(); $gpx = simplexml_load_file($filePath); if($gpx === FALSE) return; $gpx->registerXPathNamespace('10', 'http://www.topografix.com/GPX/1/0'); $gpx->registerXPathNamespace('11', 'http://www.topografix.com/GPX/1/1'); $gpx->registerXPathNamespace('gpxx', 'http://www.garmin.com/xmlschemas/GpxExtensions/v3'); $gpx->registerXPathNamespace('gpxtpx', 'http://www.garmin.com/xmlschemas/TrackPointExtension/v1'); $nodes = $gpx->xpath('//trkpt | //10:trkpt | //11:trkpt'); if ( count($nodes) > 0 ) { $lastLat = 0; $lastLon = 0; $lastEle = 0; $lastTime = 0; $dist = 0; $lastOffset = 0; $speedBuffer = array(); // normal case foreach($nodes as $trkpt) { $lat = $trkpt['lat']; $lon = $trkpt['lon']; $ele = $trkpt->ele; $time = $trkpt->time; $speed = (float)$trkpt->speed; $hr = 0; $cad = 0; if (isset($trkpt->extensions)) { $_hr = $trkpt->extensions->xpath('gpxtpx:TrackPointExtension/gpxtpx:hr/text()'); if ($_hr) { foreach ($_hr as $node) { $hr = (float)$node; } } $_cad = $trkpt->extensions->xpath('gpxtpx:TrackPointExtension/gpxtpx:cad/text()'); if ($_cad) { foreach ($_cad as $node) { $cad = (float)$node; } } } if ($lastLat == 0 && $lastLon == 0) { //Base Case array_push($points->lat, (float)$lat); array_push($points->lon, (float)$lon); array_push($points->ele, (float)round($ele,2)); array_push($points->dist, (float)round($dist,2)); array_push($points->speed, 0); array_push($points->hr, $hr); array_push($points->cad, $cad); $lastLat=$lat; $lastLon=$lon; $lastEle=$ele; $lastTime=$time; } else { //Normal Case $offset = calculateDistance((float)$lat, (float)$lon, (float)$ele, (float)$lastLat, (float)$lastLon, (float)$lastEle); $dist = $dist + $offset; if ($speed == 0) { $datediff = (float)my_date_diff($lastTime,$time); if ($datediff>0) { $speed = $offset / $datediff; } } array_push($speedBuffer, $speed); if (((float) $offset + (float) $lastOffset) > $gpxOffset) { //Bigger Offset -> write coordinate $avgSpeed = 0; foreach($speedBuffer as $s) { $avgSpeed += $s; } $avgSpeed = $avgSpeed / count($speedBuffer); $speedBuffer = array(); $lastOffset=0; array_push($points->lat, (float)$lat ); array_push($points->lon, (float)$lon ); array_push($points->ele, (float)round($ele, 2) ); array_push($points->dist, (float)round($dist, 2) ); array_push($points->speed, (float)round($avgSpeed, 1) ); array_push($points->hr, $hr); array_push($points->cad, $cad); } else { //Smoller Offset -> continue.. $lastOffset = (float) $lastOffset + (float) $offset ; } } $lastLat=$lat; $lastLon=$lon; $lastEle=$ele; $lastTime=$time; } unset($nodes); } else { $nodes = $gpx->xpath('//gpxx:rpt'); if ( count($nodes) > 0 ) { $lastLat = 0; $lastLon = 0; $lastEle = 0; $dist = 0; $lastOffset = 0; // Garmin case foreach($nodes as $rpt) { $lat = $rpt['lat']; $lon = $rpt['lon']; if ($lastLat == 0 && $lastLon == 0) { //Base Case array_push($points->lat, (float)$lat ); array_push($points->lon, (float)$lon ); array_push($points->ele, 0 ); array_push($points->dist, 0 ); array_push($points->speed, 0 ); array_push($points->hr, 0 ); array_push($points->cad, 0 ); $lastLat=$lat; $lastLon=$lon; } else { //Normal Case $offset = calculateDistance($lat, $lon, 0,$lastLat, $lastLon, 0); $dist = $dist + $offset; if (((float) $offset + (float) $lastOffset) > $gpxOffset) { //Bigger Offset -> write coordinate $lastOffset=0; array_push($points->lat, (float)$lat ); array_push($points->lon, (float)$lon ); array_push($points->ele, 0 ); array_push($points->dist, 0 ); array_push($points->speed, 0 ); array_push($points->hr, 0 ); array_push($points->cad, 0 ); } else { //Smoller Offset -> continue.. $lastOffset= (float) $lastOffset + (float) $offset; } } $lastLat=$lat; $lastLon=$lon; } unset($nodes); } else { echo "Empty Gpx or not supported File!"; } } unset($gpx); return $points; } function getWayPoints($gpxPath) { $points = array(); if (file_exists($gpxPath)) { $points = array(); $gpx = simplexml_load_file($gpxPath); $gpx->registerXPathNamespace('10', 'http://www.topografix.com/GPX/1/0'); $gpx->registerXPathNamespace('11', 'http://www.topografix.com/GPX/1/1'); $nodes = $gpx->xpath('//wpt | //10:wpt | //11:wpt'); if ( count($nodes) > 0 ) { // normal case foreach($nodes as $wpt) { $lat = $wpt['lat']; $lon = $wpt['lon']; $ele = $wpt->ele; $time = $wpt->time; $name = $wpt->name; $desc = $wpt->desc; $sym = $wpt->sym; $type = $wpt->type; array_push($points, array((float)$lat,(float)$lon,(float)$ele,$time,$name,$desc,$sym,$type)); } } } return $points; } function toRadians($degrees) { return (float)($degrees * 3.1415926535897932385 / 180); } function calculateDistance($lat1,$lon1,$ele1,$lat2,$lon2,$ele2) { $alpha = (float)sin((float)toRadians((float) $lat2 - (float) $lat1) / 2); $beta = (float)sin((float)toRadians((float) $lon2 - (float) $lon1) / 2); //Distance in meters $a = (float) ( (float)$alpha * (float)$alpha) + (float) ( (float)cos( (float)toRadians($lat1)) * (float)cos( (float)toRadians($lat2)) * (float)$beta * (float)$beta ); $dist = 2 * 6369628.75 * (float)atan2((float)sqrt((float)$a), (float)sqrt(1 - (float) $a)); $d = (float)sqrt((float)pow((float)$dist, 2) + pow((float) $lat1 - (float)$lat2, 2)); return sqrt((float)pow((float)$ele1-(float)$ele2,2)+(float)pow((float)$d,2)); } function my_date_diff($old_date, $new_date) { $t1 = strtotime($new_date); $t2 = strtotime($old_date); // milliceconds fix $t1 += date_getDecimals($new_date); $t2 += date_getDecimals($old_date); $offset = (float)($t1 - $t2); //echo "$offset = $new_date - $old_date; ".strtotime($new_date)." ".strtotime($old_date)."
"; return $offset; } function date_getDecimals($date) { if (preg_match('(\.([0-9]{2})Z?)', $date, $matches)) { return (float)((float)$matches[1] / 100); } else { return 0; } } ?>