Passed
Push — master ( 1c87d2...a64886 )
by Doug
04:35
created

Degree::fromDegreeMinuteHemisphere()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 5
c 0
b 0
f 0
ccs 3
cts 3
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * PHPCoord.
4
 *
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
9
namespace PHPCoord\UnitOfMeasure\Angle;
10
11
use function in_array;
12
use InvalidArgumentException;
13
use function preg_match;
14
use function str_pad;
15
use function str_replace;
16
use function strpos;
17
18
class Degree extends Angle
19
{
20
    private float $angle;
21
22 285
    public function __construct(float $angle)
23
    {
24 285
        $this->angle = $angle;
25 285
    }
26
27 134
    public function asRadians(): Radian
28
    {
29 134
        return new Radian($this->angle * M_PI / 180);
30
    }
31
32 6
    public function asDegrees(): self
33
    {
34 6
        return $this;
35
    }
36
37 121
    public function getValue(): float
38
    {
39 121
        return $this->angle;
40
    }
41
42 1
    public function getUnitName(): string
43
    {
44 1
        return 'degree';
45
    }
46
47 12
    public static function fromDegreeMinuteSecond(string $angle): self
48
    {
49 12
        $regex = '/^(?P<negative>[−-])?(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+)[′\'])?((?P<arcseconds>\d+\.?\d*)[″"])?$/u';
50
51 12
        return self::fromRegex($angle, $regex);
52
    }
53
54 12
    public static function fromDegreeMinuteSecondHemisphere(string $angle): self
55
    {
56 12
        $regex = '/^(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+)[′\'])?((?P<arcseconds>\d+\.?\d*)[″"])?(?P<hemisphere>[NSEW])$/u';
57
58 12
        return self::fromRegex($angle, $regex);
59
    }
60
61 2
    public static function fromHemisphereDegreeMinuteSecond(string $angle): self
62
    {
63 2
        $regex = '/^(?P<hemisphere>[NSEW])(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+)[′\'])?((?P<arcseconds>\d+\.?\d*)[″"])?$/u';
64
65 2
        return self::fromRegex($angle, $regex);
66
    }
67
68 11
    public static function fromDegreeMinute(string $angle): self
69
    {
70 11
        $regex = '/^(?P<negative>[−-])?(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+\.?\d*)[′\'])?$/u';
71
72 11
        return self::fromRegex($angle, $regex);
73
    }
74
75 12
    public static function fromDegreeMinuteHemisphere(string $angle): self
76
    {
77 12
        $regex = '/^(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+\.?\d*)[′\'])?(?P<hemisphere>[NSEW])$/u';
78
79 12
        return self::fromRegex($angle, $regex);
80
    }
81
82 2
    public static function fromHemisphereDegreeMinute(string $angle): self
83
    {
84 2
        $regex = '/^(?P<hemisphere>[NSEW])(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+\.?\d*)[′\'])?$/u';
85
86 2
        return self::fromRegex($angle, $regex);
87
    }
88
89 8
    public static function fromDegreeHemisphere(string $angle): self
90
    {
91 8
        $regex = '/^(?P<degrees>\d+\.?\d*)[°º]?(?P<hemisphere>[NSEW])$/u';
92
93 8
        return self::fromRegex($angle, $regex);
94
    }
95
96 2
    public static function fromHemisphereDegree(string $angle): self
97
    {
98 2
        $regex = '/^(?P<hemisphere>[NSEW])(?P<degrees>\d+\.?\d*)[°º]?$/u';
99
100 2
        return self::fromRegex($angle, $regex);
101
    }
102
103 3
    public static function fromSexagesimalDMSS(string $angle): self
104
    {
105 3
        $regex = '/^(?P<negative>[−-])?(?P<degrees>\d+)(?P<arcminutes>\d{2})(?P<arcseconds>\d{2}\.\d*)$/u';
106
107 3
        return self::fromRegex($angle, $regex);
108
    }
109
110 21
    public static function fromSexagesimalDMS(string $angle): self
111
    {
112 21
        $decimalPosition = strpos($angle, '.');
113 21
        if ($decimalPosition) {
114 21
            $angle = str_pad($angle, $decimalPosition + 5, '0', STR_PAD_RIGHT);
115
        } else {
116
            $angle .= '.0000';
117
        }
118 21
        $regex = '/^(?P<negative>[−-])?(?P<degrees>\d+)\.(?P<arcminutes>\d{2})(?P<arcseconds>\d{2})(?P<fractionarcseconds>\d+)?$/u';
119
120 21
        return self::fromRegex($angle, $regex);
121
    }
122
123 3
    public static function fromSexagesimalDM(string $angle): self
124
    {
125 3
        $decimalPosition = strpos($angle, '.');
126 3
        if ($decimalPosition) {
127 3
            $angle = str_pad($angle, $decimalPosition + 5, '0', STR_PAD_RIGHT);
128
        } else {
129
            $angle .= '.0000';
130
        }
131 3
        $regex = '/^(?P<negative>[−-])?(?P<degrees>\d+)\.(?P<arcminutes>\d{2})(?P<fractionarcminutes>\d+)?$/u';
132
133 3
        return self::fromRegex($angle, $regex);
134
    }
135
136 88
    private static function fromRegex(string $angle, string $regex): self
137
    {
138 88
        $angle = str_replace(' ', '', $angle);
139 88
        $foundAngle = preg_match($regex, $angle, $angleParts, PREG_UNMATCHED_AS_NULL);
140
141 88
        if (!$foundAngle) {
142 8
            throw new InvalidArgumentException("Could not find angle in '{$angle}'");
143
        }
144
145 80
        $degrees = ($angleParts['degrees'] * 1);
146 80
        $degrees += (($angleParts['arcminutes'] ?? 0) / 60);
147 80
        $degrees += (($angleParts['fractionarcminutes'] ?? 0) / 60 / 100);
148 80
        $degrees += (($angleParts['arcseconds'] ?? 0) / 3600);
149 80
        $degrees += (($angleParts['fractionarcseconds'] ?? 0) / 3600 / 100);
150
151 80
        if ($angleParts['negative'] ?? '' || in_array($angleParts['hemisphere'] ?? [], ['S', 'W'], true)) {
152 29
            $degrees *= -1;
153
        }
154
155 80
        return new static($degrees);
156
    }
157
}
158