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

Rate   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 172
Duplicated Lines 0 %

Test Coverage

Coverage 60.47%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 65
dl 0
loc 172
ccs 26
cts 43
cp 0.6047
rs 10
c 2
b 0
f 0
wmc 20

11 Methods

Rating   Name   Duplication   Size   Complexity  
A getChange() 0 3 1
A getTime() 0 3 1
A getUnitName() 0 3 1
A __toString() 0 3 1
A getValue() 0 3 1
A getChangePerYear() 0 3 1
A getSupportedSRIDsWithHelp() 0 6 1
B makeUnit() 0 24 9
A __construct() 0 7 2
A getSupportedSRIDs() 0 3 1
A multiply() 0 3 1
1
<?php
2
3
/**
4
 * PHPCoord.
5
 *
6
 * @author Doug Wright
7
 */
8
declare(strict_types=1);
9
10
namespace PHPCoord\UnitOfMeasure;
11
12
use PHPCoord\Exception\InvalidRateException;
13
use PHPCoord\Exception\UnknownUnitOfMeasureException;
14
use PHPCoord\UnitOfMeasure\Angle\Angle;
15
use PHPCoord\UnitOfMeasure\Angle\ArcSecond;
16
use PHPCoord\UnitOfMeasure\Length\Centimetre;
17
use PHPCoord\UnitOfMeasure\Length\Metre;
18
use PHPCoord\UnitOfMeasure\Length\Millimetre;
19
use PHPCoord\UnitOfMeasure\Scale\PartsPerBillion;
20
use PHPCoord\UnitOfMeasure\Scale\PartsPerMillion;
21
use PHPCoord\UnitOfMeasure\Time\Time;
22
use PHPCoord\UnitOfMeasure\Time\Year;
23
24
use function array_map;
25
26
class Rate implements UnitOfMeasure
27
{
28
    /**
29
     * Arc-seconds per year
30
     * =((pi/180) / 3600) radians per year. Year taken to be IUGS definition of 31556925.445 seconds; see UoM code
31
     * 1029.
32
     */
33
    public const EPSG_ARC_SECONDS_PER_YEAR = 'urn:ogc:def:uom:EPSG::1043';
34
35
    /**
36
     * Centimetres per year
37
     * Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029.
38
     */
39
    public const EPSG_CENTIMETRES_PER_YEAR = 'urn:ogc:def:uom:EPSG::1034';
40
41
    /**
42
     * Metres per year
43
     * Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029.
44
     */
45
    public const EPSG_METRES_PER_YEAR = 'urn:ogc:def:uom:EPSG::1042';
46
47
    /**
48
     * Milliarc-seconds per year
49
     * = ((pi/180) / 3600 / 1000) radians per year. Year taken to be IUGS definition of 31556925.445 seconds; see UoM
50
     * code 1029.
51
     */
52
    public const EPSG_MILLIARC_SECONDS_PER_YEAR = 'urn:ogc:def:uom:EPSG::1032';
53
54
    /**
55
     * Millimetres per year
56
     * Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029.
57
     */
58
    public const EPSG_MILLIMETRES_PER_YEAR = 'urn:ogc:def:uom:EPSG::1027';
59
60
    /**
61
     * Parts per billion per year
62
     * Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029. Billion is internationally
63
     * ambiguous, in different languages being 1E+9 and 1E+12. One billion taken here to be 1E+9.
64
     */
65
    public const EPSG_PARTS_PER_BILLION_PER_YEAR = 'urn:ogc:def:uom:EPSG::1030';
66
67
    /**
68
     * Parts per million per year
69
     * Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029.
70
     */
71
    public const EPSG_PARTS_PER_MILLION_PER_YEAR = 'urn:ogc:def:uom:EPSG::1041';
72
73
    /**
74
     * @var array<string, array{name: string, help: string}>
75
     */
76
    protected static array $sridData = [
77
        'urn:ogc:def:uom:EPSG::1027' => [
78
            'name' => 'millimetres per year',
79
            'help' => 'Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029.',
80
        ],
81
        'urn:ogc:def:uom:EPSG::1030' => [
82
            'name' => 'parts per billion per year',
83
            'help' => 'Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029. Billion is internationally ambiguous, in different languages being 1E+9 and 1E+12. One billion taken here to be 1E+9.',
84
        ],
85
        'urn:ogc:def:uom:EPSG::1032' => [
86
            'name' => 'milliarc-seconds per year',
87
            'help' => '= ((pi/180) / 3600 / 1000) radians per year. Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029.',
88
        ],
89
        'urn:ogc:def:uom:EPSG::1034' => [
90
            'name' => 'centimetres per year',
91
            'help' => 'Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029.',
92
        ],
93
        'urn:ogc:def:uom:EPSG::1041' => [
94
            'name' => 'parts per million per year',
95
            'help' => 'Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029.',
96
        ],
97
        'urn:ogc:def:uom:EPSG::1042' => [
98
            'name' => 'metres per year',
99
            'help' => 'Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029.',
100
        ],
101
        'urn:ogc:def:uom:EPSG::1043' => [
102
            'name' => 'arc-seconds per year',
103
            'help' => '=((pi/180) / 3600) radians per year. Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029.',
104
        ],
105
    ];
106
107
    private UnitOfMeasure $change;
108
109
    private Time $time;
110
111 54
    public function __construct(UnitOfMeasure $change, Time $time)
112
    {
113 54
        if ($change instanceof Time) {
114
            throw new InvalidRateException('A rate is a change per unit of time, the change cannot be time');
115
        }
116 54
        $this->change = $change;
117 54
        $this->time = $time;
118
    }
119
120 9
    public function getChange(): UnitOfMeasure
121
    {
122 9
        return $this->change;
123
    }
124
125 18
    public function getChangePerYear(): UnitOfMeasure
126
    {
127 18
        return $this->change->divide($this->time->asYears()->getValue());
0 ignored issues
show
Bug introduced by
The method divide() does not exist on PHPCoord\UnitOfMeasure\UnitOfMeasure. It seems like you code against a sub-type of said class. However, the method does not exist in PHPCoord\UnitOfMeasure\Rate. 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

127
        return $this->change->/** @scrutinizer ignore-call */ divide($this->time->asYears()->getValue());
Loading history...
128
    }
129
130 9
    public function getTime(): Time
131
    {
132 9
        return $this->time;
133
    }
134
135 18
    public function getValue(): float
136
    {
137 18
        return $this->change->getValue();
138
    }
139
140 9
    public function getUnitName(): string
141
    {
142 9
        return $this->change->getUnitName() . ' per ' . $this->time->getUnitName();
143
    }
144
145 9
    public function __toString(): string
146
    {
147 9
        return (string) $this->getValue();
148
    }
149
150
    public function multiply(float $multiplicand): self
151
    {
152
        return new self($this->change->multiply($multiplicand), $this->time);
0 ignored issues
show
Bug introduced by
The method multiply() does not exist on PHPCoord\UnitOfMeasure\UnitOfMeasure. Since it exists in all sub-types, consider adding an abstract or default implementation to PHPCoord\UnitOfMeasure\UnitOfMeasure. ( Ignorable by Annotation )

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

152
        return new self($this->change->/** @scrutinizer ignore-call */ multiply($multiplicand), $this->time);
Loading history...
153
    }
154
155 9
    public static function makeUnit(float $measurement, string $srid): self
156
    {
157 9
        if (!isset(self::$sridData[$srid])) {
158 9
            throw new UnknownUnitOfMeasureException($srid);
159
        }
160
161
        switch ($srid) {
162
            case self::EPSG_ARC_SECONDS_PER_YEAR:
163
                return new self(new ArcSecond($measurement), new Year(1));
164
            case self::EPSG_MILLIARC_SECONDS_PER_YEAR:
165
                return new self(Angle::makeUnit($measurement, Angle::EPSG_MILLIARC_SECOND), new Year(1));
166
            case self::EPSG_METRES_PER_YEAR:
167
                return new self(new Metre($measurement), new Year(1));
168
            case self::EPSG_MILLIMETRES_PER_YEAR:
169
                return new self(new Millimetre($measurement), new Year(1));
170
            case self::EPSG_CENTIMETRES_PER_YEAR:
171
                return new self(new Centimetre($measurement), new Year(1));
172
            case self::EPSG_PARTS_PER_BILLION_PER_YEAR:
173
                return new self(new PartsPerBillion($measurement), new Year(1));
174
            case self::EPSG_PARTS_PER_MILLION_PER_YEAR:
175
                return new self(new PartsPerMillion($measurement), new Year(1));
176
        }
177
178
        throw new UnknownUnitOfMeasureException($srid); // @codeCoverageIgnore
179
    }
180
181
    /**
182
     * @return array<string, string>
183
     */
184 18
    public static function getSupportedSRIDs(): array
185
    {
186 18
        return array_map(fn (array $data) => $data['name'], static::$sridData);
187
    }
188
189
    /**
190
     * @return array<string, array{name: string, help: string}>
191
     */
192 9
    public static function getSupportedSRIDsWithHelp(): array
193
    {
194 9
        return array_map(fn (array $data) => [
195 9
            'name' => $data['name'],
196 9
            'help' => $data['help'],
197 9
        ], static::$sridData);
198
    }
199
}
200