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) { |
|
|
|
|
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
|
|
|
|
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.