Passed
Push — master ( 3e5121...8c57bf )
by Doug
27:00
created

GeographicValue::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
nc 2
nop 4
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 2
rs 10
c 1
b 0
f 0
1
<?php
2
/**
3
 * PHPCoord.
4
 *
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
9
namespace PHPCoord\CoordinateOperation;
10
11
use function cos;
12
use PHPCoord\Datum\Datum;
13
use PHPCoord\UnitOfMeasure\Angle\Angle;
14
use PHPCoord\UnitOfMeasure\Angle\Degree;
15
use PHPCoord\UnitOfMeasure\Angle\Radian;
16
use PHPCoord\UnitOfMeasure\Length\Length;
17
use PHPCoord\UnitOfMeasure\Length\Metre;
18
use function sin;
19
use function sqrt;
20
21
/**
22
 * A geographic point w/out a CRS.
23
 * @internal
24
 */
25
class GeographicValue
26
{
27
    private Radian $latitude;
28
29
    private Radian $longitude;
30
31
    private ?Metre $height;
32
33
    private Datum $datum;
34
35 571
    public function __construct(Angle $latitude, Angle $longitude, ?Length $height, Datum $datum)
36
    {
37 571
        $this->latitude = $this->normaliseLatitude($latitude)->asRadians();
38 571
        $this->longitude = $this->normaliseLongitude($longitude)->asRadians();
39 571
        $this->datum = $datum;
40
41 571
        $this->height = $height ? $height->asMetres() : null;
42 571
    }
43
44 535
    public function getLatitude(): Radian
45
    {
46 535
        return $this->latitude;
47
    }
48
49 535
    public function getLongitude(): Radian
50
    {
51 535
        return $this->longitude;
52
    }
53
54 90
    public function getHeight(): ?Metre
55
    {
56 90
        return $this->height;
57
    }
58
59
    public function getDatum(): Datum
60
    {
61
        return $this->datum;
62
    }
63
64 310
    public function asGeocentricValue(): GeocentricValue
65
    {
66 310
        $ellipsoid = $this->datum->getEllipsoid();
67 310
        $a = $ellipsoid->getSemiMajorAxis()->asMetres()->getValue();
68 310
        $e2 = $ellipsoid->getEccentricitySquared();
69 310
        $latitude = $this->latitude->getValue();
70 310
        $longitude = $this->longitude->getValue() - $this->datum->getPrimeMeridian()->getGreenwichLongitude()->asRadians()->getValue();
71 310
        $h = isset($this->height) ? $this->height->getValue() : 0;
0 ignored issues
show
Bug introduced by
The method getValue() does not exist on null. ( Ignorable by Annotation )

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

71
        $h = isset($this->height) ? $this->height->/** @scrutinizer ignore-call */ getValue() : 0;

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
72
73 310
        $nu = $a / sqrt(1 - $e2 * (sin($latitude) ** 2));
74 310
        $x = ($nu + $h) * cos($latitude) * cos($longitude);
75 310
        $y = ($nu + $h) * cos($latitude) * sin($longitude);
76 310
        $z = ((1 - $e2) * $nu + $h) * sin($latitude);
77
78 310
        return new GeocentricValue(new Metre($x), new Metre($y), new Metre($z), $this->datum);
79
    }
80
81 571
    protected function normaliseLatitude(Angle $latitude): Angle
82
    {
83 571
        if ($latitude->asDegrees()->getValue() > 90) {
84
            return new Degree(90);
85
        }
86 571
        if ($latitude->asDegrees()->getValue() < -90) {
87
            return new Degree(-90);
88
        }
89
90 571
        return $latitude;
91
    }
92
93 571
    protected function normaliseLongitude(Angle $longitude): Angle
94
    {
95 571
        while ($longitude->asDegrees()->getValue() > 180) {
96 9
            $longitude = $longitude->subtract(new Degree(360));
97
        }
98 571
        while ($longitude->asDegrees()->getValue() <= -180) {
99 9
            $longitude = $longitude->add(new Degree(360));
100
        }
101
102 571
        return $longitude;
103
    }
104
}
105