Passed
Push — 4.x ( 2e43a7...18aaa8 )
by Doug
06:37
created

Length::makeUnit()   D

Complexity

Conditions 21
Paths 21

Size

Total Lines 46
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 34.0743

Importance

Changes 0
Metric Value
cc 21
eloc 42
nc 21
nop 2
dl 0
loc 46
ccs 29
cts 42
cp 0.6905
crap 34.0743
rs 4.1666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * PHPCoord.
5
 *
6
 * @author Doug Wright
7
 */
8
declare(strict_types=1);
9
10
namespace PHPCoord\UnitOfMeasure\Length;
11
12
use PHPCoord\Exception\UnknownUnitOfMeasureException;
13
use PHPCoord\UnitOfMeasure\UnitOfMeasure;
14
15
use function array_map;
16
17
abstract class Length implements UnitOfMeasure
18
{
19
    /**
20
     * British chain (Benoit 1895 B)
21
     * Uses Benoit's 1895 British yard-metre ratio as given by Bomford as 39.370113 inches per metre.  Used in West
22
     * Malaysian mapping.
23
     */
24
    public const EPSG_BRITISH_CHAIN_BENOIT_1895_B = 'urn:ogc:def:uom:EPSG::9062';
25
26
    /**
27
     * British chain (Sears 1922 truncated)
28
     * Uses Sear's 1922 British yard-metre ratio (UoM code 9040) truncated to 6 significant figures; this truncated
29
     * ratio (0.914398, UoM code 9099) then converted to other imperial units. 1 chSe(T) = 22 ydSe(T). Used in
30
     * metrication of Malaya RSO grid.
31
     */
32
    public const EPSG_BRITISH_CHAIN_SEARS_1922_TRUNCATED = 'urn:ogc:def:uom:EPSG::9301';
33
34
    /**
35
     * British chain (Sears 1922)
36
     * Uses Sear's 1922 British yard-metre ratio as given by Bomford as 39.370147 inches per metre.  Used in East
37
     * Malaysian and older New Zealand mapping.
38
     */
39
    public const EPSG_BRITISH_CHAIN_SEARS_1922 = 'urn:ogc:def:uom:EPSG::9042';
40
41
    /**
42
     * British foot (1936)
43
     * For the 1936 retriangulation OSGB defines the relationship of 10 feet of 1796 to the International metre through
44
     * the logarithmic relationship (10^0.48401603 exactly). 1 ft = 0.3048007491…m. Also used for metric conversions
45
     * in Ireland.
46
     */
47
    public const EPSG_BRITISH_FOOT_1936 = 'urn:ogc:def:uom:EPSG::9095';
48
49
    /**
50
     * British foot (Sears 1922)
51
     * Uses Sear's 1922 British yard-metre ratio as given by Bomford as 39.370147 inches per metre.  Used in East
52
     * Malaysian and older New Zealand mapping.
53
     */
54
    public const EPSG_BRITISH_FOOT_SEARS_1922 = 'urn:ogc:def:uom:EPSG::9041';
55
56
    /**
57
     * British yard (Sears 1922)
58
     * Uses Sear's 1922 British yard-metre ratio as given by Bomford as 39.370147 inches per metre.  Used in East
59
     * Malaysian and older New Zealand mapping.
60
     */
61
    public const EPSG_BRITISH_YARD_SEARS_1922 = 'urn:ogc:def:uom:EPSG::9040';
62
63
    /**
64
     * Clarke's foot
65
     * Assumes Clarke's 1865 ratio of 1 British foot = 0.3047972654 French legal metres applies to the international
66
     * metre.   Used in older Australian, southern African & British West Indian mapping.
67
     */
68
    public const EPSG_CLARKES_FOOT = 'urn:ogc:def:uom:EPSG::9005';
69
70
    /**
71
     * Clarke's link
72
     * =1/100 Clarke's chain. Assumes Clarke's 1865 ratio of 1 British foot = 0.3047972654 French legal metres applies
73
     * to the international metre.   Used in older Australian, southern African & British West Indian mapping.
74
     */
75
    public const EPSG_CLARKES_LINK = 'urn:ogc:def:uom:EPSG::9039';
76
77
    /**
78
     * Clarke's yard
79
     * =3 Clarke's feet.  Assumes Clarke's 1865 ratio of 1 British foot = 0.3047972654 French legal metres applies to
80
     * the international metre.   Used in older Australian, southern African & British West Indian mapping.
81
     */
82
    public const EPSG_CLARKES_YARD = 'urn:ogc:def:uom:EPSG::9037';
83
84
    /**
85
     * German legal metre
86
     * Used in Namibia.
87
     */
88
    public const EPSG_GERMAN_LEGAL_METRE = 'urn:ogc:def:uom:EPSG::9031';
89
90
    /**
91
     * Gold Coast foot
92
     * Used in Ghana and some adjacent parts of British west Africa prior to metrication, except for the metrication of
93
     * projection defining parameters when British foot (Sears 1922) used.
94
     */
95
    public const EPSG_GOLD_COAST_FOOT = 'urn:ogc:def:uom:EPSG::9094';
96
97
    /**
98
     * Indian foot
99
     * Indian Foot = 0.99999566 British feet (A.R.Clarke 1865).  British yard (= 3 British feet) taken to be
100
     * J.S.Clark's 1865 value of 0.9144025 metres.
101
     */
102
    public const EPSG_INDIAN_FOOT = 'urn:ogc:def:uom:EPSG::9080';
103
104
    /**
105
     * Indian yard
106
     * Indian Foot = 0.99999566 British feet (A.R.Clarke 1865).  British yard (= 3 British feet) taken to be
107
     * J.S.Clark's 1865 value of 0.9144025 metres.
108
     */
109
    public const EPSG_INDIAN_YARD = 'urn:ogc:def:uom:EPSG::9084';
110
111
    /**
112
     * US survey foot
113
     * Used in USA.
114
     */
115
    public const EPSG_US_SURVEY_FOOT = 'urn:ogc:def:uom:EPSG::9003';
116
117
    /**
118
     * Centimetre.
119
     */
120
    public const EPSG_CENTIMETRE = 'urn:ogc:def:uom:EPSG::1033';
121
122
    /**
123
     * Foot.
124
     */
125
    public const EPSG_FOOT = 'urn:ogc:def:uom:EPSG::9002';
126
127
    /**
128
     * Kilometre.
129
     */
130
    public const EPSG_KILOMETRE = 'urn:ogc:def:uom:EPSG::9036';
131
132
    /**
133
     * Link
134
     * =1/100 international chain.
135
     */
136
    public const EPSG_LINK = 'urn:ogc:def:uom:EPSG::9098';
137
138
    /**
139
     * Metre
140
     * SI base unit for length.
141
     */
142
    public const EPSG_METRE = 'urn:ogc:def:uom:EPSG::9001';
143
144
    /**
145
     * Millimetre.
146
     */
147
    public const EPSG_MILLIMETRE = 'urn:ogc:def:uom:EPSG::1025';
148
149
    /**
150
     * @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...
151
     */
152
    protected static array $sridData = [
153
        'urn:ogc:def:uom:EPSG::1025' => [
154
            'name' => 'millimetre',
155
            'help' => '',
156
        ],
157
        'urn:ogc:def:uom:EPSG::1033' => [
158
            'name' => 'centimetre',
159
            'help' => '',
160
        ],
161
        'urn:ogc:def:uom:EPSG::9001' => [
162
            'name' => 'metre',
163
            'help' => 'SI base unit for length.',
164
        ],
165
        'urn:ogc:def:uom:EPSG::9002' => [
166
            'name' => 'foot',
167
            'help' => '',
168
        ],
169
        'urn:ogc:def:uom:EPSG::9003' => [
170
            'name' => 'US survey foot',
171
            'help' => 'Used in USA.',
172
        ],
173
        'urn:ogc:def:uom:EPSG::9005' => [
174
            'name' => 'Clarke\'s foot',
175
            'help' => 'Assumes Clarke\'s 1865 ratio of 1 British foot = 0.3047972654 French legal metres applies to the international metre.   Used in older Australian, southern African & British West Indian mapping.',
176
        ],
177
        'urn:ogc:def:uom:EPSG::9031' => [
178
            'name' => 'German legal metre',
179
            'help' => 'Used in Namibia.',
180
        ],
181
        'urn:ogc:def:uom:EPSG::9036' => [
182
            'name' => 'kilometre',
183
            'help' => '',
184
        ],
185
        'urn:ogc:def:uom:EPSG::9037' => [
186
            'name' => 'Clarke\'s yard',
187
            'help' => '=3 Clarke\'s feet.  Assumes Clarke\'s 1865 ratio of 1 British foot = 0.3047972654 French legal metres applies to the international metre.   Used in older Australian, southern African & British West Indian mapping.',
188
        ],
189
        'urn:ogc:def:uom:EPSG::9039' => [
190
            'name' => 'Clarke\'s link',
191
            'help' => '=1/100 Clarke\'s chain. Assumes Clarke\'s 1865 ratio of 1 British foot = 0.3047972654 French legal metres applies to the international metre.   Used in older Australian, southern African & British West Indian mapping.',
192
        ],
193
        'urn:ogc:def:uom:EPSG::9040' => [
194
            'name' => 'British yard (Sears 1922)',
195
            'help' => 'Uses Sear\'s 1922 British yard-metre ratio as given by Bomford as 39.370147 inches per metre.  Used in East Malaysian and older New Zealand mapping.',
196
        ],
197
        'urn:ogc:def:uom:EPSG::9041' => [
198
            'name' => 'British foot (Sears 1922)',
199
            'help' => 'Uses Sear\'s 1922 British yard-metre ratio as given by Bomford as 39.370147 inches per metre.  Used in East Malaysian and older New Zealand mapping.',
200
        ],
201
        'urn:ogc:def:uom:EPSG::9042' => [
202
            'name' => 'British chain (Sears 1922)',
203
            'help' => 'Uses Sear\'s 1922 British yard-metre ratio as given by Bomford as 39.370147 inches per metre.  Used in East Malaysian and older New Zealand mapping.',
204
        ],
205
        'urn:ogc:def:uom:EPSG::9062' => [
206
            'name' => 'British chain (Benoit 1895 B)',
207
            'help' => 'Uses Benoit\'s 1895 British yard-metre ratio as given by Bomford as 39.370113 inches per metre.  Used in West Malaysian mapping.',
208
        ],
209
        'urn:ogc:def:uom:EPSG::9080' => [
210
            'name' => 'Indian foot',
211
            'help' => 'Indian Foot = 0.99999566 British feet (A.R.Clarke 1865).  British yard (= 3 British feet) taken to be J.S.Clark\'s 1865 value of 0.9144025 metres.',
212
        ],
213
        'urn:ogc:def:uom:EPSG::9084' => [
214
            'name' => 'Indian yard',
215
            'help' => 'Indian Foot = 0.99999566 British feet (A.R.Clarke 1865).  British yard (= 3 British feet) taken to be J.S.Clark\'s 1865 value of 0.9144025 metres.',
216
        ],
217
        'urn:ogc:def:uom:EPSG::9094' => [
218
            'name' => 'Gold Coast foot',
219
            'help' => 'Used in Ghana and some adjacent parts of British west Africa prior to metrication, except for the metrication of projection defining parameters when British foot (Sears 1922) used.',
220
        ],
221
        'urn:ogc:def:uom:EPSG::9095' => [
222
            'name' => 'British foot (1936)',
223
            'help' => 'For the 1936 retriangulation OSGB defines the relationship of 10 feet of 1796 to the International metre through the logarithmic relationship (10^0.48401603 exactly). 1 ft = 0.3048007491…m. Also used for metric conversions in Ireland.',
224
        ],
225
        'urn:ogc:def:uom:EPSG::9098' => [
226
            'name' => 'link',
227
            'help' => '=1/100 international chain.',
228
        ],
229
        'urn:ogc:def:uom:EPSG::9301' => [
230
            'name' => 'British chain (Sears 1922 truncated)',
231
            'help' => 'Uses Sear\'s 1922 British yard-metre ratio (UoM code 9040) truncated to 6 significant figures; this truncated ratio (0.914398, UoM code 9099) then converted to other imperial units. 1 chSe(T) = 22 ydSe(T). Used in metrication of Malaya RSO grid.',
232
        ],
233
    ];
234
235
    abstract public function __construct(float $length);
236
237
    abstract public function asMetres(): Metre;
238
239 319
    public function add(self $unit): self
240
    {
241 319
        if ($this::class === $unit::class) {
242 319
            return new static($this->getValue() + $unit->getValue());
243
        }
244
        $resultAsMetres = new Metre($this->asMetres()->getValue() + $unit->asMetres()->getValue());
245
        $conversionRatio = (new static(1))->asMetres()->getValue();
246
247
        return new static($resultAsMetres->getValue() / $conversionRatio);
248
    }
249
250 212
    public function subtract(self $unit): self
251
    {
252 212
        if ($this::class === $unit::class) {
253 212
            return new static($this->getValue() - $unit->getValue());
254
        }
255
        $resultAsMetres = new Metre($this->asMetres()->getValue() - $unit->asMetres()->getValue());
256
        $conversionRatio = (new static(1))->asMetres()->getValue();
257
258
        return new static($resultAsMetres->getValue() / $conversionRatio);
259
    }
260
261 1544
    public function multiply(float $multiplicand): self
262
    {
263 1544
        return new static($this->getValue() * $multiplicand);
264
    }
265
266 225
    public function divide(float $divisor): self
267
    {
268 225
        return new static($this->getValue() / $divisor);
269
    }
270
271 560
    public static function makeUnit(float $measurement, string $srid): self
272
    {
273
        switch ($srid) {
274 560
            case self::EPSG_METRE:
275 398
                return new Metre($measurement);
276 180
            case self::EPSG_KILOMETRE:
277
                return new Kilometre($measurement);
278 180
            case self::EPSG_CENTIMETRE:
279
                return new Centimetre($measurement);
280 180
            case self::EPSG_MILLIMETRE:
281
                return new Millimetre($measurement);
282 180
            case self::EPSG_FOOT:
283 9
                return new Foot($measurement);
284 180
            case self::EPSG_LINK:
285 27
                return new Link($measurement);
286 153
            case self::EPSG_BRITISH_CHAIN_BENOIT_1895_B:
287
                return new BritishChain1895BenoitB($measurement);
288 153
            case self::EPSG_BRITISH_FOOT_SEARS_1922:
289
                return new BritishFoot1922Sears($measurement);
290 153
            case self::EPSG_BRITISH_YARD_SEARS_1922:
291
                return new BritishYard1922Sears($measurement);
292 153
            case self::EPSG_BRITISH_CHAIN_SEARS_1922:
293
                return new BritishChain1922Sears($measurement);
294 153
            case self::EPSG_BRITISH_CHAIN_SEARS_1922_TRUNCATED:
295
                return new BritishChain1922SearsTruncated($measurement);
296 153
            case self::EPSG_BRITISH_FOOT_1936:
297 9
                return new BritishFoot1936($measurement);
298 144
            case self::EPSG_US_SURVEY_FOOT:
299 99
                return new USSurveyFoot($measurement);
300 45
            case self::EPSG_CLARKES_FOOT:
301 27
                return new ClarkeFoot($measurement);
302 27
            case self::EPSG_CLARKES_YARD:
303
                return new ClarkeYard($measurement);
304 27
            case self::EPSG_CLARKES_LINK:
305 18
                return new ClarkeLink($measurement);
306 9
            case self::EPSG_INDIAN_FOOT:
307
                return new IndianFoot($measurement);
308 9
            case self::EPSG_INDIAN_YARD:
309
                return new IndianYard($measurement);
310 9
            case self::EPSG_GOLD_COAST_FOOT:
311
                return new GoldCoastFoot($measurement);
312 9
            case self::EPSG_GERMAN_LEGAL_METRE:
313
                return new GermanLegalMetre($measurement);
314
        }
315
316 9
        throw new UnknownUnitOfMeasureException($srid);
317
    }
318
319 225
    public static function convert(self $length, string $targetSRID): self
320
    {
321 225
        $conversionRatio = static::makeUnit(1, $targetSRID)->asMetres()->getValue();
322
323 225
        return self::makeUnit($length->asMetres()->getValue() / $conversionRatio, $targetSRID);
324
    }
325
326
    /**
327
     * @return array<string, string>
328
     */
329 27
    public static function getSupportedSRIDs(): array
330
    {
331 27
        return array_map(fn ($supportedSrid) => $supportedSrid['name'], self::$sridData);
332
    }
333
334
    /**
335
     * @return array<string, array{name: string, help: string}>
336
     */
337 9
    public static function getSupportedSRIDsWithHelp(): array
338
    {
339 9
        return array_map(fn (array $data) => [
340 9
            'name' => $data['name'],
341 9
            'help' => $data['help'],
342 9
        ], static::$sridData);
343
    }
344
345 225
    public function __toString(): string
346
    {
347 225
        return (string) $this->getValue();
348
    }
349
}
350