Passed
Push — master ( f00c65...31a7ea )
by Doug
61:30
created

Rate::makeUnit()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 11
nc 2
nop 2
dl 0
loc 15
ccs 11
cts 11
cp 1
crap 2
rs 9.9
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\UnitOfMeasure;
10
11
use PHPCoord\Exception\InvalidRateException;
12
use PHPCoord\Exception\UnknownUnitOfMeasureException;
13
use PHPCoord\UnitOfMeasure\Angle\Angle;
14
use PHPCoord\UnitOfMeasure\Angle\ArcSecond;
15
use PHPCoord\UnitOfMeasure\Length\Centimetre;
16
use PHPCoord\UnitOfMeasure\Length\Metre;
17
use PHPCoord\UnitOfMeasure\Length\Millimetre;
18
use PHPCoord\UnitOfMeasure\Scale\PartsPerBillion;
19
use PHPCoord\UnitOfMeasure\Scale\PartsPerMillion;
20
use PHPCoord\UnitOfMeasure\Time\Time;
21
use PHPCoord\UnitOfMeasure\Time\Year;
22
23
class Rate implements UnitOfMeasure
24
{
25
    /**
26
     * arc-seconds per year
27
     * =((pi/180) / 3600) radians per year. Year taken to be IUGS definition of 31556925.445 seconds; see UoM code
28
     * 1029.
29
     */
30
    public const EPSG_ARC_SECONDS_PER_YEAR = 'urn:ogc:def:uom:EPSG::1043';
31
32
    /**
33
     * centimetres per year
34
     * Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029.
35
     */
36
    public const EPSG_CENTIMETRES_PER_YEAR = 'urn:ogc:def:uom:EPSG::1034';
37
38
    /**
39
     * metres per year
40
     * Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029.
41
     */
42
    public const EPSG_METRES_PER_YEAR = 'urn:ogc:def:uom:EPSG::1042';
43
44
    /**
45
     * milliarc-seconds per year
46
     * = ((pi/180) / 3600 / 1000) radians per year. Year taken to be IUGS definition of 31556925.445 seconds; see UoM
47
     * code 1029.
48
     */
49
    public const EPSG_MILLIARC_SECONDS_PER_YEAR = 'urn:ogc:def:uom:EPSG::1032';
50
51
    /**
52
     * millimetres per year
53
     * Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029.
54
     */
55
    public const EPSG_MILLIMETRES_PER_YEAR = 'urn:ogc:def:uom:EPSG::1027';
56
57
    /**
58
     * parts per billion per year
59
     * Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029. Billion is internationally
60
     * ambiguous, in different languages being 1E+9 and 1E+12. One billion taken here to be 1E+9.
61
     */
62
    public const EPSG_PARTS_PER_BILLION_PER_YEAR = 'urn:ogc:def:uom:EPSG::1030';
63
64
    /**
65
     * parts per million per year
66
     * Year taken to be IUGS definition of 31556925.445 seconds; see UoM code 1029.
67
     */
68
    public const EPSG_PARTS_PER_MILLION_PER_YEAR = 'urn:ogc:def:uom:EPSG::1041';
69
70
    protected static array $sridData = [
71
        'urn:ogc:def:uom:EPSG::1027' => [
72
            'name' => 'millimetres per year',
73
        ],
74
        'urn:ogc:def:uom:EPSG::1030' => [
75
            'name' => 'parts per billion per year',
76
        ],
77
        'urn:ogc:def:uom:EPSG::1032' => [
78
            'name' => 'milliarc-seconds per year',
79
        ],
80
        'urn:ogc:def:uom:EPSG::1034' => [
81
            'name' => 'centimetres per year',
82
        ],
83
        'urn:ogc:def:uom:EPSG::1041' => [
84
            'name' => 'parts per million per year',
85
        ],
86
        'urn:ogc:def:uom:EPSG::1042' => [
87
            'name' => 'metres per year',
88
        ],
89
        'urn:ogc:def:uom:EPSG::1043' => [
90
            'name' => 'arc-seconds per year',
91
        ],
92
    ];
93
94
    private UnitOfMeasure $change;
95
96
    private Time $time;
97
98
    private static array $supportedCache = [];
99
100 180
    public function __construct(UnitOfMeasure $change, Time $time)
101
    {
102 180
        if ($change instanceof Time) {
103
            throw new InvalidRateException('A rate is a change per unit of time, the change cannot be time');
104
        }
105
106 180
        $this->change = $change;
107 180
        $this->time = $time;
108 180
    }
109
110 9
    public function getChange(): UnitOfMeasure
111
    {
112 9
        return $this->change;
113
    }
114
115 18
    public function getChangePerYear(): UnitOfMeasure
116
    {
117 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

117
        return $this->change->/** @scrutinizer ignore-call */ divide($this->time->asYears()->getValue());
Loading history...
118
    }
119
120 9
    public function getTime(): Time
121
    {
122 9
        return $this->time;
123
    }
124
125 18
    public function getValue(): float
126
    {
127 18
        return $this->change->getValue();
128
    }
129
130 9
    public function getUnitName(): string
131
    {
132 9
        return $this->change->getUnitName() . ' per ' . $this->time->getUnitName();
133
    }
134
135 9
    public function __toString(): string
136
    {
137 9
        return (string) $this->getValue();
138
    }
139
140 135
    public static function makeUnit(float $measurement, string $srid): self
141
    {
142 135
        if (!isset(static::$sridData[$srid])) {
143 9
            throw new UnknownUnitOfMeasureException($srid);
144
        }
145
146
        return match ($srid) {
147 126
            self::EPSG_ARC_SECONDS_PER_YEAR => new self(new ArcSecond($measurement), new Year(1)),
148 18
            self::EPSG_MILLIARC_SECONDS_PER_YEAR => new self(Angle::makeUnit($measurement, Angle::EPSG_MILLIARC_SECOND), new Year(1)),
149 108
            self::EPSG_METRES_PER_YEAR => new self(new Metre($measurement), new Year(1)),
150 18
            self::EPSG_MILLIMETRES_PER_YEAR => new self(new Millimetre($measurement), new Year(1)),
151 90
            self::EPSG_CENTIMETRES_PER_YEAR => new self(new Centimetre($measurement), new Year(1)),
152 18
            self::EPSG_PARTS_PER_BILLION_PER_YEAR => new self(new PartsPerBillion($measurement), new Year(1)),
153 72
            self::EPSG_PARTS_PER_MILLION_PER_YEAR => new self(new PartsPerMillion($measurement), new Year(1)),
154 18
            default => throw new UnknownUnitOfMeasureException($srid),
155 54
        };
156 18
    }
157 36
158 18
    public static function getSupportedSRIDs(): array
159 18
    {
160 18
        if (!self::$supportedCache) {
0 ignored issues
show
Bug Best Practice introduced by
The expression self::supportedCache of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
161
            foreach (static::$sridData as $srid => $data) {
162
                self::$supportedCache[$srid] = $data['name'];
163
            }
164
        }
165
166 18
        return self::$supportedCache;
167
    }
168
}
169