Completed
Branch 3.0-dev (e499db)
by Doug
02:12
created

Cartesian::setX()   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 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * PHPCoord
4
 * @package PHPCoord
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
namespace PHPCoord;
9
10
/**
11
 * ECEF Cartesian coordinate
12
 * @author Doug Wright
13
 * @package PHPCoord
14
 */
15
class Cartesian
16
{
17
18
    /**
19
     * X co-ordinate in metres
20
     * @var float
21
     */
22
    protected $x;
23
24
    /**
25
     * Y co-ordinate in metres
26
     * @var float
27
     */
28
    protected $y;
29
30
    /**
31
     * Z co-ordinate in metres
32
     * @var float
33
     */
34
    protected $z;
35
36
    /**
37
     * Reference ellipsoid used in this datum
38
     * @var RefEll
39
     */
40
    protected $refEll;
41
42
    /**
43
     * Cartesian constructor.
44
     * @param int $x
0 ignored issues
show
Documentation introduced by
Should the type for parameter $x not be double?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
45
     * @param int $y
0 ignored issues
show
Documentation introduced by
Should the type for parameter $y not be double?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
46
     * @param int $z
0 ignored issues
show
Documentation introduced by
Should the type for parameter $z not be double?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
47
     * @param RefEll $refEll
48
     */
49 12
    public function __construct(float $x, float $y, float $z, RefEll $refEll)
50
    {
51 12
        $this->x = $x;
52 12
        $this->y = $y;
53 12
        $this->z = $z;
54 12
        $this->refEll = $refEll;
55
    }
56
57
    /**
58
     * String version of coordinate.
59
     * @return string
60
     */
61 1
    public function __toString(): string
62
    {
63 1
        return "({$this->x}, {$this->y}, {$this->z})";
64
    }
65
66
    /**
67
     * @return float
68
     */
69 11
    public function getX(): float
70
    {
71 11
        return $this->x;
72
    }
73
74
    /**
75
     * @return float
76
     */
77 11
    public function getY(): float
78
    {
79 11
        return $this->y;
80
    }
81
82
    /**
83
     * @return float
84
     */
85 11
    public function getZ(): float
86
    {
87 11
        return $this->z;
88
    }
89
90
    /**
91
     * @return RefEll
92
     */
93 1
    public function getRefEll(): RefEll
94
    {
95 1
        return $this->refEll;
96
    }
97
98
    /**
99
     * Convert these coordinates into a latitude, longitude
100
     * Formula for transformation is taken from OS document
101
     * "A Guide to Coordinate Systems in Great Britain"
102
     *
103
     * @return LatLng
104
     */
105 9
    public function toLatitudeLongitude(): LatLng
106
    {
107 9
        $lambda = rad2deg(atan2($this->y, $this->x));
108
109 9
        $p = sqrt(pow($this->x, 2) + pow($this->y, 2));
110
111 9
        $phi = atan($this->z / ($p * (1 - $this->refEll->getEcc())));
112
113
        do {
114 9
            $phi1 = $phi;
115 9
            $v = $this->refEll->getMaj() / (sqrt(1 - $this->refEll->getEcc() * pow(sin($phi), 2)));
116 9
            $phi = atan(($this->z + ($this->refEll->getEcc() * $v * sin($phi))) / $p);
117 9
        } while (abs($phi - $phi1) >= 0.00001);
118
119 9
        $h = (int)round($p / cos($phi) - $v);
120
121 9
        $phi = rad2deg($phi);
122
123 9
        return new LatLng($phi, $lambda, $h, $this->refEll);
124
    }
125
126
    /**
127
     * Convert a latitude, longitude height to x, y, z
128
     * Formula for transformation is taken from OS document
129
     * "A Guide to Coordinate Systems in Great Britain"
130
     *
131
     * @param LatLng $latLng
132
     * @return Cartesian
133
     */
134 9
    public static function fromLatLong(LatLng $latLng): Cartesian
135
    {
136 9
        $a = $latLng->getRefEll()->getMaj();
137 9
        $eSquared = $latLng->getRefEll()->getEcc();
138 9
        $phi = deg2rad($latLng->getLat());
139 9
        $lambda = deg2rad($latLng->getLng());
140
141 9
        $v = $a / (sqrt(1 - $eSquared * pow(sin($phi), 2)));
142 9
        $x = ($v + $latLng->getH()) * cos($phi) * cos($lambda);
143 9
        $y = ($v + $latLng->getH()) * cos($phi) * sin($lambda);
144 9
        $z = ((1 - $eSquared) * $v + $latLng->getH()) * sin($phi);
145
146 9
        return new static($x, $y, $z, $latLng->getRefEll());
147
    }
148
149
    /**
150
     * Transform the datum used for these coordinates by using a Helmert Transform
151
     * @param RefEll $toRefEll
152
     * @param float $tranX
153
     * @param float $tranY
154
     * @param float $tranZ
155
     * @param float $scale
156
     * @param float $rotX  rotation about x-axis in radians
157
     * @param float $rotY  rotation about y-axis in radians
158
     * @param float $rotZ  rotation about z-axis in radians
159
     * @return Cartesian
160
     */
161 10
    public function transformDatum(
162
        RefEll $toRefEll,
163
        float $tranX,
164
        float $tranY,
165
        float $tranZ,
166
        float $scale,
167
        float $rotX,
168
        float $rotY,
169
        float $rotZ): Cartesian
170
    {
171 10
        $x = $tranX + ($this->getX() * (1 + $scale)) - ($this->getY() * $rotZ) + ($this->getZ() * $rotY);
172 10
        $y = $tranY + ($this->getX() * $rotZ) + ($this->getY() * (1 + $scale)) - ($this->getZ() * $rotX);
173 10
        $z = $tranZ - ($this->getX() * $rotY) + ($this->getY() * $rotX) + ($this->getZ() * (1 + $scale));
174
175 10
        return new static($x, $y, $z, $toRefEll);
176
    }
177
}
178