Completed
Push — master ( 1a8ca7...b2e639 )
by Doug
01:57
created

Cartesian::getRefEll()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * PHPCoord
4
 * @package PHPCoord
5
 * @author Doug Wright
6
 */
7
namespace PHPCoord;
8
9
/**
10
 * ECEF Cartesian coordinate
11
 * @author Doug Wright
12
 * @package PHPCoord
13
 */
14
class Cartesian
15
{
16
17
    /**
18
     * X
19
     * @var float
20
     */
21
    protected $x;
22
23
    /**
24
     * Y
25
     * @var float
26
     */
27
    protected $y;
28
29
    /**
30
     * Z
31
     * @var float
32
     */
33
    protected $z;
34
35
    /**
36
     * Reference ellipsoid used in this datum
37
     * @var RefEll
38
     */
39
    protected $refEll;
40
41
    /**
42
     * Cartesian constructor.
43
     * @param float $x
44
     * @param float $y
45
     * @param float $z
46
     * @param RefEll $refEll
47
     */
48 12
    public function __construct($x, $y, $z, RefEll $refEll)
49
    {
50 12
        $this->setX($x);
51 12
        $this->setY($y);
52 12
        $this->setZ($z);
53 12
        $this->setRefEll($refEll);
54 12
    }
55
56
    /**
57
     * String version of coordinate.
58
     * @return string
59
     */
60 1
    public function __toString()
61
    {
62 1
        return "({$this->x}, {$this->y}, {$this->z})";
63
    }
64
65
    /**
66
     * @return float
67
     */
68 11
    public function getX()
69
    {
70 11
        return $this->x;
71
    }
72
73
    /**
74
     * @param float $x
75
     */
76 12
    public function setX($x)
77
    {
78 12
        $this->x = $x;
79 12
    }
80
81
    /**
82
     * @return float
83
     */
84 11
    public function getY()
85
    {
86 11
        return $this->y;
87
    }
88
89
    /**
90
     * @param float $y
91
     */
92 12
    public function setY($y)
93
    {
94 12
        $this->y = $y;
95 12
    }
96
97
    /**
98
     * @return float
99
     */
100 11
    public function getZ()
101
    {
102 11
        return $this->z;
103
    }
104
105
    /**
106
     * @param float $z
107
     */
108 12
    public function setZ($z)
109
    {
110 12
        $this->z = $z;
111 12
    }
112
113
    /**
114
     * @return RefEll
115
     */
116 1
    public function getRefEll()
117
    {
118 1
        return $this->refEll;
119
    }
120
121
    /**
122
     * @param RefEll $refEll
123
     */
124 12
    public function setRefEll($refEll)
125
    {
126 12
        $this->refEll = $refEll;
127 12
    }
128
129
    /**
130
     * Convert these coordinates into a latitude, longitude
131
     * Formula for transformation is taken from OS document
132
     * "A Guide to Coordinate Systems in Great Britain"
133
     *
134
     * @return LatLng
135
     */
136 9
    public function toLatitudeLongitude()
137
    {
138
139 9
        $lambda = rad2deg(atan2($this->y, $this->x));
140
141 9
        $p = sqrt(pow($this->x, 2) + pow($this->y, 2));
142
143 9
        $phi = atan($this->z / ($p * (1 - $this->refEll->getEcc())));
144
145
        do {
146 9
            $phi1 = $phi;
147 9
            $v = $this->refEll->getMaj() / (sqrt(1 - $this->refEll->getEcc() * pow(sin($phi), 2)));
148 9
            $phi = atan(($this->z + ($this->refEll->getEcc() * $v * sin($phi))) / $p);
149 9
        } while (abs($phi - $phi1) >= 0.00001);
150
151 9
        $h = $p / cos($phi) - $v;
152
153 9
        $phi = rad2deg($phi);
154
155 9
        return new LatLng($phi, $lambda, $h, $this->refEll);
156
    }
157
158
    /**
159
     * Convert a latitude, longitude height to x, y, z
160
     * Formula for transformation is taken from OS document
161
     * "A Guide to Coordinate Systems in Great Britain"
162
     *
163
     * @param LatLng $latLng
164
     * @return Cartesian
165
     */
166 9
    public static function fromLatLong(LatLng $latLng)
167
    {
168
169 9
        $a = $latLng->getRefEll()->getMaj();
170 9
        $eSquared = $latLng->getRefEll()->getEcc();
171 9
        $phi = deg2rad($latLng->getLat());
172 9
        $lambda = deg2rad($latLng->getLng());
173
174 9
        $v = $a / (sqrt(1 - $eSquared * pow(sin($phi), 2)));
175 9
        $x = ($v + $latLng->getH()) * cos($phi) * cos($lambda);
176 9
        $y = ($v + $latLng->getH()) * cos($phi) * sin($lambda);
177 9
        $z = ((1 - $eSquared) * $v + $latLng->getH()) * sin($phi);
178
179 9
        return new static($x, $y, $z, $latLng->getRefEll());
180
    }
181
182
    /**
183
     * Transform the datum used for these coordinates by using a Helmert Transform
184
     * @param RefEll $toRefEll
185
     * @param float $tranX
186
     * @param float $tranY
187
     * @param float $tranZ
188
     * @param float $scale
189
     * @param float $rotX  rotation about x-axis in radians
190
     * @param float $rotY  rotation about y-axis in radians
191
     * @param float $rotZ  rotation about z-axis in radians
192
     * @return mixed
193
     */
194 10
    public function transformDatum(RefEll $toRefEll, $tranX, $tranY, $tranZ, $scale, $rotX, $rotY, $rotZ)
195
    {
196
197 10
        $x = $tranX + ($this->getX() * (1 + $scale)) - ($this->getY() * $rotZ) + ($this->getZ() * $rotY);
198 10
        $y = $tranY + ($this->getX() * $rotZ) + ($this->getY() * (1 + $scale)) - ($this->getZ() * $rotX);
199 10
        $z = $tranZ - ($this->getX() * $rotY) + ($this->getY() * $rotX) + ($this->getZ() * (1 + $scale));
200
201 10
        $this->setX($x);
202 10
        $this->setY($y);
203 10
        $this->setZ($z);
204 10
        $this->setRefEll($toRefEll);
205 10
    }
206
}
207