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

Cartesian::transformDatum()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 13
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
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