Passed
Push — master ( 0e0534...3c9843 )
by Doug
02:42
created

VerticalPoint   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 133
Duplicated Lines 0 %

Test Coverage

Coverage 97.5%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 31
c 2
b 0
f 0
dl 0
loc 133
ccs 39
cts 40
cp 0.975
rs 10
wmc 13

11 Methods

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

123
        /** @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...
124
        GeographicPoint $horizontalPoint
125
    ): self {
126 2
        $latitude = $horizontalPoint->getLatitude()->asRadians()->getValue();
127 2
        $longitude = $horizontalPoint->getLongitude()->asRadians()->getValue();
128 2
        $latitudeOrigin = $ordinate1OfEvaluationPoint->asRadians()->getValue();
129 2
        $longitudeOrigin = $ordinate2OfEvaluationPoint->asRadians()->getValue();
130 2
        $a = $horizontalPoint->getCRS()->getDatum()->getEllipsoid()->getSemiMajorAxis()->asMetres()->getValue();
131 2
        $e2 = $horizontalPoint->getCRS()->getDatum()->getEllipsoid()->getEccentricitySquared();
132
133 2
        $rhoOrigin = $a * (1 - $e2) / (1 - $e2 * sin($latitudeOrigin) ** 2) ** 1.5;
134 2
        $nuOrigin = $a / sqrt(1 - $e2 * (sin($latitudeOrigin) ** 2));
135
136 2
        $latitudeTerm = new Metre($inclinationInLatitude->asRadians()->getValue() * $rhoOrigin * ($latitude - $latitudeOrigin));
137 2
        $longitudeTerm = new Metre($inclinationInLongitude->asRadians()->getValue() * $nuOrigin * ($longitude - $longitudeOrigin) * cos($latitude));
138 2
        $newVerticalHeight = $this->getHeight()->add($verticalOffset)->add($latitudeTerm)->add($longitudeTerm);
139
140 2
        return self::create($newVerticalHeight, $to);
141
    }
142
143
    /**
144
     * Height Depth Reversal.
145
     */
146 1
    public function heightDepthReversal(
147
        Vertical $to
148
    ): self {
149 1
        return static::create($this->height->multiply(-1), $to);
150
    }
151
152
    /**
153
     * Change of Vertical Unit.
154
     */
155 1
    public function changeOfVerticalUnit(
156
        Vertical $to,
157
        Scale $unitConversionScalar
0 ignored issues
show
Unused Code introduced by
The parameter $unitConversionScalar 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

157
        /** @scrutinizer ignore-unused */ Scale $unitConversionScalar

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...
158
    ) {
159
        // units are auto-converted, don't need to use the supplied param
160 1
        return static::create($this->height, $to, $this->epoch);
161
    }
162
}
163