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

Cartesian::transformDatum()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 2
Bugs 1 Features 1
Metric Value
c 2
b 1
f 1
dl 0
loc 12
ccs 9
cts 9
cp 1
rs 9.4285
cc 1
eloc 8
nc 1
nop 8
crap 1

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 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