Passed
Push — 4.x ( c37faa...bd875a )
by Doug
12:53
created

GeocentricPoint   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 84
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 8
eloc 21
c 1
b 0
f 0
dl 0
loc 84
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A calculateSurfaceDistance() 0 12 2
A __construct() 0 6 1
A getCRS() 0 3 1
A getX() 0 3 1
A __toString() 0 3 1
A getY() 0 3 1
A getZ() 0 3 1
1
<?php
2
/**
3
 * PHPCoord.
4
 *
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
9
namespace PHPCoord;
10
11
use PHPCoord\CoordinateReferenceSystem\CoordinateReferenceSystem;
12
use PHPCoord\CoordinateReferenceSystem\Geocentric;
13
use PHPCoord\CoordinateSystem\Axis;
14
use PHPCoord\UnitOfMeasure\Length\Length;
15
use PHPCoord\UnitOfMeasure\Length\Metre;
16
use PHPCoord\UnitOfMeasure\UnitOfMeasureFactory;
17
18
/**
19
 * Coordinate representing a point in ECEF geocentric form.
20
 * @author Doug Wright
21
 */
22
class GeocentricPoint extends Point
23
{
24
    /**
25
     * X co-ordinate.
26
     * @var Length
27
     */
28
    protected $x;
29
30
    /**
31
     * Y co-ordinate.
32
     * @var Length
33
     */
34
    protected $y;
35
36
    /**
37
     * Z co-ordinate.
38
     * @var Length
39
     */
40
    protected $z;
41
42
    /**
43
     * Coordinate reference system.
44
     * @var CoordinateReferenceSystem
45
     */
46
    protected $crs;
47
48
    /**
49
     * Constructor.
50
     * @param Length $x refer to CRS for preferred unit of measure, but any length unit accepted
51
     * @param Length $y refer to CRS for preferred unit of measure, but any length unit accepted
52
     * @param Length $z refer to CRS for preferred unit of measure, but any length unit accepted
53
     */
54
    public function __construct(Length $x, Length $y, Length $z, Geocentric $crs)
55
    {
56
        $this->crs = $crs;
57
        $this->x = UnitOfMeasureFactory::convertLength($x, $this->getAxisByName(Axis::GEOCENTRIC_X)->getUnitOfMeasureId());
58
        $this->y = UnitOfMeasureFactory::convertLength($y, $this->getAxisByName(Axis::GEOCENTRIC_Y)->getUnitOfMeasureId());
59
        $this->z = UnitOfMeasureFactory::convertLength($z, $this->getAxisByName(Axis::GEOCENTRIC_Z)->getUnitOfMeasureId());
60
    }
61
62
    public function getX(): Length
63
    {
64
        return $this->x;
65
    }
66
67
    public function getY(): Length
68
    {
69
        return $this->y;
70
    }
71
72
    public function getZ(): Length
73
    {
74
        return $this->z;
75
    }
76
77
    public function getCRS(): CoordinateReferenceSystem
78
    {
79
        return $this->crs;
80
    }
81
82
    /**
83
     * Calculate surface distance between two points.
84
     * Note: this implementation is currently not accurate over long distances, it is the straight line distance, not
85
     * the surface distance.
86
     */
87
    public function calculateSurfaceDistance(Point $to): Length
88
    {
89
        if ($to->getCRS()->getEpsgCode() !== $this->crs->getEpsgCode()) {
90
            throw new \InvalidArgumentException('Can only calculate distances between two points in the same CRS');
91
        }
92
93
        /* @var GeocentricPoint $to */
94
        return new Metre(
95
            sqrt(
96
                ($to->getX()->getValue() - $this->x->getValue()) ** 2 +
97
                ($to->getY()->getValue() - $this->y->getValue()) ** 2 +
98
                ($to->getZ()->getValue() - $this->z->getValue()) ** 2
99
            )
100
        );
101
    }
102
103
    public function __toString(): string
104
    {
105
        return "({$this->x}, {$this->y}, {$this->z})";
106
    }
107
}
108