Passed
Push — master ( be3192...a784d9 )
by Doug
25:13
created

VerticalPoint::verticalOffsetAndSlope()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 12
c 0
b 0
f 0
nc 1
nop 8
dl 0
loc 25
ccs 13
cts 13
cp 1
crap 1
rs 9.8666

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
 *
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
9
namespace PHPCoord;
10
11
use function abs;
12
use function cos;
13
use DateTime;
14
use DateTimeImmutable;
15
use DateTimeInterface;
16
use PHPCoord\CoordinateReferenceSystem\Vertical;
17
use PHPCoord\Exception\InvalidCoordinateReferenceSystemException;
18
use PHPCoord\UnitOfMeasure\Angle\Angle;
19
use PHPCoord\UnitOfMeasure\Length\Length;
20
use PHPCoord\UnitOfMeasure\Length\Metre;
21
use function sin;
22
use function sqrt;
23
24
/**
25
 * Coordinate representing a vertical dimension.
26
 */
27
class VerticalPoint extends Point
28
{
29
    /**
30
     * Height.
31
     */
32
    protected Length $height;
33
34
    /**
35
     * Coordinate reference system.
36
     */
37
    protected Vertical $crs;
38
39
    /**
40
     * Coordinate epoch (date for which the specified coordinates represented this point).
41
     */
42
    protected ?DateTimeImmutable $epoch;
43
44
    /**
45
     * Constructor.
46
     * @param Length $height refer to CRS for preferred unit of measure, but any length unit accepted
47
     */
48 180
    protected function __construct(Length $height, Vertical $crs, ?DateTimeInterface $epoch = null)
49
    {
50 180
        $this->height = Length::convert($height, $crs->getCoordinateSystem()->getAxes()[0]->getUnitOfMeasureId());
51 180
        $this->crs = $crs;
52
53 180
        if ($epoch instanceof DateTime) {
54 9
            $epoch = DateTimeImmutable::createFromMutable($epoch);
55
        }
56 180
        $this->epoch = $epoch;
57 180
    }
58
59
    /**
60
     * Constructor.
61
     * @param Length $height refer to CRS for preferred unit of measure, but any length unit accepted
62
     */
63 180
    public static function create(Length $height, Vertical $crs, ?DateTimeInterface $epoch = null): self
64
    {
65 180
        return new static($height, $crs, $epoch);
66
    }
67
68 144
    public function getHeight(): Length
69
    {
70 144
        return $this->height;
71
    }
72
73 45
    public function getCRS(): Vertical
74
    {
75 45
        return $this->crs;
76
    }
77
78 27
    public function getCoordinateEpoch(): ?DateTimeImmutable
79
    {
80 27
        return $this->epoch;
81
    }
82
83 9
    public function calculateDistance(Point $to): Length
84
    {
85 9
        if ($to->getCRS()->getSRID() !== $this->crs->getSRID()) {
86
            throw new InvalidCoordinateReferenceSystemException('Can only calculate distances between two points in the same CRS');
87
        }
88
89
        /* @var self $to */
90 9
        return new Metre(abs($this->height->asMetres()->getValue() - $to->height->asMetres()->getValue()));
91
    }
92
93 54
    public function __toString(): string
94
    {
95 54
        return "({$this->height})";
96
    }
97
98
    /**
99
     * Vertical Offset
100
     * This transformation allows calculation of height (or depth) in the target system by adding the parameter value
101
     * to the height (or depth)-value of the point in the source system.
102
     */
103 9
    public function verticalOffset(
104
        Vertical $to,
105
        Length $verticalOffset
106
    ): self {
107 9
        return static::create($this->height->add($verticalOffset), $to);
108
    }
109
110
    /**
111
     * Vertical Offset and Slope
112
     * This transformation allows calculation of height in the target system by applying the parameter values to the
113
     * height value of the point in the source system.
114
     */
115 18
    public function verticalOffsetAndSlope(
116
        Vertical $to,
117
        Angle $ordinate1OfEvaluationPoint,
118
        Angle $ordinate2OfEvaluationPoint,
119
        Length $verticalOffset,
120
        Angle $inclinationInLatitude,
121
        Angle $inclinationInLongitude,
122
        string $EPSGCodeForHorizontalCRS,
0 ignored issues
show
Unused Code introduced by
The parameter $EPSGCodeForHorizontalCRS is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

122
        /** @scrutinizer ignore-unused */ string $EPSGCodeForHorizontalCRS,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
123
        GeographicPoint $horizontalPoint
124
    ): self {
125 18
        $latitude = $horizontalPoint->getLatitude()->asRadians()->getValue();
126 18
        $longitude = $horizontalPoint->getLongitude()->asRadians()->getValue();
127 18
        $latitudeOrigin = $ordinate1OfEvaluationPoint->asRadians()->getValue();
128 18
        $longitudeOrigin = $ordinate2OfEvaluationPoint->asRadians()->getValue();
129 18
        $a = $horizontalPoint->getCRS()->getDatum()->getEllipsoid()->getSemiMajorAxis()->asMetres()->getValue();
130 18
        $e2 = $horizontalPoint->getCRS()->getDatum()->getEllipsoid()->getEccentricitySquared();
131
132 18
        $rhoOrigin = $a * (1 - $e2) / (1 - $e2 * sin($latitudeOrigin) ** 2) ** 1.5;
133 18
        $nuOrigin = $a / sqrt(1 - $e2 * (sin($latitudeOrigin) ** 2));
134
135 18
        $latitudeTerm = new Metre($inclinationInLatitude->asRadians()->getValue() * $rhoOrigin * ($latitude - $latitudeOrigin));
136 18
        $longitudeTerm = new Metre($inclinationInLongitude->asRadians()->getValue() * $nuOrigin * ($longitude - $longitudeOrigin) * cos($latitude));
137 18
        $newVerticalHeight = $this->getHeight()->add($verticalOffset)->add($latitudeTerm)->add($longitudeTerm);
138
139 18
        return self::create($newVerticalHeight, $to);
140
    }
141
142
    /**
143
     * Height Depth Reversal.
144
     */
145 9
    public function heightDepthReversal(
146
        Vertical $to
147
    ): self {
148 9
        return static::create($this->height->multiply(-1), $to);
149
    }
150
151
    /**
152
     * Change of Vertical Unit.
153
     */
154 9
    public function changeOfVerticalUnit(
155
        Vertical $to
156
    ): self {
157
        // units are auto-converted, don't need to use the supplied param
158 9
        return static::create($this->height, $to, $this->epoch);
159
    }
160
161
    /**
162
     * Zero-tide height to mean-tide height (EVRF2019)
163
     * The offset of -0.08593 is applied to force EVRF2019 mean-tide height to be equal to EVRF2019 height at the
164
     * EVRF2019 nominal origin at Amsterdams Peil.
165
     */
166 18
    public function zeroTideHeightToMeanTideHeightEVRF2019(
167
        Vertical $to,
168
        bool $inReverse,
169
        GeographicPoint $horizontalPoint
170
    ): self {
171 18
        $latitude = $horizontalPoint->getLatitude()->asRadians()->getValue();
172 18
        $delta = new Metre((0.29541 * sin($latitude) ** 2 + 0.00042 * sin($latitude) ** 4 - 0.0994) - 0.08593);
173
174 18
        if ($inReverse) {
175 9
            $delta = $delta->multiply(-1);
176
        }
177
178 18
        return static::create($this->height->add($delta), $to);
179
    }
180
}
181