Passed
Push — 4.x ( 2e43a7...18aaa8 )
by Doug
06:37
created

Degree::getValue()   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
dl 0
loc 3
c 1
b 0
f 0
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\UnitOfMeasure\Angle;
10
11
use Composer\Pcre\Preg;
12
use InvalidArgumentException;
13
14
use function in_array;
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 STR_PAD_RIGHT;
22
23
class Degree extends Angle
24
{
25
    private float $angle;
26
27 2193
    public function __construct(float $angle)
28
    {
29 2193
        $this->angle = $angle;
30
    }
31
32 1518
    public function asRadians(): Radian
33
    {
34 1518
        return new Radian($this->angle * M_PI / 180);
35
    }
36
37 1230
    public function asDegrees(): self
38
    {
39 1230
        return $this;
40
    }
41
42 2166
    public function getValue(): float
43
    {
44 2166
        return $this->angle;
45
    }
46
47 9
    public function getUnitName(): string
48
    {
49 9
        return 'degree';
50
    }
51
52 90
    public static function fromDegreeMinuteSecond(string $angle): self
53
    {
54 90
        $regex = '/^(?P<negative>[−-])?(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+)[′\'])?((?P<arcseconds>\d+\.?\d*)[″"])?$/u';
55
56 90
        return self::fromRegex($angle, $regex);
57
    }
58
59 90
    public static function fromDegreeMinuteSecondHemisphere(string $angle): self
60
    {
61 90
        $regex = '/^(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+)[′\'])?((?P<arcseconds>\d+\.?\d*)[″"])?(?P<hemisphere>[NSEW])$/u';
62
63 90
        return self::fromRegex($angle, $regex);
64
    }
65
66
    public static function fromHemisphereDegreeMinuteSecond(string $angle): self
67
    {
68
        $regex = '/^(?P<hemisphere>[NSEW])(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+)[′\'])?((?P<arcseconds>\d+\.?\d*)[″"])?$/u';
69
70
        return self::fromRegex($angle, $regex);
71
    }
72
73 81
    public static function fromDegreeMinute(string $angle): self
74
    {
75 81
        $regex = '/^(?P<negative>[−-])?(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+\.?\d*)[′\'])?$/u';
76
77 81
        return self::fromRegex($angle, $regex);
78
    }
79
80 90
    public static function fromDegreeMinuteHemisphere(string $angle): self
81
    {
82 90
        $regex = '/^(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+\.?\d*)[′\'])?(?P<hemisphere>[NSEW])$/u';
83
84 90
        return self::fromRegex($angle, $regex);
85
    }
86
87
    public static function fromHemisphereDegreeMinute(string $angle): self
88
    {
89
        $regex = '/^(?P<hemisphere>[NSEW])(?P<degrees>\d+)[°º]?((?P<arcminutes>\d+\.?\d*)[′\'])?$/u';
90
91
        return self::fromRegex($angle, $regex);
92
    }
93
94 54
    public static function fromDegreeHemisphere(string $angle): self
95
    {
96 54
        $regex = '/^(?P<degrees>\d+\.?\d*)[°º]?(?P<hemisphere>[NSEW])$/u';
97
98 54
        return self::fromRegex($angle, $regex);
99
    }
100
101
    public static function fromHemisphereDegree(string $angle): self
102
    {
103
        $regex = '/^(?P<hemisphere>[NSEW])(?P<degrees>\d+\.?\d*)[°º]?$/u';
104
105
        return self::fromRegex($angle, $regex);
106
    }
107
108 99
    public static function fromSexagesimalDMSS(string $angle): self
109
    {
110 99
        $regex = '/^(?P<negative>[−-])?(?P<degrees>\d+)(?P<arcminutes>\d{2})(?P<arcseconds>\d{2}\.\d*)$/u';
111
112 99
        return self::fromRegex($angle, $regex);
113
    }
114
115 108
    public static function fromSexagesimalDMS(string $angle): self
116
    {
117 108
        $decimalPosition = strpos($angle, '.');
118 108
        if ($decimalPosition) {
119 108
            $angle = str_pad($angle, $decimalPosition + 5, '0', STR_PAD_RIGHT);
120
        } else {
121 27
            $angle .= '.0000';
122
        }
123 108
        $regex = '/^(?P<negative>[−-])?(?P<degrees>\d+)\.(?P<arcminutes>\d{2})(?P<arcseconds>\d{2})(?P<fractionarcseconds>\d+)?$/u';
124
125 108
        return self::fromRegex($angle, $regex);
126
    }
127
128 27
    public static function fromSexagesimalDM(string $angle): self
129
    {
130 27
        $decimalPosition = strpos($angle, '.');
131 27
        if ($decimalPosition) {
132 27
            $angle = str_pad($angle, $decimalPosition + 5, '0', STR_PAD_RIGHT);
133
        } else {
134
            $angle .= '.0000';
135
        }
136 27
        $regex = '/^(?P<negative>[−-])?(?P<degrees>\d+)\.(?P<arcminutes>\d{2})(?P<fractionarcminutes>\d+)?$/u';
137
138 27
        return self::fromRegex($angle, $regex);
139
    }
140
141
    /**
142
     * @param non-empty-string $regex
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
143
     */
144 639
    private static function fromRegex(string $angle, string $regex): self
145
    {
146
        /** @var non-empty-string $angle */
147 639
        $angle = str_replace(' ', '', $angle);
148 639
        $foundAngle = Preg::match($regex, $angle, $angleParts);
149
150 639
        if (!$foundAngle) {
151 72
            throw new InvalidArgumentException("Could not find angle in '{$angle}'");
152
        }
153
154 567
        $degrees = (float) $angleParts['degrees'];
155 567
        $degrees += ((float) ($angleParts['arcminutes'] ?? 0) / 60);
156 567
        $degrees += isset($angleParts['fractionarcminutes']) ? ((float) $angleParts['fractionarcminutes'] / 60 / 10 ** strlen($angleParts['fractionarcminutes'])) : 0;
157 567
        $degrees += ((float) ($angleParts['arcseconds'] ?? 0) / 3600);
158 567
        $degrees += isset($angleParts['fractionarcseconds']) ? ((float) $angleParts['fractionarcseconds'] / 3600 / 10 ** strlen($angleParts['fractionarcseconds'])) : 0;
159
160 567
        if ($angleParts['negative'] ?? '' || in_array($angleParts['hemisphere'] ?? [], ['S', 'W'], true)) {
161 189
            $degrees *= -1;
162
        }
163
164 567
        return new static($degrees);
165
    }
166
167 798
    public static function convert(Angle $angle, string $targetSRID): Angle
168
    {
169 798
        if ($targetSRID === self::EPSG_DEGREE) {
170 798
            return $angle;
171
        }
172
173
        return parent::convert($angle, $targetSRID);
174
    }
175
}
176