Skip to content

Commit

Permalink
Calculate Bounds when not in original GPX file (#71)
Browse files Browse the repository at this point in the history
* added a BoundsCalculator to compute it when not in the original GPX. Plus tests.

* reverted some useless code related to PHP 8 and minor reformats.
  • Loading branch information
miqwit committed May 6, 2024
1 parent ecde89a commit 7131274
Show file tree
Hide file tree
Showing 16 changed files with 533 additions and 34 deletions.
52 changes: 52 additions & 0 deletions src/phpGPX/Helpers/BoundsCalculator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php
/**
* DistanceCalculator.php
*
* @author miqwit
* @since 03/2024
* @version 1.0
*/

namespace phpGPX\Helpers;

use phpGPX\Models\Point;
use phpGPX\phpGPX;

/**
* This helper will return the boundaries of a group of points,
* e.g. the lowest latitude, lowest longitude, highest latitude, highest longitude.
* This can be useful to display a segment on a map and to zoom the map
* properly, so it shows all the points.
*/
class BoundsCalculator
{
/**
* @return array of array Only two points with latitude and longitude that correspond to the
* most northwestern and southeastern points of the track
*/
public static function calculate(array $points): array
{
$pointCount = count($points);

$north = $east = -PHP_FLOAT_MAX; // look for longest lat and lon
$south = $west = PHP_FLOAT_MAX; // look for shortest lat and lon

for ($p = 0; $p < $pointCount; $p++) {
$curPoint = $points[$p];

$lng = $curPoint->longitude;
$lat = $curPoint->latitude;

// Update northWest and southEast points if needed
if ($lat > $north) {$north = $lat;}
if ($lng > $east) {$east = $lng;}
if ($lat < $south) {$south = $lat;}
if ($lng < $west) {$west = $lng;}
}

return [
["lat" => $north, "lng" => $west],
["lat" => $south, "lng" => $east]
];
}
}
29 changes: 16 additions & 13 deletions src/phpGPX/Models/Bounds.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,27 @@ class Bounds implements Summarizable
*/
public $maxLongitude;

/**
* Bounds constructor.
*/
public function __construct()
{
$this->minLatitude = null;
$this->minLongitude = null;
$this->maxLongitude = null;
$this->maxLatitude = null;
}
/**
* @param ?float $minLatitude
* @param ?float $minLongitude
* @param ?float $maxLatitude
* @param ?float $maxLongitude
*/
public function __construct(?float $minLatitude, ?float $minLongitude, ?float $maxLatitude, ?float $maxLongitude)
{
$this->minLatitude = $minLatitude;
$this->minLongitude = $minLongitude;
$this->maxLatitude = $maxLatitude;
$this->maxLongitude = $maxLongitude;
}


/**
/**
* Serialize object to array
* @return array
*/
public function toArray()
{
public function toArray(): array
{
return [
'minlat' => $this->minLatitude,
'minlon' => $this->minLongitude,
Expand Down
2 changes: 1 addition & 1 deletion src/phpGPX/Models/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,5 @@ public function __construct()
* Return all points in collection.
* @return Point[]
*/
abstract public function getPoints();
abstract public function getPoints(): array;
}
5 changes: 3 additions & 2 deletions src/phpGPX/Models/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace phpGPX\Models;

use phpGPX\Helpers\BoundsCalculator;
use phpGPX\Helpers\DistanceCalculator;
use phpGPX\Helpers\ElevationGainLossCalculator;
use phpGPX\Helpers\GeoHelper;
Expand Down Expand Up @@ -40,8 +41,8 @@ public function __construct()
* Return all points in collection.
* @return Point[]
*/
public function getPoints()
{
public function getPoints(): array
{
/** @var Point[] $points */
$points = [];

Expand Down
4 changes: 4 additions & 0 deletions src/phpGPX/Models/Segment.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace phpGPX\Models;

use phpGPX\Helpers\BoundsCalculator;
use phpGPX\Helpers\DistanceCalculator;
use phpGPX\Helpers\ElevationGainLossCalculator;
use phpGPX\Helpers\GeoHelper;
Expand Down Expand Up @@ -127,5 +128,8 @@ public function recalculateStats()
$this->stats->averagePace = $this->stats->duration / ($this->stats->distance / 1000);
}
}

list($northWest, $southEast) = BoundsCalculator::calculate($this->getPoints());
$this->stats->bounds = [$northWest, $southEast];
}
}
12 changes: 11 additions & 1 deletion src/phpGPX/Models/Stats.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ class Stats implements Summarizable
*/
public $duration = null;

/**
* An array of two points representing
* the most northwestern and the most
* southeastern points of a segment
* @var array
*/
public $bounds = array();

/**
* Reset all stats
*/
Expand All @@ -125,6 +133,7 @@ public function reset()
$this->startedAtCoords = null;
$this->finishedAt = null;
$this->finishedAtCoords = null;
$this->bounds = null;
}

/**
Expand All @@ -148,7 +157,8 @@ public function toArray()
'startedAtCoords' => $this->startedAtCoords,
'finishedAt' => DateTimeHelper::formatDateTime($this->finishedAt, phpGPX::$DATETIME_FORMAT, phpGPX::$DATETIME_TIMEZONE_OUTPUT),
'finishedAtCoords' => $this->finishedAtCoords,
'duration' => (float)$this->duration
'duration' => (float)$this->duration,
'bounds' => $this->bounds
];
}
}
8 changes: 6 additions & 2 deletions src/phpGPX/Models/Track.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace phpGPX\Models;

use phpGPX\Helpers\BoundsCalculator;
use phpGPX\Helpers\GeoHelper;
use phpGPX\Helpers\SerializationHelper;
use phpGPX\phpGPX;
Expand Down Expand Up @@ -37,8 +38,8 @@ public function __construct()
* Return all points in collection.
* @return Point[]
*/
public function getPoints()
{
public function getPoints(): array
{
/** @var Point[] $points */
$points = [];

Expand Down Expand Up @@ -154,5 +155,8 @@ public function recalculateStats()
$this->stats->averagePace = $this->stats->duration / ($this->stats->distance / 1000);
}
}

list($northWest, $southEast) = BoundsCalculator::calculate($this->getPoints());
$this->stats->bounds = [$northWest, $southEast];
}
}
12 changes: 6 additions & 6 deletions src/phpGPX/Parsers/BoundsParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ public static function parse(\SimpleXMLElement $node)
return null;
}

$bounds = new Bounds();

$bounds->minLatitude = isset($node['minlat']) ? (float) $node['minlat'] : null;
$bounds->minLongitude = isset($node['minlon']) ? (float) $node['minlon'] : null;
$bounds->maxLatitude = isset($node['maxlat']) ? (float) $node['maxlat'] : null;
$bounds->maxLongitude = isset($node['maxlon']) ? (float) $node['maxlon'] : null;
$bounds = new Bounds(
isset($node['minlat']) ? (float) $node['minlat'] : null,
isset($node['minlon']) ? (float) $node['minlon'] : null,
isset($node['maxlat']) ? (float) $node['maxlat'] : null,
isset($node['maxlon']) ? (float) $node['maxlon'] : null
);

return $bounds;
}
Expand Down
46 changes: 45 additions & 1 deletion tests/LoadFileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@

class LoadFileTest extends TestCase
{
public function testLoadXmlFileGeneratedByTimezero()
/**
* @coversNothing
* @return void
*/
public function testLoadXmlFileGeneratedByTimezero()
{
$file = __DIR__ . '/fixtures/timezero.gpx';

Expand Down Expand Up @@ -106,6 +110,16 @@ private function createExpectedArray()
'lng' => 0.0801333333365323
],
'duration' => 9.0,
'bounds' => [
[
'lat' => 49.3635449998312,
'lng' => 0.0801333333365323
],
[
'lat' => 49.3635266991555,
'lng' => 0.0801483333364938
],
]
],
],
],
Expand Down Expand Up @@ -133,6 +147,16 @@ private function createExpectedArray()
'lng' => 0.0801333333365323
],
'duration' => 9.0,
'bounds' => [
[
'lat' => 49.4574117319429,
'lng' => 0.0342948235267376
],
[
'lat' => 49.4573700325059,
'lng' => 0.0343682156842231
],
]
],
],
[
Expand Down Expand Up @@ -189,6 +213,16 @@ private function createExpectedArray()
'lng' => 0.0342948235267376
],
'duration' => 3.0,
'bounds' => [
[
'lat' => 49.4574117319429,
'lng' => 0.0342948235267376
],
[
'lat' => 49.4573700325059,
'lng' => 0.0343682156842231
],
]
],
],
],
Expand Down Expand Up @@ -216,6 +250,16 @@ private function createExpectedArray()
'lng' => 0.0342948235267376
],
'duration' => 3.0,
'bounds' => [
[
'lat' => 49.4574117319429,
'lng' => 0.0342948235267376
],
[
'lat' => 49.4573700325059,
'lng' => 0.0343682156842231
],
]
],
],
],
Expand Down
9 changes: 1 addition & 8 deletions tests/UnitTests/phpGPX/Parsers/BoundsParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,7 @@ class BoundsParserTest extends AbstractParserTest

public static function createTestInstance()
{
$bounds = new Bounds();

$bounds->maxLatitude = 49.090543;
$bounds->maxLongitude = 18.886939;
$bounds->minLatitude = 49.072489;
$bounds->minLongitude = 18.814543;

return $bounds;
return new Bounds(49.072489, 18.814543, 49.090543, 18.886939);
}

protected function setUp(): void
Expand Down
25 changes: 25 additions & 0 deletions tests/UnitTests/phpGPX/Parsers/PointParserTest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"ageofdgpsdata": null,
"cmt": null,
"desc": null,
"dgpsid": null,
"difference": null,
"distance": null,
"ele": 2419,
"extensions": null,
"fix": null,
"geoidheight": null,
"hdop": null,
"lat": 46.571948,
"link": [],
"lon": 8.414757,
"magvar": null,
"name": null,
"pdop": null,
"sat": null,
"src": null,
"sym": null,
"time": "2017-08-13T07:10:41+00:00",
"type": null,
"vdop": null
}

0 comments on commit 7131274

Please sign in to comment.