Passed
Push — master ( bbeaaa...9ed6c0 )
by Doug
25:29
created

Degree   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 147
Duplicated Lines 0 %

Test Coverage

Coverage 97.06%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 53
dl 0
loc 147
ccs 66
cts 68
cp 0.9706
rs 10
c 1
b 0
f 0
wmc 26

18 Methods

Rating   Name   Duplication   Size   Complexity  
A asDegrees() 0 3 1
A asRadians() 0 3 1
A getUnitName() 0 3 1
A getValue() 0 3 1
A fromSexagesimalDM() 0 11 2
A fromDegreeHemisphere() 0 5 1
A fromDegreeMinuteHemisphere() 0 5 1
A convert() 0 7 2
A fromRegex() 0 20 6
A fromHemisphereDegree() 0 5 1
A fromSexagesimalDMSS() 0 5 1
A fromDegreeMinuteSecond() 0 5 1
A __construct() 0 3 1
A fromHemisphereDegreeMinuteSecond() 0 5 1
A fromDegreeMinuteSecondHemisphere() 0 5 1
A fromDegreeMinute() 0 5 1
A fromHemisphereDegreeMinute() 0 5 1
A fromSexagesimalDMS() 0 11 2
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 InvalidArgumentException;
12
13
use function in_array;
14
use function preg_match;
15
use function str_pad;
16
use function str_replace;
17
use function strlen;
18
use function strpos;
19
20
use const M_PI;
21
use const PREG_UNMATCHED_AS_NULL;
22
use const STR_PAD_RIGHT;
23
24
class Degree extends Angle
25
{
26
    private float $angle;
27
28 7571
    public function __construct(float $angle)
29
    {
30 7571
        $this->angle = $angle;
31
    }
32
33 6547
    public function asRadians(): Radian
34
    {
35 6547
        return new Radian($this->angle * M_PI / 180);
36
    }
37
38 6158
    public function asDegrees(): self
39
    {
40 6158
        return $this;
41
    }
42
43 7418
    public function getValue(): float
44
    {
45 7418
        return $this->angle;
46
    }
47
48 27
    public function getUnitName(): string
49
    {
50 27
        return 'degree';
51
    }
52
53 108
    public static function fromDegreeMinuteSecond(string $angle): self
54
    {
55 108
        $regex = '/^(?P<negative>[−-])?(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+)[′\'])?((?P<arcseconds>\d+\.?\d*)[″"])?$/u';
56
57 108
        return self::fromRegex($angle, $regex);
58
    }
59
60 126
    public static function fromDegreeMinuteSecondHemisphere(string $angle): self
61
    {
62 126
        $regex = '/^(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+)[′\'])?((?P<arcseconds>\d+\.?\d*)[″"])?(?P<hemisphere>[NSEW])$/u';
63
64 126
        return self::fromRegex($angle, $regex);
65
    }
66
67 18
    public static function fromHemisphereDegreeMinuteSecond(string $angle): self
68
    {
69 18
        $regex = '/^(?P<hemisphere>[NSEW])(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+)[′\'])?((?P<arcseconds>\d+\.?\d*)[″"])?$/u';
70
71 18
        return self::fromRegex($angle, $regex);
72
    }
73
74 99
    public static function fromDegreeMinute(string $angle): self
75
    {
76 99
        $regex = '/^(?P<negative>[−-])?(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+\.?\d*)[′\'])?$/u';
77
78 99
        return self::fromRegex($angle, $regex);
79
    }
80
81 108
    public static function fromDegreeMinuteHemisphere(string $angle): self
82
    {
83 108
        $regex = '/^(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+\.?\d*)[′\'])?(?P<hemisphere>[NSEW])$/u';
84
85 108
        return self::fromRegex($angle, $regex);
86
    }
87
88 18
    public static function fromHemisphereDegreeMinute(string $angle): self
89
    {
90 18
        $regex = '/^(?P<hemisphere>[NSEW])(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+\.?\d*)[′\'])?$/u';
91
92 18
        return self::fromRegex($angle, $regex);
93
    }
94
95 72
    public static function fromDegreeHemisphere(string $angle): self
96
    {
97 72
        $regex = '/^(?P<degrees>\d+\.?\d*)[°º]?(?P<hemisphere>[NSEW])$/u';
98
99 72
        return self::fromRegex($angle, $regex);
100
    }
101
102 18
    public static function fromHemisphereDegree(string $angle): self
103
    {
104 18
        $regex = '/^(?P<hemisphere>[NSEW])(?P<degrees>\d+\.?\d*)[°º]?$/u';
105
106 18
        return self::fromRegex($angle, $regex);
107
    }
108
109 99
    public static function fromSexagesimalDMSS(string $angle): self
110
    {
111 99
        $regex = '/^(?P<negative>[−-])?(?P<degrees>\d+)(?P<arcminutes>\d{2})(?P<arcseconds>\d{2}\.\d*)$/u';
112
113 99
        return self::fromRegex($angle, $regex);
114
    }
115
116 1945
    public static function fromSexagesimalDMS(string $angle): self
117
    {
118 1945
        $decimalPosition = strpos($angle, '.');
119 1945
        if ($decimalPosition) {
120 1828
            $angle = str_pad($angle, $decimalPosition + 5, '0', STR_PAD_RIGHT);
121
        } else {
122 523
            $angle .= '.0000';
123
        }
124 1945
        $regex = '/^(?P<negative>[−-])?(?P<degrees>\d+)\.(?P<arcminutes>\d{2})(?P<arcseconds>\d{2})(?P<fractionarcseconds>\d+)?$/u';
125
126 1945
        return self::fromRegex($angle, $regex);
127
    }
128
129 27
    public static function fromSexagesimalDM(string $angle): self
130
    {
131 27
        $decimalPosition = strpos($angle, '.');
132 27
        if ($decimalPosition) {
133 27
            $angle = str_pad($angle, $decimalPosition + 5, '0', STR_PAD_RIGHT);
134
        } else {
135
            $angle .= '.0000';
136
        }
137 27
        $regex = '/^(?P<negative>[−-])?(?P<degrees>\d+)\.(?P<arcminutes>\d{2})(?P<fractionarcminutes>\d+)?$/u';
138
139 27
        return self::fromRegex($angle, $regex);
140
    }
141
142 2638
    private static function fromRegex(string $angle, string $regex): self
143
    {
144 2638
        $angle = str_replace(' ', '', $angle);
145 2638
        $foundAngle = preg_match($regex, $angle, $angleParts, PREG_UNMATCHED_AS_NULL);
146
147 2638
        if (!$foundAngle) {
148 72
            throw new InvalidArgumentException("Could not find angle in '{$angle}'");
149
        }
150
151 2566
        $degrees = ($angleParts['degrees'] * 1);
152 2566
        $degrees += (($angleParts['arcminutes'] ?? 0) / 60);
153 2566
        $degrees += isset($angleParts['fractionarcminutes']) ? ($angleParts['fractionarcminutes'] / 60 / 10 ** strlen($angleParts['fractionarcminutes'])) : 0;
154 2566
        $degrees += (($angleParts['arcseconds'] ?? 0) / 3600);
155 2566
        $degrees += isset($angleParts['fractionarcseconds']) ? ($angleParts['fractionarcseconds'] / 3600 / 10 ** strlen($angleParts['fractionarcseconds'])) : 0;
156
157 2566
        if ($angleParts['negative'] ?? '' || in_array($angleParts['hemisphere'] ?? [], ['S', 'W'], true)) {
158 388
            $degrees *= -1;
159
        }
160
161 2566
        return new static($degrees);
162
    }
163
164 5799
    public static function convert(Angle $angle, string $targetSRID): Angle
165
    {
166 5799
        if ($targetSRID === self::EPSG_DEGREE) {
167 5799
            return $angle;
168
        }
169
170
        return parent::convert($angle, $targetSRID);
171
    }
172
}
173