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

Rate::makeUnit()   B

Complexity

Conditions 9
Paths 9

Size

Total Lines 24
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 9

Importance

Changes 0
Metric Value
cc 9
eloc 18
nc 9
nop 2
dl 0
loc 24
ccs 17
cts 17
cp 1
crap 9
rs 8.0555
c 0
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 function array_map;
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\Length;
17
use PHPCoord\UnitOfMeasure\Length\Metre;
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 20
    public function __construct(UnitOfMeasure $change, Time $time)
99
    {
100 20
        if ($change instanceof Time) {
101
            throw new InvalidRateException('A rate is a change per unit of time, the change cannot be time');
102
        }
103
104 20
        $this->change = $change;
105 20
        $this->time = $time;
106 20
    }
107
108 1
    public function getChange(): UnitOfMeasure
109
    {
110 1
        return $this->change;
111
    }
112
113 2
    public function getChangePerYear(): UnitOfMeasure
114
    {
115 2
        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

115
        return $this->change->/** @scrutinizer ignore-call */ divide($this->time->asYears()->getValue());
Loading history...
116
    }
117
118 1
    public function getTime(): Time
119
    {
120 1
        return $this->time;
121
    }
122
123 2
    public function getValue(): float
124
    {
125 2
        return $this->change->getValue();
126
    }
127
128 1
    public function getUnitName(): string
129
    {
130 1
        return $this->change->getUnitName() . ' per ' . $this->time->getUnitName();
131
    }
132
133 1
    public function __toString(): string
134
    {
135 1
        return (string) $this->getValue();
136
    }
137
138 15
    public static function makeUnit(float $measurement, string $srid): self
139
    {
140 15
        if (!isset(static::$sridData[$srid])) {
141 1
            throw new UnknownUnitOfMeasureException($srid);
142
        }
143
144
        switch ($srid) {
145 14
            case self::EPSG_ARC_SECONDS_PER_YEAR:
146 2
                return new self(new ArcSecond($measurement), new Year(1));
147 12
            case self::EPSG_MILLIARC_SECONDS_PER_YEAR:
148 2
                return new self(Angle::makeUnit($measurement, Angle::EPSG_MILLIARC_SECOND), new Year(1));
149 10
            case self::EPSG_METRES_PER_YEAR:
150 2
                return new self(new Metre($measurement), new Year(1));
151 8
            case self::EPSG_MILLIMETRES_PER_YEAR:
152 2
                return new self(Length::makeUnit($measurement, Length::EPSG_MILLIMETRE), new Year(1));
153 6
            case self::EPSG_CENTIMETRES_PER_YEAR:
154 2
                return new self(Length::makeUnit($measurement, Length::EPSG_CENTIMETRE), new Year(1));
155 4
            case self::EPSG_PARTS_PER_BILLION_PER_YEAR:
156 2
                return new self(new PartsPerBillion($measurement), new Year(1));
157 2
            case self::EPSG_PARTS_PER_MILLION_PER_YEAR:
158 2
                return new self(new PartsPerMillion($measurement), new Year(1));
159
        }
160
161
        throw new UnknownUnitOfMeasureException($srid); //@codeCoverageIgnore
162
    }
163
164 9
    public static function getSupportedSRIDs(): array
165
    {
166 9
        return array_map(function ($sridData) {return $sridData['name']; }, static::$sridData);
167
    }
168
}
169