Skip to content

Commit aac01e5

Browse files
authored
Merge pull request #61 πŸ‘©πŸ»β€πŸ¦°
* Real distance calculator * Fixed real distance tests * Merge branch 'master' into feature/real-distance * Few text changes, year updates
1 parent b17febf commit aac01e5

13 files changed

+108
-13
lines changed

β€ŽCHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 1.2.0 : 2022-07-30
4+
5+
- **Feature**: [Real distance calculation #37](https://github.com/Sibyx/phpGPX/issues/37) (DistanceCalculator refactor)
6+
37
## 1.1.3 : 2021-07-29
48

59
- **Fix**: [Fix negative duration #58](https://github.com/Sibyx/phpGPX/pull/58) by [@neronmoon](https://github.com/neronmoon)

β€ŽLICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2017 Jakub Dubec
3+
Copyright (c) 2017-2022 Jakub Dubec
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

β€ŽREADME.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ You can easily install phpGPX library with [composer](https://getcomposer.org/).
4444
please use release candidates.
4545

4646
```
47-
composer require sibyx/phpgpx:1.1.3
47+
composer require sibyx/phpgpx:1.2.0
4848
```
4949

5050
## Examples

β€Žcomposer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "sibyx/phpgpx",
33
"type": "library",
4-
"version": "1.1.3",
4+
"version": "1.2.0",
55
"description": "A simple PHP library for GPX import/export",
66
"minimum-stability": "stable",
77
"license": "MIT",

β€Žsrc/phpGPX/Helpers/DistanceCalculator.php

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,56 @@
33
* DistanceCalculator.php
44
*
55
* @author Jens Hassler
6+
* @author Jakub Dubec
67
* @since 07/2018
8+
* @version 2.0
79
*/
810

911
namespace phpGPX\Helpers;
1012

11-
use phpGPX\Helpers\GeoHelper;
1213
use phpGPX\Models\Point;
1314
use phpGPX\phpGPX;
1415

1516
class DistanceCalculator
1617
{
18+
/**
19+
* @var Point[]
20+
*/
21+
private $points;
22+
23+
/**
24+
* DistanceCalculator constructor.
25+
* @param Point[] $points
26+
*/
27+
public function __construct(array $points)
28+
{
29+
$this->points = $points;
30+
}
31+
32+
public function getRawDistance()
33+
{
34+
return $this->calculate([GeoHelper::class, 'getRawDistance']);
35+
}
36+
37+
public function getRealDistance()
38+
{
39+
return $this->calculate([GeoHelper::class, 'getRealDistance']);
40+
}
41+
1742
/**
1843
* @param Point[]|array $points
1944
* @return float
2045
*/
21-
public static function calculate(array $points)
46+
private function calculate($strategy)
2247
{
2348
$distance = 0;
2449

25-
$pointCount = count($points);
50+
$pointCount = count($this->points);
2651

2752
$lastConsideredPoint = null;
2853

2954
for ($p = 0; $p < $pointCount; $p++) {
30-
$curPoint = $points[$p];
55+
$curPoint = $this->points[$p];
3156

3257
// skip the first point
3358
if ($p === 0) {
@@ -36,11 +61,11 @@ public static function calculate(array $points)
3661
}
3762

3863
// calculate the delta from current point to last considered point
39-
$curPoint->difference = GeoHelper::getDistance($lastConsideredPoint, $curPoint);
64+
$curPoint->difference = call_user_func($strategy, $lastConsideredPoint, $curPoint);
4065

4166
// if smoothing is applied we only consider points with a delta above the threshold (e.g. 2 meters)
4267
if (phpGPX::$APPLY_DISTANCE_SMOOTHING) {
43-
$differenceFromLastConsideredPoint = GeoHelper::getDistance($curPoint, $lastConsideredPoint);
68+
$differenceFromLastConsideredPoint = call_user_func($strategy, $curPoint, $lastConsideredPoint);
4469

4570
if ($differenceFromLastConsideredPoint > phpGPX::$DISTANCE_SMOOTHING_THRESHOLD) {
4671
$distance += $differenceFromLastConsideredPoint;

β€Žsrc/phpGPX/Helpers/GeoHelper.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ abstract class GeoHelper
2424
* @param Point $point2
2525
* @return float
2626
*/
27-
public static function getDistance(Point $point1, Point $point2)
27+
public static function getRawDistance(Point $point1, Point $point2)
2828
{
2929
$latFrom = deg2rad($point1->latitude);
3030
$lonFrom = deg2rad($point1->longitude);
@@ -38,4 +38,21 @@ public static function getDistance(Point $point1, Point $point2)
3838

3939
return $angle * self::EARTH_RADIUS;
4040
}
41+
42+
/**
43+
* Returns distance between two points including elevation gain/loss
44+
* @param Point $point1
45+
* @param Point $point2
46+
* @return float
47+
*/
48+
public static function getRealDistance(Point $point1, Point $point2)
49+
{
50+
$distance = self::getRawDistance($point1, $point2);
51+
52+
$elevation1 = $point1->elevation != null ? $point1->elevation : 0;
53+
$elevation2 = $point2->elevation != null ? $point2->elevation : 0;
54+
$elevDiff = abs($elevation1 - $elevation2);
55+
56+
return sqrt(pow($distance, 2) + pow($elevDiff, 2));
57+
}
4158
}

β€Žsrc/phpGPX/Models/Route.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ public function recalculateStats()
102102
list($this->stats->cumulativeElevationGain, $this->stats->cumulativeElevationLoss) =
103103
ElevationGainLossCalculator::calculate($this->getPoints());
104104

105-
$this->stats->distance = DistanceCalculator::calculate($this->getPoints());
105+
$calculator = new DistanceCalculator($this->getPoints());
106+
$this->stats->distance = $calculator->getRawDistance();
107+
$this->stats->realDistance = $calculator->getRealDistance();
106108

107109
for ($p = 0; $p < $pointCount; $p++) {
108110
if ((phpGPX::$IGNORE_ELEVATION_0 === false || $this->points[$p]->elevation > 0) && $this->stats->minAltitude > $this->points[$p]->elevation) {

β€Žsrc/phpGPX/Models/Segment.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ public function recalculateStats()
9797
list($this->stats->cumulativeElevationGain, $this->stats->cumulativeElevationLoss) =
9898
ElevationGainLossCalculator::calculate($this->getPoints());
9999

100-
$this->stats->distance = DistanceCalculator::calculate($this->getPoints());
100+
$calculator = new DistanceCalculator($this->getPoints());
101+
$this->stats->distance = $calculator->getRawDistance();
102+
$this->stats->realDistance = $calculator->getRealDistance();
101103

102104
for ($i = 0; $i < $count; $i++) {
103105
if ($this->stats->maxAltitude < $this->points[$i]->elevation) {

β€Žsrc/phpGPX/Models/Stats.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ class Stats implements Summarizable
2222
*/
2323
public $distance = 0;
2424

25+
/**
26+
* Distance in meters (m) including elevation loss/gain
27+
* @var float
28+
*/
29+
public $realDistance = 0;
30+
2531
/**
2632
* Average speed in meters per second (m/s)
2733
* @var float
@@ -82,6 +88,7 @@ class Stats implements Summarizable
8288
public function reset()
8389
{
8490
$this->distance = null;
91+
$this->realDistance = null;
8592
$this->averageSpeed = null;
8693
$this->averagePace = null;
8794
$this->minAltitude = null;
@@ -100,6 +107,7 @@ public function toArray()
100107
{
101108
return [
102109
'distance' => (float)$this->distance,
110+
'realDistance' => (float)$this->realDistance,
103111
'avgSpeed' => (float)$this->averageSpeed,
104112
'avgPace' => (float)$this->averagePace,
105113
'minAltitude' => (float)$this->minAltitude,

β€Žsrc/phpGPX/Models/Track.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ public function recalculateStats()
124124
$this->stats->cumulativeElevationLoss += $this->segments[$s]->stats->cumulativeElevationLoss;
125125

126126
$this->stats->distance += $this->segments[$s]->stats->distance;
127+
$this->stats->realDistance += $this->segments[$s]->stats->realDistance;
127128

128129
if ($this->stats->minAltitude === null) {
129130
$this->stats->minAltitude = $this->segments[$s]->stats->minAltitude;

β€Žtests/LoadFileTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ private function createExpectedArray()
8484
],
8585
'stats' => [
8686
'distance' => 2.314424561683643,
87+
'realDistance' => 2.314424561683643,
8788
'avgSpeed' => 0.2571582846315159,
8889
'avgPace' => 3888.6555859279733,
8990
'minAltitude' => 0.0,
@@ -98,6 +99,7 @@ private function createExpectedArray()
9899
],
99100
'stats' => [
100101
'distance' => 2.314424561683643,
102+
'realDistance' => 2.314424561683643,
101103
'avgSpeed' => 0.2571582846315159,
102104
'avgPace' => 3888.6555859279733,
103105
'minAltitude' => 0.0,
@@ -141,6 +143,7 @@ private function createExpectedArray()
141143
],
142144
'stats' => [
143145
'distance' => 7.062730302497254,
146+
'realDistance' => 7.062730302497254,
144147
'avgSpeed' => 2.354243434165751,
145148
'avgPace' => 424.7649098167112,
146149
'minAltitude' => 0.0,
@@ -155,6 +158,7 @@ private function createExpectedArray()
155158
],
156159
'stats' => [
157160
'distance' => 7.062730302497254,
161+
'realDistance' => 7.062730302497254,
158162
'avgSpeed' => 2.354243434165751,
159163
'avgPace' => 424.7649098167112,
160164
'minAltitude' => 0.0,

β€Žtests/LoadRouteFileTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ private function createExpectedArray()
8888
],
8989
'stats' => [
9090
'distance' => 132.0785853,
91+
'realDistance' => 132.0785853,
9192
'avgSpeed' => 0.0,
9293
'avgPace' => 0.0,
9394
'minAltitude' => 0.0,
@@ -133,6 +134,7 @@ private function createExpectedArray()
133134
],
134135
'stats' => [
135136
'distance' => 132.0785853,
137+
'realDistance' => 132.0785853,
136138
'avgSpeed' => 0.0,
137139
'avgPace' => 0.0,
138140
'minAltitude' => 0.0,

β€Žtests/UnitTests/phpGPX/Helpers/GeoHelperTest.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,39 @@ public function testGetDistance()
3131

3232
$this->assertEquals(
3333
856.97,
34-
GeoHelper::getDistance($point1, $point2),
34+
GeoHelper::getRawDistance($point1, $point2),
3535
"Invalid distance between two points!",
3636
1
3737
);
3838
}
39+
40+
/**
41+
* @link http://cosinekitty.com/compass.html
42+
*/
43+
public function testRealDistance()
44+
{
45+
$point1 = new Point(Point::WAYPOINT);
46+
$point1->latitude = 48.1573923225717;
47+
$point1->longitude = 17.0547121910204;
48+
$point1->elevation = 100;
49+
50+
$point2 = new Point(Point::WAYPOINT);
51+
$point2->latitude = 48.1644916381763;
52+
$point2->longitude = 17.0591753907502;
53+
$point2->elevation = 200;
54+
55+
$this->assertEquals(
56+
856.97,
57+
GeoHelper::getRawDistance($point1, $point2),
58+
"Invalid distance between two points!",
59+
1
60+
);
61+
62+
$this->assertEquals(
63+
862,
64+
GeoHelper::getRealDistance($point1, $point2),
65+
"Invalid real distance between two points!",
66+
1
67+
);
68+
}
3969
}

0 commit comments

Comments
Β (0)