Completed
Push — master ( 3c4a39...ba1925 )
by Doug
02:35
created

Cartesian::transformDatum()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 17
rs 9.4286
cc 1
eloc 11
nc 1
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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
    public function __construct($x, $y, $z, RefEll $refEll)
49
    {
50
        $this->setX($x);
51
        $this->setY($y);
52
        $this->setZ($z);
53
        $this->setRefEll($refEll);
54
    }
55
56
    /**
57
     * String version of coordinate.
58
     * @return string
59
     */
60
    public function __toString()
61
    {
62
        return "({$this->x}, {$this->y}, {$this->z})";
63
    }
64
65
    /**
66
     * @return float
67
     */
68
    public function getX()
69
    {
70
        return $this->x;
71
    }
72
73
    /**
74
     * @param float $x
75
     */
76
    public function setX($x)
77
    {
78
        $this->x = $x;
79
    }
80
81
    /**
82
     * @return float
83
     */
84
    public function getY()
85
    {
86
        return $this->y;
87
    }
88
89
    /**
90
     * @param float $y
91
     */
92
    public function setY($y)
93
    {
94
        $this->y = $y;
95
    }
96
97
    /**
98
     * @return float
99
     */
100
    public function getZ()
101
    {
102
        return $this->z;
103
    }
104
105
    /**
106
     * @param float $z
107
     */
108
    public function setZ($z)
109
    {
110
        $this->z = $z;
111
    }
112
113
    /**
114
     * @return RefEll
115
     */
116
    public function getRefEll()
117
    {
118
        return $this->refEll;
119
    }
120
121
    /**
122
     * @param RefEll $refEll
123
     */
124
    public function setRefEll($refEll)
125
    {
126
        $this->refEll = $refEll;
127
    }
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
    public function toLatitudeLongitude()
137
    {
138
139
        $lambda = rad2deg(atan2($this->y, $this->x));
140
141
        $p = sqrt(pow($this->x, 2) + pow($this->y, 2));
142
143
        $phi = atan($this->z / ($p * (1 - $this->refEll->getEcc())));
144
145
        do {
146
            $phi1 = $phi;
147
            $v = $this->refEll->getMaj() / (sqrt(1 - $this->refEll->getEcc() * pow(sin($phi), 2)));
148
            $phi = atan(($this->z + ($this->refEll->getEcc() * $v * sin($phi))) / $p);
149
        } while (abs($phi - $phi1) >= 0.00001);
150
151
        $h = $p / cos($phi) - $v;
152
153
        $phi = rad2deg($phi);
154
155
        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
    public static function fromLatLong(LatLng $latLng)
167
    {
168
169
        $a = $latLng->getRefEll()->getMaj();
170
        $eSquared = $latLng->getRefEll()->getEcc();
171
        $phi = deg2rad($latLng->getLat());
172
        $lambda = deg2rad($latLng->getLng());
173
174
        $v = $a / (sqrt(1 - $eSquared * pow(sin($phi), 2)));
175
        $x = ($v + $latLng->getH()) * cos($phi) * cos($lambda);
176
        $y = ($v + $latLng->getH()) * cos($phi) * sin($lambda);
177
        $z = ((1 - $eSquared) * $v + $latLng->getH()) * sin($phi);
178
179
        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 seconds
190
     * @param float $rotY  rotation about y-axis in seconds
191
     * @param float $rotZ  rotation about z-axis in seconds
192
     * @return mixed
193
     */
194
    public function transformDatum(RefEll $toRefEll, $tranX, $tranY, $tranZ, $scale, $rotX, $rotY, $rotZ)
195
    {
196
197
        //Helmert uses rotations in radians
198
        $rotX = deg2rad($rotX / 3600);
199
        $rotY = deg2rad($rotY / 3600);
200
        $rotZ = deg2rad($rotZ / 3600);
201
202
        $x = $tranX + ($this->getX() * (1 + $scale)) - ($this->getY() * $rotZ) + ($this->getZ() * $rotY);
203
        $y = $tranY + ($this->getX() * $rotZ) + ($this->getY() * (1 + $scale)) - ($this->getZ() * $rotX);
204
        $z = $tranZ - ($this->getX() * $rotY) + ($this->getY() * $rotX) + ($this->getZ() * (1 + $scale));
205
206
        $this->setX($x);
207
        $this->setY($y);
208
        $this->setZ($z);
209
        $this->setRefEll($toRefEll);
210
    }
211
}
212