Adding elevation difference to the GPX simplification

This commit is contained in:
2019-11-24 13:26:23 +01:00
parent 5afb60da5d
commit 2a4fa8b2d0
2 changed files with 32 additions and 14 deletions

View File

@@ -108,7 +108,8 @@ class GeoJson extends Geo {
const EXT = '.geojson';
const MAX_FILESIZE = 2; //MB
const MAX_DEVIATION = 0.1; //10%
const MAX_DEVIATION_FLAT = 0.1; //10%
const MAX_DEVIATION_ELEV = 0.1; //20%
public function __construct($sFileName) {
parent::__construct($sFileName);
@@ -136,6 +137,9 @@ class GeoJson extends Geo {
public function buildTracks($asTracks, $bSimplify=false) {
$this->addNotice('Creating '.($bSimplify?'Simplified ':'').'GeoJson Tracks');
$iGlobalInvalidPointCount = 0;
$iGlobalPointCount = 0;
$this->asTracks = array();
foreach($asTracks as $asTrackProps) {
@@ -178,40 +182,55 @@ class GeoJson extends Geo {
$asTrackPoints = $asTrackProps['points'];
$iPointCount = count($asTrackPoints);
$iInvalidPointCount = 0;
$asPrevPoint = array();
foreach($asTrackPoints as $iIndex=>$asPoint) {
if($bSimplify && $iIndex > 0 && $iIndex < ($iPointCount - 1)) {
if(!$this->isPointValid($asTrackPoints[$iIndex - 1], $asPoint, $asTrackPoints[$iIndex + 1])) {
$asNextPoint = ($iIndex < ($iPointCount - 1))?$asTrackPoints[$iIndex + 1]:array();
if($bSimplify && !empty($asPrevPoint) && !empty($asNextPoint)) {
if(!$this->isPointValid($asPrevPoint, $asPoint, $asNextPoint)) {
$iInvalidPointCount++;
continue;
}
}
$asTrack['geometry']['coordinates'][] = array_values($asPoint);
$asPrevPoint = $asPoint;
}
$this->asTracks[] = $asTrack;
$iGlobalInvalidPointCount += $iInvalidPointCount;
$iGlobalPointCount += $iPointCount;
if($iInvalidPointCount > 0) $this->addNotice('Removing '.$iInvalidPointCount.'/'.$iPointCount.' points ('.round($iInvalidPointCount / $iPointCount * 100, 1).'%) from '.$asTrackProps['name']);
}
if($bSimplify) $this->addNotice('Total: '.$iGlobalInvalidPointCount.'/'.$iGlobalPointCount.' points removed ('.round($iGlobalInvalidPointCount / $iGlobalPointCount * 100, 1).'%)');
}
private function isPointValid($asPointA, $asPointO, $asPointB) {
/* A----O Calculate angle AO^OB
\ If angle is within [Pi - 10%; Pi + 10%], O can be discarded
\ O is valid otherwise
B
-> -> -> ->
Law of Cosines: angle = arccos(OA.OB / ||OA||.||OB||)
*/
* \ If angle is within [Pi - 10%; Pi + 10%], O can be discarded
* \ O is valid otherwise
* B
*/
//Path Turn Check -> -> -> ->
//Law of Cosines (vector): angle = arccos(OA.OB / ||OA||.||OB||)
$fVectorOA = array('lon'=>($asPointA['lon'] - $asPointO['lon']), 'lat'=> ($asPointA['lat'] - $asPointO['lat']));
$fVectorOB = array('lon'=>($asPointB['lon'] - $asPointO['lon']), 'lat'=> ($asPointB['lat'] - $asPointO['lat']));
$fVectorOAxOB = $fVectorOA['lon'] * $fVectorOB['lon'] + $fVectorOA['lat'] * $fVectorOB['lat'];
$fLengthOA = sqrt(pow($asPointA['lon'] - $asPointO['lon'], 2) + pow($asPointA['lat'] - $asPointO['lat'], 2));
$fLengthOB = sqrt(pow($asPointO['lon'] - $asPointB['lon'], 2) + pow($asPointO['lat'] - $asPointB['lat'], 2));
$fVectorOAxOB = $fVectorOA['lon'] * $fVectorOB['lon'] + $fVectorOA['lat'] * $fVectorOB['lat'];
$fAngleAOB = acos($fVectorOAxOB/($fLengthOA * $fLengthOB));
return ($fAngleAOB <= (1 - self::MAX_DEVIATION) * M_PI || $fAngleAOB >= (1 + self::MAX_DEVIATION) * M_PI);
//Elevation Check
//Law of Cosines: angle = arccos((OB² + AO² - AB²) / (2*OB*AO))
$fLengthAB = sqrt(pow($asPointB['ele'] - $asPointA['ele'], 2) + pow($fLengthOA + $fLengthOB, 2));
$fLengthAO = sqrt(pow($asPointO['ele'] - $asPointA['ele'], 2) + pow($fLengthOA, 2));
$fLengthOB = sqrt(pow($asPointB['ele'] - $asPointO['ele'], 2) + pow($fLengthOB, 2));
$fAngleAOBElev = acos((pow($fLengthOB, 2) + pow($fLengthAO, 2) - pow($fLengthAB, 2)) / (2 * $fLengthOB * $fLengthAO));
return ($fAngleAOB <= (1 - self::MAX_DEVIATION_FLAT) * M_PI || $fAngleAOB >= (1 + self::MAX_DEVIATION_FLAT) * M_PI ||
$fAngleAOBElev <= (1 - self::MAX_DEVIATION_ELEV) * M_PI || $fAngleAOBElev >= (1 + self::MAX_DEVIATION_ELEV) * M_PI);
}
private function buildGeoJson() {

View File

@@ -8,5 +8,4 @@
* import/export
* Reset zoom on image closing (lightbox)
* Fix fullscreen button on ios
* Fix lightbox portrait mode: push text under
* Simplify track when converting gpx to geojson
* Fix lightbox portrait mode: push text under