Passed
Push — master ( 0baa7a...f13449 )
by Doug
50:51
created

Scale::makeUnit()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2.0054

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 2
dl 0
loc 12
ccs 8
cts 9
cp 0.8889
crap 2.0054
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * PHPCoord.
5
 *
6
 * @author Doug Wright
7
 */
8
declare(strict_types=1);
9
10
namespace PHPCoord\UnitOfMeasure\Scale;
11
12
use PHPCoord\Exception\UnknownUnitOfMeasureException;
13
use PHPCoord\UnitOfMeasure\UnitOfMeasure;
14
15
use function array_map;
16
17
abstract class Scale implements UnitOfMeasure
18
{
19
    /**
20
     * Coefficient
21
     * Used when parameters are coefficients.  They inherently take the units which depend upon the term to which the
22
     * coefficient applies.
23
     */
24
    public const EPSG_COEFFICIENT = 'urn:ogc:def:uom:EPSG::9203';
25
26
    /**
27
     * Parts per billion
28
     * Billion is internationally ambiguous, in different languages being 1E+9 and 1E+12. One billion taken here to be
29
     * 1E+9.
30
     */
31
    public const EPSG_PARTS_PER_BILLION = 'urn:ogc:def:uom:EPSG::1028';
32
33
    /**
34
     * Parts per million.
35
     */
36
    public const EPSG_PARTS_PER_MILLION = 'urn:ogc:def:uom:EPSG::9202';
37
38
    /**
39
     * Unity
40
     * EPSG standard unit for scale. SI coherent derived unit (standard unit) for dimensionless quantity, expressed by
41
     * the number one but this is not explicitly shown.
42
     */
43
    public const EPSG_UNITY = 'urn:ogc:def:uom:EPSG::9201';
44
45
    /**
46
     * @var array<string, array{name: string, fqcn?: class-string<self>, help: string}>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string, array{name...g<self>, help: string}> at position 12 could not be parsed: Unknown type name 'class-string' at position 12 in array<string, array{name: string, fqcn?: class-string<self>, help: string}>.
Loading history...
47
     */
48
    protected static array $sridData = [
49
        'urn:ogc:def:uom:EPSG::1028' => [
50
            'name' => 'parts per billion',
51
            'help' => 'Billion is internationally ambiguous, in different languages being 1E+9 and 1E+12. One billion taken here to be 1E+9.',
52
        ],
53
        'urn:ogc:def:uom:EPSG::9201' => [
54
            'name' => 'unity',
55
            'help' => 'EPSG standard unit for scale. SI coherent derived unit (standard unit) for dimensionless quantity, expressed by the number one but this is not explicitly shown.',
56
        ],
57
        'urn:ogc:def:uom:EPSG::9202' => [
58
            'name' => 'parts per million',
59
            'help' => '',
60
        ],
61
        'urn:ogc:def:uom:EPSG::9203' => [
62
            'name' => 'coefficient',
63
            'help' => 'Used when parameters are coefficients.  They inherently take the units which depend upon the term to which the coefficient applies.',
64
        ],
65
    ];
66
67
    abstract public function __construct(float $scale);
68
69
    abstract public function asUnity(): Unity;
70
71 174
    public function add(self $unit): self
72
    {
73 174
        if ($this::class === $unit::class) {
74 174
            return new static($this->getValue() + $unit->getValue());
75
        }
76
        $resultAsUnity = new Unity($this->asUnity()->getValue() + $unit->asUnity()->getValue());
77
        $conversionRatio = (new static(1))->asUnity()->getValue();
78
79
        return new static($resultAsUnity->getValue() / $conversionRatio);
80
    }
81
82 9
    public function subtract(self $unit): self
83
    {
84 9
        if ($this::class === $unit::class) {
85 9
            return new static($this->getValue() - $unit->getValue());
86
        }
87
        $resultAsUnity = new Unity($this->asUnity()->getValue() - $unit->asUnity()->getValue());
88
        $conversionRatio = (new static(1))->asUnity()->getValue();
89
90
        return new static($resultAsUnity->getValue() / $conversionRatio);
91
    }
92
93 183
    public function multiply(float $multiplicand): self
94
    {
95 183
        return new static($this->getValue() * $multiplicand);
96
    }
97
98 165
    public function divide(float $divisor): self
99
    {
100 165
        return new static($this->getValue() / $divisor);
101
    }
102
103 363
    public static function makeUnit(float $measurement, string $srid): self
104
    {
105 363
        if (isset(self::$sridData[$srid]['fqcn'])) {
106
            return new self::$sridData[$srid]['fqcn']($measurement);
107
        }
108
109 363
        return match ($srid) {
110 63
            self::EPSG_COEFFICIENT => new Coefficient($measurement),
111 138
            self::EPSG_PARTS_PER_BILLION => new PartsPerBillion($measurement),
112 171
            self::EPSG_PARTS_PER_MILLION => new PartsPerMillion($measurement),
113 252
            self::EPSG_UNITY => new Unity($measurement),
114 363
            default => throw new UnknownUnitOfMeasureException($srid),
115 363
        };
116
    }
117
118
    /**
119
     * @return array<string, string>
120
     */
121 18
    public static function getSupportedSRIDs(): array
122
    {
123 18
        return array_map(fn ($supportedSrid) => $supportedSrid['name'], self::$sridData);
124
    }
125
126
    /**
127
     * @return array<string, array{name: string, help: string}>
128
     */
129 9
    public static function getSupportedSRIDsWithHelp(): array
130
    {
131 9
        return array_map(fn (array $data) => [
132 9
            'name' => $data['name'],
133 9
            'help' => $data['help'],
134 9
        ], static::$sridData);
135
    }
136
137
    /**
138
     * @param class-string<self> $implementingClassFQCN
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<self> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<self>.
Loading history...
139
     */
140
    public static function registerCustomUnit(string $srid, string $name, string $implementingClassFQCN, string $help = ''): void
141
    {
142
        self::$sridData[$srid] = [
143
            'name' => $name,
144
            'fqcn' => $implementingClassFQCN,
145
            'help' => $help,
146
        ];
147
    }
148
149 9
    public function __toString(): string
150
    {
151 9
        return (string) $this->getValue();
152
    }
153
}
154