Passed
Push — 4.x ( 1d49e7...4cde9a )
by Doug
06:44
created

CompoundPoint::__toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * PHPCoord.
4
 *
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
9
namespace PHPCoord;
10
11
use DateTime;
12
use DateTimeImmutable;
13
use DateTimeInterface;
14
use PHPCoord\CoordinateOperation\AutoConversion;
15
use PHPCoord\CoordinateOperation\GeographicValue;
16
use PHPCoord\CoordinateReferenceSystem\Compound;
17
use PHPCoord\CoordinateReferenceSystem\Geographic3D;
18
use PHPCoord\CoordinateReferenceSystem\Vertical;
19
use PHPCoord\Exception\InvalidCoordinateReferenceSystemException;
20
use PHPCoord\UnitOfMeasure\Angle\Angle;
21
use PHPCoord\UnitOfMeasure\Length\Length;
22
use PHPCoord\UnitOfMeasure\Length\Metre;
23
24
/**
25
 * Coordinate representing a point expressed in 2 different CRSs (2D horizontal + 1D Vertical).
26
 */
27
class CompoundPoint extends Point
28
{
29
    use AutoConversion;
30
31
    /**
32
     * Horizontal point.
33
     * @var GeographicPoint|ProjectedPoint
34
     */
35
    protected Point $horizontalPoint;
36
37
    /**
38
     * Vertical point.
39
     */
40
    protected VerticalPoint $verticalPoint;
41
42
    /**
43
     * Coordinate reference system.
44
     */
45
    protected Compound $crs;
46
47
    /**
48
     * Coordinate epoch (date for which the specified coordinates represented this point).
49
     */
50
    protected ?DateTimeImmutable $epoch;
51
52
    /**
53
     * Constructor.
54
     * @param GeographicPoint|ProjectedPoint $horizontalPoint
55
     */
56 7
    protected function __construct(Point $horizontalPoint, VerticalPoint $verticalPoint, Compound $crs, ?DateTimeInterface $epoch = null)
57
    {
58 7
        $this->horizontalPoint = $horizontalPoint;
0 ignored issues
show
Documentation Bug introduced by
$horizontalPoint is of type PHPCoord\Point, but the property $horizontalPoint was declared to be of type PHPCoord\GeographicPoint|PHPCoord\ProjectedPoint. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
59 7
        $this->verticalPoint = $verticalPoint;
60 7
        $this->crs = $crs;
61
62 7
        if ($epoch instanceof DateTime) {
63 1
            $epoch = DateTimeImmutable::createFromMutable($epoch);
64
        }
65 7
        $this->epoch = $epoch;
66 7
    }
67
68
    /**
69
     * @param GeographicPoint|ProjectedPoint $horizontalPoint
70
     */
71 7
    public static function create(Point $horizontalPoint, VerticalPoint $verticalPoint, Compound $crs, ?DateTimeInterface $epoch = null)
72
    {
73 7
        return new static($horizontalPoint, $verticalPoint, $crs, $epoch);
74
    }
75
76 5
    public function getHorizontalPoint(): Point
77
    {
78 5
        return $this->horizontalPoint;
79
    }
80
81 5
    public function getVerticalPoint(): VerticalPoint
82
    {
83 5
        return $this->verticalPoint;
84
    }
85
86 6
    public function getCRS(): Compound
87
    {
88 6
        return $this->crs;
89
    }
90
91 4
    public function getCoordinateEpoch(): ?DateTimeImmutable
92
    {
93 4
        return $this->epoch;
94
    }
95
96
    /**
97
     * Calculate distance between two points.
98
     */
99 2
    public function calculateDistance(Point $to): Length
100
    {
101 2
        if ($to->getCRS()->getSRID() !== $this->crs->getSRID()) {
102 1
            throw new InvalidCoordinateReferenceSystemException('Can only calculate distances between two points in the same CRS');
103
        }
104
105
        /* @var CompoundPoint $to */
106 1
        return $this->horizontalPoint->calculateDistance($to->horizontalPoint);
107
    }
108
109 3
    public function __toString(): string
110
    {
111 3
        return "({$this->horizontalPoint}, {$this->verticalPoint})";
112
    }
113
114
    /**
115
     * Geographic2D with Height Offsets.
116
     * This transformation allows calculation of coordinates in the target system by adding the parameter value to the
117
     * coordinate values of the point in the source system.
118
     */
119 1
    public function geographic2DWithHeightOffsets(
120
        Geographic3D $to,
121
        Angle $latitudeOffset,
122
        Angle $longitudeOffset,
123
        Length $geoidUndulation
124
    ): GeographicPoint {
125 1
        $toLatitude = $this->getHorizontalPoint()->getLatitude()->add($latitudeOffset);
0 ignored issues
show
Bug introduced by
The method getLatitude() does not exist on PHPCoord\Point. It seems like you code against a sub-type of PHPCoord\Point such as PHPCoord\GeographicPoint. ( Ignorable by Annotation )

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

125
        $toLatitude = $this->getHorizontalPoint()->/** @scrutinizer ignore-call */ getLatitude()->add($latitudeOffset);
Loading history...
126 1
        $toLongitude = $this->getHorizontalPoint()->getLongitude()->add($longitudeOffset);
0 ignored issues
show
Bug introduced by
The method getLongitude() does not exist on PHPCoord\Point. It seems like you code against a sub-type of PHPCoord\Point such as PHPCoord\GeographicPoint. ( Ignorable by Annotation )

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

126
        $toLongitude = $this->getHorizontalPoint()->/** @scrutinizer ignore-call */ getLongitude()->add($longitudeOffset);
Loading history...
127 1
        $toHeight = $this->getVerticalPoint()->getHeight()->add($geoidUndulation);
128
129 1
        return GeographicPoint::create($toLatitude, $toLongitude, $toHeight, $to, $this->epoch);
130
    }
131
132
    /**
133
     * Vertical Offset and Slope
134
     * This transformation allows calculation of height in the target system by applying the parameter values to the
135
     * height value of the point in the source system.
136
     */
137 1
    public function verticalOffsetAndSlope(
138
        Compound $to,
139
        Angle $ordinate1OfEvaluationPoint,
140
        Angle $ordinate2OfEvaluationPoint,
141
        Length $verticalOffset,
142
        Angle $inclinationInLatitude,
143
        Angle $inclinationInLongitude,
144
        int $horizontalCRSCode
0 ignored issues
show
Unused Code introduced by
The parameter $horizontalCRSCode 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

144
        /** @scrutinizer ignore-unused */ int $horizontalCRSCode

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...
145
    ): self {
146 1
        $latitude = $this->horizontalPoint->getLatitude()->asRadians()->getValue();
147 1
        $longitude = $this->horizontalPoint->getLongitude()->asRadians()->getValue();
148 1
        $latitudeOrigin = $ordinate1OfEvaluationPoint->asRadians()->getValue();
149 1
        $longitudeOrigin = $ordinate2OfEvaluationPoint->asRadians()->getValue();
150 1
        $a = $this->horizontalPoint->getCRS()->getDatum()->getEllipsoid()->getSemiMajorAxis()->asMetres()->getValue();
151 1
        $e2 = $this->horizontalPoint->getCRS()->getDatum()->getEllipsoid()->getEccentricitySquared();
152
153 1
        $rhoOrigin = $a * (1 - $e2) / (1 - $e2 * sin($latitudeOrigin) ** 2) ** 1.5;
154 1
        $nuOrigin = $a / sqrt(1 - $e2 * (sin($latitudeOrigin) ** 2));
155
156 1
        $latitudeTerm = new Metre($inclinationInLatitude->asRadians()->getValue() * $rhoOrigin * ($latitude - $latitudeOrigin));
157 1
        $longitudeTerm = new Metre($inclinationInLongitude->asRadians()->getValue() * $nuOrigin * ($longitude - $longitudeOrigin) * cos($latitude));
158 1
        $newVerticalHeight = $this->verticalPoint->getHeight()->add($verticalOffset)->add($latitudeTerm)->add($longitudeTerm);
159
160 1
        $newVerticalPoint = VerticalPoint::create($newVerticalHeight, $to->getVertical());
161
162 1
        return static::create($this->horizontalPoint, $newVerticalPoint, $to);
163
    }
164
165 1
    public function asGeographicValue(): GeographicValue
166
    {
167 1
        return $this->horizontalPoint->asGeographicValue();
0 ignored issues
show
Bug introduced by
The method asGeographicValue() does not exist on PHPCoord\Point. It seems like you code against a sub-type of said class. However, the method does not exist in PHPCoord\VerticalPoint. Are you sure you never get one of those? ( Ignorable by Annotation )

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

167
        return $this->horizontalPoint->/** @scrutinizer ignore-call */ asGeographicValue();
Loading history...
168
    }
169
}
170