Passed
Push — extents ( 6d8774...01b6e3 )
by Doug
61:12
created

Ellipsoid::getFlattening()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 1
cts 1
cp 1
crap 1
rs 10
c 1
b 0
f 0
1
<?php
2
/**
3
 * PHPCoord.
4
 *
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
9
namespace PHPCoord\Datum;
10
11
use PHPCoord\Exception\UnknownEllipsoidException;
12
use PHPCoord\UnitOfMeasure\Length\Length;
13
use function sqrt;
14
15
class Ellipsoid
16
{
17
    /**
18
     * Airy 1830
19
     * Original definition is a=20923713, b=20853810 feet of 1796. 1/f is given to 7 decimal places. For the 1936
20
     * retriangulation OSGB defines the relationship of 10 feet of 1796 to the International metre through
21
     * ([10^0.48401603]/10) exactly = 0.3048007491...
22
     */
23
    public const EPSG_AIRY_1830 = 'urn:ogc:def:ellipsoid:EPSG::7001';
24
25
    /**
26
     * Airy Modified 1849
27
     * OSGB Airy 1830 figure (ellipsoid code 7001) rescaled by 0.999965 to best fit the scale of the 19th century
28
     * primary triangulation of Ireland.
29
     */
30
    public const EPSG_AIRY_MODIFIED_1849 = 'urn:ogc:def:ellipsoid:EPSG::7002';
31
32
    /**
33
     * Australian National Spheroid
34
     * Based on the GRS 1967 figure but with 1/f taken to 2 decimal places exactly.  The dimensions are also used as
35
     * the GRS 1967 Modified ellipsoid (see code 7050).
36
     */
37
    public const EPSG_AUSTRALIAN_NATIONAL_SPHEROID = 'urn:ogc:def:ellipsoid:EPSG::7003';
38
39
    /**
40
     * Average Terrestrial System 1977.
41
     */
42
    public const EPSG_AVERAGE_TERRESTRIAL_SYSTEM_1977 = 'urn:ogc:def:ellipsoid:EPSG::7041';
43
44
    /**
45
     * Bessel 1841
46
     * Original Bessel definition is a=3272077.14 and b=3261139.33 toise. This used a weighted mean of values from
47
     * several authors but did not account for differences in the length of the various toise: the "Bessel toise" is
48
     * therefore of uncertain length.
49
     */
50
    public const EPSG_BESSEL_1841 = 'urn:ogc:def:ellipsoid:EPSG::7004';
51
52
    /**
53
     * Bessel Modified
54
     * Used in Norway and also in Sweden with a 1mm increase in semi-major axis.
55
     */
56
    public const EPSG_BESSEL_MODIFIED = 'urn:ogc:def:ellipsoid:EPSG::7005';
57
58
    /**
59
     * Bessel Namibia (GLM)
60
     * The semi-major axis has the same value as the Bessel 1841 ellipsoid (code 7004) but is in different units -
61
     * German Legal Metres rather than International metres - hence a different size.  a = 6377483.865 International
62
     * metres. Used in Namibia.
63
     */
64
    public const EPSG_BESSEL_NAMIBIA_GLM = 'urn:ogc:def:ellipsoid:EPSG::7046';
65
66
    /**
67
     * CGCS2000
68
     * Defining parameters semi-major axis, flattening and angular velocity are same as for GRS 1980 (ellipsoid code
69
     * 7019); GM = 3986004.4e8 m*m*m/s/s (from NASA 1986 Lageos determination).
70
     */
71
    public const EPSG_CGCS2000 = 'urn:ogc:def:ellipsoid:EPSG::1024';
72
73
    /**
74
     * Clarke 1858
75
     * Clarke's 1858/II solution. Derived parameters: a = 6378293.645m using his 1865 ratio of 0.3047972654 feet per
76
     * metre; 1/f = 294.26068…  In Australia and Amoco Trinidad 1/f taken to two decimal places (294.26 exactly);
77
     * elsewhere a and b used to derive 1/f.
78
     */
79
    public const EPSG_CLARKE_1858 = 'urn:ogc:def:ellipsoid:EPSG::7007';
80
81
    /**
82
     * Clarke 1866
83
     * Original definition a=20926062 and b=20855121 (British) feet. Uses Clarke's 1865 inch-metre ratio of 39.370432
84
     * to obtain metres. (Metric value then converted to US survey feet for use in the US and international feet for
85
     * use in Cayman Islands).
86
     */
87
    public const EPSG_CLARKE_1866 = 'urn:ogc:def:ellipsoid:EPSG::7008';
88
89
    /**
90
     * Clarke 1866 Authalic Sphere
91
     * Authalic sphere derived from Clarke 1866 ellipsoid (code 7008).
92
     */
93
    public const EPSG_CLARKE_1866_AUTHALIC_SPHERE = 'urn:ogc:def:ellipsoid:EPSG::7052';
94
95
    /**
96
     * Clarke 1880
97
     * Clarke gave a and b and also 1/f=293.465 (to 3 decimal places exactly). In the 19th century b was normally given
98
     * as the second defining parameter.
99
     */
100
    public const EPSG_CLARKE_1880 = 'urn:ogc:def:ellipsoid:EPSG::7034';
101
102
    /**
103
     * Clarke 1880 (Arc)
104
     * Adopts Clarke's value for a with derived 1/f.  Uses his 1865 ratio of 39.370432 inch per metre to convert
105
     * semi-major axis to metres.
106
     */
107
    public const EPSG_CLARKE_1880_ARC = 'urn:ogc:def:ellipsoid:EPSG::7013';
108
109
    /**
110
     * Clarke 1880 (Benoit)
111
     * Adopts Clarke's values for a and b.  Uses Benoit's 1895 ratio of 0.9143992 metres per yard to convert to metres.
112
     */
113
    public const EPSG_CLARKE_1880_BENOIT = 'urn:ogc:def:ellipsoid:EPSG::7010';
114
115
    /**
116
     * Clarke 1880 (IGN)
117
     * Adopts Clarke's values for a and b using his 1865 ratio of 39.370432 inches per metre to convert axes to metres.
118
     */
119
    public const EPSG_CLARKE_1880_IGN = 'urn:ogc:def:ellipsoid:EPSG::7011';
120
121
    /**
122
     * Clarke 1880 (RGS)
123
     * Adopts Clarke's values for a and 1/f.  Adopts his 1865 ratio of 39.370432 inches per metre to convert semi-major
124
     * axis to metres. Also known as Clarke Modified 1880.
125
     */
126
    public const EPSG_CLARKE_1880_RGS = 'urn:ogc:def:ellipsoid:EPSG::7012';
127
128
    /**
129
     * Clarke 1880 (SGA 1922)
130
     * Used in Old French Triangulation (ATF).   Uses Clarke's 1865 inch-metre ratio of 39.370432 to convert axes to
131
     * metres.
132
     */
133
    public const EPSG_CLARKE_1880_SGA_1922 = 'urn:ogc:def:ellipsoid:EPSG::7014';
134
135
    /**
136
     * Clarke 1880 (international foot)
137
     * Clarke's 1880 definition in feet assumed for the purposes of metric conversion to be international foot. a =
138
     * 6378306.370…metres. 1/f derived from a and b = 293.4663077… Used in Fiji.
139
     */
140
    public const EPSG_CLARKE_1880_INTERNATIONAL_FOOT = 'urn:ogc:def:ellipsoid:EPSG::7055';
141
142
    /**
143
     * Danish 1876
144
     * Semi-major axis originally given as 3271883.25 toise. Uses toise to French metre ratio of 1.94903631 to two
145
     * decimal place precision. An alternative ratio with the German legal metre of 1.9490622 giving 6377104m has not
146
     * been used in Danish work.
147
     */
148
    public const EPSG_DANISH_1876 = 'urn:ogc:def:ellipsoid:EPSG::7051';
149
150
    /**
151
     * Everest (1830 Definition)
152
     * Everest gave a and b to 2 decimal places and also 1/f=300.8017 (to 4 decimal places exactly). In the 19th
153
     * century b was normally given as the second defining parameter.
154
     */
155
    public const EPSG_EVEREST_1830_DEFINITION = 'urn:ogc:def:ellipsoid:EPSG::7042';
156
157
    /**
158
     * Everest 1830 (1937 Adjustment)
159
     * Used for the 1937 readjustment of Indian triangulation.  Clarke's 1865 Indian-British foot ratio (0.99999566)
160
     * and Benoit's 1898 British inch-metre ratio (39.370113) rounded as 0.30479841 exactly and applied to Everest's
161
     * 1830 definition taken as a and 1/f.
162
     */
163
    public const EPSG_EVEREST_1830_1937_ADJUSTMENT = 'urn:ogc:def:ellipsoid:EPSG::7015';
164
165
    /**
166
     * Everest 1830 (1962 Definition)
167
     * Used by Pakistan since metrication.  Clarke's 1865 Indian foot-British foot ratio (0.99999566) and his 1865
168
     * British inch-metre ratio (39.369971) rounded with slight error as 1 Ind ft = 0.3047995m exactly and applied to
169
     * Everest's 1830 definition of a & b.
170
     */
171
    public const EPSG_EVEREST_1830_1962_DEFINITION = 'urn:ogc:def:ellipsoid:EPSG::7044';
172
173
    /**
174
     * Everest 1830 (1967 Definition)
175
     * Adopted 1967 for use in East Malaysia.  Applies Sears 1922 inch-metre ratio of 39.370147 to Everest 1830
176
     * original definition of a and 1/f but with a taken to be in British rather than Indian feet.
177
     */
178
    public const EPSG_EVEREST_1830_1967_DEFINITION = 'urn:ogc:def:ellipsoid:EPSG::7016';
179
180
    /**
181
     * Everest 1830 (1975 Definition)
182
     * Used by India since metrication.  Clarke's 1865 Indian foot-British foot ratio (0.99999566) and his 1865 British
183
     * inch-metre ratio (39.369971) rounded as 1 Ind ft = 0.3047995m exactly applied to Everest's 1830 original
184
     * definition taken as a and b.
185
     */
186
    public const EPSG_EVEREST_1830_1975_DEFINITION = 'urn:ogc:def:ellipsoid:EPSG::7045';
187
188
    /**
189
     * Everest 1830 (RSO 1969)
190
     * Adopted for 1969 metrication of peninsula Malaysia RSO grid.  Uses Sears 1922 yard-metre ratio truncated to 6
191
     * significant figures applied to Everest 1830 original definition of a and 1/f but with a taken to be in British
192
     * rather than Indian feet.
193
     */
194
    public const EPSG_EVEREST_1830_RSO_1969 = 'urn:ogc:def:ellipsoid:EPSG::7056';
195
196
    /**
197
     * Everest 1830 Modified
198
     * Adopted 1967 for use in West Malaysia.  Applies Benoit 1898 inch-metre ratio of 39.370113 to Everest 1830
199
     * original definition of a and 1/f but with a taken to be in British rather than Indian feet.
200
     */
201
    public const EPSG_EVEREST_1830_MODIFIED = 'urn:ogc:def:ellipsoid:EPSG::7018';
202
203
    /**
204
     * GEM 10C
205
     * Used for  GEM 10C Gravity Potential Model.
206
     */
207
    public const EPSG_GEM_10C = 'urn:ogc:def:ellipsoid:EPSG::7031';
208
209
    /**
210
     * GRS 1967
211
     * Adopted by IUGG 1967 Lucerne.  1/f given is derived from geocentric gravitational constant (GM)= 398603e9
212
     * m*m*m/s/s; dynamic form factor (J2) = 0.0010827 and Earth's angular velocity w = 7.2921151467e-5 rad/s. See also
213
     * GRS 1967 Modified (code 7050).
214
     */
215
    public const EPSG_GRS_1967 = 'urn:ogc:def:ellipsoid:EPSG::7036';
216
217
    /**
218
     * GRS 1967 Modified
219
     * Based on the GRS 1967 figure (code 7036) but with 1/f taken to 2 decimal places exactly. Used with SAD69 and
220
     * TWD67 datums. The dimensions are also used as the Australian National Spheroid (code 7003).
221
     */
222
    public const EPSG_GRS_1967_MODIFIED = 'urn:ogc:def:ellipsoid:EPSG::7050';
223
224
    /**
225
     * GRS 1980
226
     * Adopted by IUGG 1979 Canberra.  Inverse flattening is derived from geocentric gravitational constant GM =
227
     * 3986005e8 m*m*m/s/s; dynamic form factor J2 = 108263e-8 and Earth's angular velocity = 7292115e-11 rad/s.
228
     */
229
    public const EPSG_GRS_1980 = 'urn:ogc:def:ellipsoid:EPSG::7019';
230
231
    /**
232
     * GRS 1980 Authalic Sphere
233
     * Authalic sphere derived from GRS 1980 ellipsoid (code 7019).  (An authalic sphere is one with a surface area
234
     * equal to the surface area of the ellipsoid). 1/f is infinite.
235
     */
236
    public const EPSG_GRS_1980_AUTHALIC_SPHERE = 'urn:ogc:def:ellipsoid:EPSG::7048';
237
238
    /**
239
     * GSK-2011.
240
     */
241
    public const EPSG_GSK_2011 = 'urn:ogc:def:ellipsoid:EPSG::1025';
242
243
    /**
244
     * Helmert 1906
245
     * Helmert 1906/III solution.
246
     */
247
    public const EPSG_HELMERT_1906 = 'urn:ogc:def:ellipsoid:EPSG::7020';
248
249
    /**
250
     * Hough 1960.
251
     */
252
    public const EPSG_HOUGH_1960 = 'urn:ogc:def:ellipsoid:EPSG::7053';
253
254
    /**
255
     * Hughes 1980
256
     * Used in US DMSP SSM/I microwave sensor processing software. Semi-minor axis derived from
257
     * eccentricity=0.081816153. Semi-major axis (a) sometimes given as 3443.992nm which OGP suspects is a derived
258
     * approximation. OGP conversion assumes 1nm=1852m exactly.
259
     */
260
    public const EPSG_HUGHES_1980 = 'urn:ogc:def:ellipsoid:EPSG::7058';
261
262
    /**
263
     * IAG 1975.
264
     */
265
    public const EPSG_IAG_1975 = 'urn:ogc:def:ellipsoid:EPSG::7049';
266
267
    /**
268
     * Indonesian National Spheroid
269
     * Based on the GRS 1967 figure but with 1/f taken to 3 decimal places exactly.
270
     */
271
    public const EPSG_INDONESIAN_NATIONAL_SPHEROID = 'urn:ogc:def:ellipsoid:EPSG::7021';
272
273
    /**
274
     * International 1924
275
     * Adopted by IUGG 1924 in Madrid. Based on Hayford 1909/1910 figures.
276
     */
277
    public const EPSG_INTERNATIONAL_1924 = 'urn:ogc:def:ellipsoid:EPSG::7022';
278
279
    /**
280
     * International 1924 Authalic Sphere
281
     * Authalic sphere derived from International 1924 ellipsoid (code 7022).
282
     */
283
    public const EPSG_INTERNATIONAL_1924_AUTHALIC_SPHERE = 'urn:ogc:def:ellipsoid:EPSG::7057';
284
285
    /**
286
     * Krassowsky 1940.
287
     */
288
    public const EPSG_KRASSOWSKY_1940 = 'urn:ogc:def:ellipsoid:EPSG::7024';
289
290
    /**
291
     * NWL 9D
292
     * Used by Transit Precise Ephemeris between October 1971 and January 1987.
293
     */
294
    public const EPSG_NWL_9D = 'urn:ogc:def:ellipsoid:EPSG::7025';
295
296
    /**
297
     * OSU86F
298
     * Used for OSU86 gravity potential (geoidal) model.
299
     */
300
    public const EPSG_OSU86F = 'urn:ogc:def:ellipsoid:EPSG::7032';
301
302
    /**
303
     * OSU91A
304
     * Used for OSU91 gravity potential (geoidal) model.
305
     */
306
    public const EPSG_OSU91A = 'urn:ogc:def:ellipsoid:EPSG::7033';
307
308
    /**
309
     * PZ-90
310
     * Earth's angular velocity ω = 7.292115e-5 rad/sec; gravitational constant GM =  3986004.418e8 m*m*m/s/s.
311
     */
312
    public const EPSG_PZ_90 = 'urn:ogc:def:ellipsoid:EPSG::7054';
313
314
    /**
315
     * Plessis 1817
316
     * Rescaling of Delambre 1810 figure (a=6376985 m) to make meridional arc from equator to pole equal to 10000000
317
     * metres exactly. (Ref: Strasser).
318
     */
319
    public const EPSG_PLESSIS_1817 = 'urn:ogc:def:ellipsoid:EPSG::7027';
320
321
    /**
322
     * Struve 1860
323
     * Original definition of semi-major axis given as 3272539 toise.  In "Ellipsoidisch Parameter der Erdfigur
324
     * (1800-1950)" , Strasser suggests a conversion factor of 1.94903631 which gives a=6378297.337 metres.
325
     */
326
    public const EPSG_STRUVE_1860 = 'urn:ogc:def:ellipsoid:EPSG::7028';
327
328
    /**
329
     * WGS 72.
330
     */
331
    public const EPSG_WGS_72 = 'urn:ogc:def:ellipsoid:EPSG::7043';
332
333
    /**
334
     * WGS 84
335
     * 1/f derived from four defining parameters semi-major axis; C20 = -484.16685*10e-6; earth's angular velocity ω =
336
     * 7292115e-11 rad/sec; gravitational constant GM = 3986005e8 m*m*m/s/s. In 1994 new GM = 3986004.418e8 m*m*m/s/s
337
     * but a and 1/f retained.
338
     */
339
    public const EPSG_WGS_84 = 'urn:ogc:def:ellipsoid:EPSG::7030';
340
341
    /**
342
     * War Office
343
     * In non-metric form, a=20926201 Gold Coast feet. DMA Technical Manual 8358.1 and data derived from this quotes
344
     * value for semi-major axis as 6378300.58m: OGP recommends use of defined value 6378300m exactly.
345
     */
346
    public const EPSG_WAR_OFFICE = 'urn:ogc:def:ellipsoid:EPSG::7029';
347
348
    /**
349
     * Zach 1812
350
     * Defined as log a = 6.5266022 Klafter (Austrian fathom, Kl), log b = 6.5251990 Kl. a=10^6.526 6022 = 3362035 Kl.
351
     * Then using the Austro-Hungarian 1871 KL/m legal ratio of 1.89648384, a = 6376045m.
352
     */
353
    public const EPSG_ZACH_1812 = 'urn:ogc:def:ellipsoid:EPSG::1026';
354
355
    protected static array $sridData = [
356
        'urn:ogc:def:ellipsoid:EPSG::1024' => [
357
            'name' => 'CGCS2000',
358
            'semi_major_axis' => 6378137.0,
359
            'semi_minor_axis' => 6356752.314140356,
360
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
361
        ],
362
        'urn:ogc:def:ellipsoid:EPSG::1025' => [
363
            'name' => 'GSK-2011',
364
            'semi_major_axis' => 6378136.5,
365
            'semi_minor_axis' => 6356751.757955603,
366
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
367
        ],
368
        'urn:ogc:def:ellipsoid:EPSG::1026' => [
369
            'name' => 'Zach 1812',
370
            'semi_major_axis' => 6376045.0,
371
            'semi_minor_axis' => 6355477.112903226,
372
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
373
        ],
374
        'urn:ogc:def:ellipsoid:EPSG::7001' => [
375
            'name' => 'Airy 1830',
376
            'semi_major_axis' => 6377563.396,
377
            'semi_minor_axis' => 6356256.909237285,
378
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
379
        ],
380
        'urn:ogc:def:ellipsoid:EPSG::7002' => [
381
            'name' => 'Airy Modified 1849',
382
            'semi_major_axis' => 6377340.189,
383
            'semi_minor_axis' => 6356034.447938534,
384
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
385
        ],
386
        'urn:ogc:def:ellipsoid:EPSG::7003' => [
387
            'name' => 'Australian National Spheroid',
388
            'semi_major_axis' => 6378160.0,
389
            'semi_minor_axis' => 6356774.719195306,
390
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
391
        ],
392
        'urn:ogc:def:ellipsoid:EPSG::7004' => [
393
            'name' => 'Bessel 1841',
394
            'semi_major_axis' => 6377397.155,
395
            'semi_minor_axis' => 6356078.962818189,
396
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
397
        ],
398
        'urn:ogc:def:ellipsoid:EPSG::7005' => [
399
            'name' => 'Bessel Modified',
400
            'semi_major_axis' => 6377492.018,
401
            'semi_minor_axis' => 6356173.508712696,
402
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
403
        ],
404
        'urn:ogc:def:ellipsoid:EPSG::7007' => [
405
            'name' => 'Clarke 1858',
406
            'semi_major_axis' => 20926348.0,
407
            'semi_minor_axis' => 20855233.0,
408
            'uom' => 'urn:ogc:def:uom:EPSG::9005',
409
        ],
410
        'urn:ogc:def:ellipsoid:EPSG::7008' => [
411
            'name' => 'Clarke 1866',
412
            'semi_major_axis' => 6378206.4,
413
            'semi_minor_axis' => 6356583.8,
414
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
415
        ],
416
        'urn:ogc:def:ellipsoid:EPSG::7010' => [
417
            'name' => 'Clarke 1880 (Benoit)',
418
            'semi_major_axis' => 6378300.789,
419
            'semi_minor_axis' => 6356566.435,
420
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
421
        ],
422
        'urn:ogc:def:ellipsoid:EPSG::7011' => [
423
            'name' => 'Clarke 1880 (IGN)',
424
            'semi_major_axis' => 6378249.2,
425
            'semi_minor_axis' => 6356515.0,
426
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
427
        ],
428
        'urn:ogc:def:ellipsoid:EPSG::7012' => [
429
            'name' => 'Clarke 1880 (RGS)',
430
            'semi_major_axis' => 6378249.145,
431
            'semi_minor_axis' => 6356514.8695497755,
432
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
433
        ],
434
        'urn:ogc:def:ellipsoid:EPSG::7013' => [
435
            'name' => 'Clarke 1880 (Arc)',
436
            'semi_major_axis' => 6378249.145,
437
            'semi_minor_axis' => 6356514.966398753,
438
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
439
        ],
440
        'urn:ogc:def:ellipsoid:EPSG::7014' => [
441
            'name' => 'Clarke 1880 (SGA 1922)',
442
            'semi_major_axis' => 6378249.2,
443
            'semi_minor_axis' => 6356514.996941779,
444
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
445
        ],
446
        'urn:ogc:def:ellipsoid:EPSG::7015' => [
447
            'name' => 'Everest 1830 (1937 Adjustment)',
448
            'semi_major_axis' => 6377276.345,
449
            'semi_minor_axis' => 6356075.413140239,
450
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
451
        ],
452
        'urn:ogc:def:ellipsoid:EPSG::7016' => [
453
            'name' => 'Everest 1830 (1967 Definition)',
454
            'semi_major_axis' => 6377298.556,
455
            'semi_minor_axis' => 6356097.550300896,
456
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
457
        ],
458
        'urn:ogc:def:ellipsoid:EPSG::7018' => [
459
            'name' => 'Everest 1830 Modified',
460
            'semi_major_axis' => 6377304.063,
461
            'semi_minor_axis' => 6356103.038993155,
462
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
463
        ],
464
        'urn:ogc:def:ellipsoid:EPSG::7019' => [
465
            'name' => 'GRS 1980',
466
            'semi_major_axis' => 6378137.0,
467
            'semi_minor_axis' => 6356752.314140356,
468
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
469
        ],
470
        'urn:ogc:def:ellipsoid:EPSG::7020' => [
471
            'name' => 'Helmert 1906',
472
            'semi_major_axis' => 6378200.0,
473
            'semi_minor_axis' => 6356818.169627891,
474
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
475
        ],
476
        'urn:ogc:def:ellipsoid:EPSG::7021' => [
477
            'name' => 'Indonesian National Spheroid',
478
            'semi_major_axis' => 6378160.0,
479
            'semi_minor_axis' => 6356774.50408554,
480
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
481
        ],
482
        'urn:ogc:def:ellipsoid:EPSG::7022' => [
483
            'name' => 'International 1924',
484
            'semi_major_axis' => 6378388.0,
485
            'semi_minor_axis' => 6356911.9461279465,
486
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
487
        ],
488
        'urn:ogc:def:ellipsoid:EPSG::7024' => [
489
            'name' => 'Krassowsky 1940',
490
            'semi_major_axis' => 6378245.0,
491
            'semi_minor_axis' => 6356863.018773047,
492
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
493
        ],
494
        'urn:ogc:def:ellipsoid:EPSG::7025' => [
495
            'name' => 'NWL 9D',
496
            'semi_major_axis' => 6378145.0,
497
            'semi_minor_axis' => 6356759.769488684,
498
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
499
        ],
500
        'urn:ogc:def:ellipsoid:EPSG::7027' => [
501
            'name' => 'Plessis 1817',
502
            'semi_major_axis' => 6376523.0,
503
            'semi_minor_axis' => 6355862.933255573,
504
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
505
        ],
506
        'urn:ogc:def:ellipsoid:EPSG::7028' => [
507
            'name' => 'Struve 1860',
508
            'semi_major_axis' => 6378298.3,
509
            'semi_minor_axis' => 6356657.142669562,
510
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
511
        ],
512
        'urn:ogc:def:ellipsoid:EPSG::7029' => [
513
            'name' => 'War Office',
514
            'semi_major_axis' => 6378300.0,
515
            'semi_minor_axis' => 6356751.689189189,
516
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
517
        ],
518
        'urn:ogc:def:ellipsoid:EPSG::7030' => [
519
            'name' => 'WGS 84',
520
            'semi_major_axis' => 6378137.0,
521
            'semi_minor_axis' => 6356752.314245179,
522
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
523
        ],
524
        'urn:ogc:def:ellipsoid:EPSG::7031' => [
525
            'name' => 'GEM 10C',
526
            'semi_major_axis' => 6378137.0,
527
            'semi_minor_axis' => 6356752.314245179,
528
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
529
        ],
530
        'urn:ogc:def:ellipsoid:EPSG::7032' => [
531
            'name' => 'OSU86F',
532
            'semi_major_axis' => 6378136.2,
533
            'semi_minor_axis' => 6356751.516927429,
534
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
535
        ],
536
        'urn:ogc:def:ellipsoid:EPSG::7033' => [
537
            'name' => 'OSU91A',
538
            'semi_major_axis' => 6378136.3,
539
            'semi_minor_axis' => 6356751.616592146,
540
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
541
        ],
542
        'urn:ogc:def:ellipsoid:EPSG::7034' => [
543
            'name' => 'Clarke 1880',
544
            'semi_major_axis' => 20926202.0,
545
            'semi_minor_axis' => 20854895.0,
546
            'uom' => 'urn:ogc:def:uom:EPSG::9005',
547
        ],
548
        'urn:ogc:def:ellipsoid:EPSG::7036' => [
549
            'name' => 'GRS 1967',
550
            'semi_major_axis' => 6378160.0,
551
            'semi_minor_axis' => 6356774.516090714,
552
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
553
        ],
554
        'urn:ogc:def:ellipsoid:EPSG::7041' => [
555
            'name' => 'Average Terrestrial System 1977',
556
            'semi_major_axis' => 6378135.0,
557
            'semi_minor_axis' => 6356750.304921594,
558
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
559
        ],
560
        'urn:ogc:def:ellipsoid:EPSG::7042' => [
561
            'name' => 'Everest (1830 Definition)',
562
            'semi_major_axis' => 20922931.8,
563
            'semi_minor_axis' => 20853374.58,
564
            'uom' => 'urn:ogc:def:uom:EPSG::9080',
565
        ],
566
        'urn:ogc:def:ellipsoid:EPSG::7043' => [
567
            'name' => 'WGS 72',
568
            'semi_major_axis' => 6378135.0,
569
            'semi_minor_axis' => 6356750.520016094,
570
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
571
        ],
572
        'urn:ogc:def:ellipsoid:EPSG::7044' => [
573
            'name' => 'Everest 1830 (1962 Definition)',
574
            'semi_major_axis' => 6377301.243,
575
            'semi_minor_axis' => 6356100.230165385,
576
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
577
        ],
578
        'urn:ogc:def:ellipsoid:EPSG::7045' => [
579
            'name' => 'Everest 1830 (1975 Definition)',
580
            'semi_major_axis' => 6377299.151,
581
            'semi_minor_axis' => 6356098.145120132,
582
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
583
        ],
584
        'urn:ogc:def:ellipsoid:EPSG::7046' => [
585
            'name' => 'Bessel Namibia (GLM)',
586
            'semi_major_axis' => 6377397.155,
587
            'semi_minor_axis' => 6356078.962818189,
588
            'uom' => 'urn:ogc:def:uom:EPSG::9031',
589
        ],
590
        'urn:ogc:def:ellipsoid:EPSG::7048' => [
591
            'name' => 'GRS 1980 Authalic Sphere',
592
            'semi_major_axis' => 6371007.0,
593
            'semi_minor_axis' => 6371007.0,
594
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
595
        ],
596
        'urn:ogc:def:ellipsoid:EPSG::7049' => [
597
            'name' => 'IAG 1975',
598
            'semi_major_axis' => 6378140.0,
599
            'semi_minor_axis' => 6356755.288157528,
600
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
601
        ],
602
        'urn:ogc:def:ellipsoid:EPSG::7050' => [
603
            'name' => 'GRS 1967 Modified',
604
            'semi_major_axis' => 6378160.0,
605
            'semi_minor_axis' => 6356774.719195306,
606
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
607
        ],
608
        'urn:ogc:def:ellipsoid:EPSG::7051' => [
609
            'name' => 'Danish 1876',
610
            'semi_major_axis' => 6377019.27,
611
            'semi_minor_axis' => 6355762.5391,
612
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
613
        ],
614
        'urn:ogc:def:ellipsoid:EPSG::7052' => [
615
            'name' => 'Clarke 1866 Authalic Sphere',
616
            'semi_major_axis' => 6370997.0,
617
            'semi_minor_axis' => 6370997.0,
618
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
619
        ],
620
        'urn:ogc:def:ellipsoid:EPSG::7053' => [
621
            'name' => 'Hough 1960',
622
            'semi_major_axis' => 6378270.0,
623
            'semi_minor_axis' => 6356794.343434343,
624
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
625
        ],
626
        'urn:ogc:def:ellipsoid:EPSG::7054' => [
627
            'name' => 'PZ-90',
628
            'semi_major_axis' => 6378136.0,
629
            'semi_minor_axis' => 6356751.361745712,
630
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
631
        ],
632
        'urn:ogc:def:ellipsoid:EPSG::7055' => [
633
            'name' => 'Clarke 1880 (international foot)',
634
            'semi_major_axis' => 20926202.0,
635
            'semi_minor_axis' => 20854895.0,
636
            'uom' => 'urn:ogc:def:uom:EPSG::9002',
637
        ],
638
        'urn:ogc:def:ellipsoid:EPSG::7056' => [
639
            'name' => 'Everest 1830 (RSO 1969)',
640
            'semi_major_axis' => 6377295.664,
641
            'semi_minor_axis' => 6356094.667915204,
642
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
643
        ],
644
        'urn:ogc:def:ellipsoid:EPSG::7057' => [
645
            'name' => 'International 1924 Authalic Sphere',
646
            'semi_major_axis' => 6371228.0,
647
            'semi_minor_axis' => 6371228.0,
648
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
649
        ],
650
        'urn:ogc:def:ellipsoid:EPSG::7058' => [
651
            'name' => 'Hughes 1980',
652
            'semi_major_axis' => 6378273.0,
653
            'semi_minor_axis' => 6356889.449,
654
            'uom' => 'urn:ogc:def:uom:EPSG::9001',
655
        ],
656
    ];
657
658
    private static array $cachedObjects = [];
659
660
    protected Length $semiMajorAxis;
661
662
    protected Length $semiMinorAxis;
663
664 461
    protected string $name;
665
666 461
    protected string $srid;
667 461
668 461
    public function __construct(Length $semiMajorAxis, Length $semiMinorAxis, string $name = '', string $srid = '')
669
    {
670 59791
        $this->semiMajorAxis = $semiMajorAxis;
671
        $this->semiMinorAxis = $semiMinorAxis;
672 59791
        $this->name = $name;
673
        $this->srid = $srid;
674
    }
675 189
676
    public function getSemiMajorAxis(): Length
677 189
    {
678
        return $this->semiMajorAxis;
679
    }
680 59665
681
    public function getSemiMinorAxis(): Length
682 59665
    {
683
        return $this->semiMinorAxis;
684
    }
685 44903
686
    public function getFlattening(): float
687 44903
    {
688
        return ($this->semiMajorAxis->getValue() - $this->semiMinorAxis->getValue()) / $this->semiMajorAxis->getValue();
689
    }
690 59548
691
    public function getInverseFlattening(): float
692 59548
    {
693
        return 1 / $this->getFlattening();
694
    }
695 54994
696
    public function getEccentricity(): float
697 54994
    {
698 9
        return sqrt($this->getEccentricitySquared());
699
    }
700
701 54985
    public function getEccentricitySquared(): float
702 443
    {
703
        return (2 * $this->getFlattening()) - $this->getFlattening() ** 2;
704 443
    }
705 443
706 443
    public function getName(): string
707
    {
708
        return $this->name;
709
    }
710 54985
711
    public function getSRID(): string
712
    {
713 9
        return $this->srid;
714
    }
715 9
716 9
    public static function fromSRID(string $srid): self
717 9
    {
718
        if (!isset(static::$sridData[$srid])) {
719
            throw new UnknownEllipsoidException($srid);
720 9
        }
721
722
        if (!isset(self::$cachedObjects[$srid])) {
723
            $data = static::$sridData[$srid];
724
725
            self::$cachedObjects[$srid] = new static(
726
                Length::makeUnit($data['semi_major_axis'], $data['uom']),
727
                Length::makeUnit($data['semi_minor_axis'], $data['uom']),
728
                $data['name'],
729
                $srid,
730
            );
731
        }
732
733
        return self::$cachedObjects[$srid];
734
    }
735
736
    public static function getSupportedSRIDs(): array
737
    {
738
        $supported = [];
739
        foreach (static::$sridData as $srid => $data) {
740
            $supported[$srid] = $data['name'];
741
        }
742
743
        return $supported;
744
    }
745
746
    public static function registerCustomEllipsoid(string $srid, string $name, float $semiMajorAxis, float $semiMinorAxis, string $uomSrid): void
747
    {
748
        self::$sridData[$srid] = ['name' => $name, 'semi_major_axis' => $semiMajorAxis, 'semi_minor_axis' => $semiMinorAxis, 'uom' => $uomSrid];
749
    }
750
}
751