Passed
Push — master ( 344e29...cbaf3e )
by Doug
38:02
created

Scale   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 119
Duplicated Lines 0 %

Test Coverage

Coverage 78.38%

Importance

Changes 0
Metric Value
eloc 44
dl 0
loc 119
ccs 29
cts 37
cp 0.7838
rs 10
c 0
b 0
f 0
wmc 13

8 Methods

Rating   Name   Duplication   Size   Complexity  
A multiply() 0 3 1
A add() 0 9 2
A __toString() 0 3 1
A divide() 0 3 1
A registerCustomUnit() 0 5 1
A getSupportedSRIDs() 0 9 3
A subtract() 0 9 2
A makeUnit() 0 12 2
1
<?php
2
/**
3
 * PHPCoord.
4
 *
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
9
namespace PHPCoord\UnitOfMeasure\Scale;
10
11
use PHPCoord\Exception\UnknownUnitOfMeasureException;
12
use PHPCoord\UnitOfMeasure\UnitOfMeasure;
13
14
abstract class Scale implements UnitOfMeasure
15
{
16
    /**
17
     * Coefficient
18
     * Used when parameters are coefficients.  They inherently take the units which depend upon the term to which the
19
     * coefficient applies.
20
     */
21
    public const EPSG_COEFFICIENT = 'urn:ogc:def:uom:EPSG::9203';
22
23
    /**
24
     * Parts per billion
25
     * Billion is internationally ambiguous, in different languages being 1E+9 and 1E+12. One billion taken here to be
26
     * 1E+9.
27
     */
28
    public const EPSG_PARTS_PER_BILLION = 'urn:ogc:def:uom:EPSG::1028';
29
30
    /**
31
     * Parts per million.
32
     */
33
    public const EPSG_PARTS_PER_MILLION = 'urn:ogc:def:uom:EPSG::9202';
34
35
    /**
36
     * Unity
37
     * EPSG standard unit for scale. SI coherent derived unit (standard unit) for dimensionless quantity, expressed by
38
     * the number one but this is not explicitly shown.
39
     */
40
    public const EPSG_UNITY = 'urn:ogc:def:uom:EPSG::9201';
41
42
    protected static array $sridData = [
43
        'urn:ogc:def:uom:EPSG::1028' => [
44
            'name' => 'parts per billion',
45
        ],
46
        'urn:ogc:def:uom:EPSG::9201' => [
47
            'name' => 'unity',
48
        ],
49
        'urn:ogc:def:uom:EPSG::9202' => [
50
            'name' => 'parts per million',
51
        ],
52
        'urn:ogc:def:uom:EPSG::9203' => [
53
            'name' => 'coefficient',
54
        ],
55
    ];
56
57
    protected static array $customSridData = [];
58
59
    private static array $supportedCache = [];
60
61
    abstract public function __construct(float $scale);
62
63
    abstract public function asUnity(): Unity;
64
65 54
    public function add(self $unit): self
66
    {
67 54
        if ($this::class === $unit::class) {
68 54
            return new static($this->getValue() + $unit->getValue());
69
        }
70
        $resultAsUnity = new Unity($this->asUnity()->getValue() + $unit->asUnity()->getValue());
71
        $conversionRatio = (new static(1))->asUnity()->getValue();
72
73
        return new static($resultAsUnity->getValue() / $conversionRatio);
74
    }
75
76 9
    public function subtract(self $unit): self
77
    {
78 9
        if ($this::class === $unit::class) {
79 9
            return new static($this->getValue() - $unit->getValue());
80
        }
81
        $resultAsUnity = new Unity($this->asUnity()->getValue() - $unit->asUnity()->getValue());
82
        $conversionRatio = (new static(1))->asUnity()->getValue();
83
84
        return new static($resultAsUnity->getValue() / $conversionRatio);
85
    }
86
87 348
    public function multiply(float $multiplicand): self
88
    {
89 348
        return new static($this->getValue() * $multiplicand);
90
    }
91
92 45
    public function divide(float $divisor): self
93
    {
94 45
        return new static($this->getValue() / $divisor);
95
    }
96
97 539
    public static function makeUnit(float $measurement, string $srid): self
98
    {
99 539
        if (isset(self::$customSridData[$srid])) {
100 18
            return new self::$customSridData[$srid]['fqcn']($measurement);
101
        }
102
103 539
        return match ($srid) {
104 539
            self::EPSG_COEFFICIENT => new Coefficient($measurement),
105 539
            self::EPSG_PARTS_PER_BILLION => new PartsPerBillion($measurement),
106 539
            self::EPSG_PARTS_PER_MILLION => new PartsPerMillion($measurement),
107 539
            self::EPSG_UNITY => new Unity($measurement),
108 539
            default => throw new UnknownUnitOfMeasureException($srid),
109 539
        };
110
    }
111
112 36
    public static function getSupportedSRIDs(): array
113
    {
114 36
        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...
115
            foreach (static::$sridData as $srid => $data) {
116
                self::$supportedCache[$srid] = $data['name'];
117
            }
118
        }
119
120 36
        return self::$supportedCache;
121
    }
122
123 18
    public static function registerCustomUnit(string $srid, string $name, string $implementingClassFQCN): void
124
    {
125 18
        self::$customSridData[$srid] = ['name' => $name, 'fqcn' => $implementingClassFQCN];
126 18
        self::getSupportedSRIDs(); // init cache if not already
127 18
        self::$supportedCache[$srid] = $name; // update cache
128
    }
129
130 9
    public function __toString(): string
131
    {
132 9
        return (string) $this->getValue();
133
    }
134
}
135