Coverage Report

Created: 2026-03-22 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PROJ/src/iso19111/operation/parammappings.cpp
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  PROJ
4
 * Purpose:  ISO19111:2019 implementation
5
 * Author:   Even Rouault <even dot rouault at spatialys dot com>
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
9
 *
10
 * Permission is hereby granted, free of charge, to any person obtaining a
11
 * copy of this software and associated documentation files (the "Software"),
12
 * to deal in the Software without restriction, including without limitation
13
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14
 * and/or sell copies of the Software, and to permit persons to whom the
15
 * Software is furnished to do so, subject to the following conditions:
16
 *
17
 * The above copyright notice and this permission notice shall be included
18
 * in all copies or substantial portions of the Software.
19
 *
20
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26
 * DEALINGS IN THE SOFTWARE.
27
 ****************************************************************************/
28
29
#include "parammappings.hpp"
30
#include "oputils.hpp"
31
#include "proj_constants.h"
32
33
#include "proj/internal/internal.hpp"
34
35
NS_PROJ_START
36
37
using namespace internal;
38
39
namespace operation {
40
41
//! @cond Doxygen_Suppress
42
43
const char *WKT1_LATITUDE_OF_ORIGIN = "latitude_of_origin";
44
const char *WKT1_CENTRAL_MERIDIAN = "central_meridian";
45
const char *WKT1_SCALE_FACTOR = "scale_factor";
46
const char *WKT1_FALSE_EASTING = "false_easting";
47
const char *WKT1_FALSE_NORTHING = "false_northing";
48
const char *WKT1_STANDARD_PARALLEL_1 = "standard_parallel_1";
49
const char *WKT1_STANDARD_PARALLEL_2 = "standard_parallel_2";
50
const char *WKT1_LATITUDE_OF_CENTER = "latitude_of_center";
51
const char *WKT1_LONGITUDE_OF_CENTER = "longitude_of_center";
52
const char *WKT1_AZIMUTH = "azimuth";
53
const char *WKT1_RECTIFIED_GRID_ANGLE = "rectified_grid_angle";
54
55
static const char *lat_0 = "lat_0";
56
static const char *lat_1 = "lat_1";
57
static const char *lat_2 = "lat_2";
58
static const char *lat_ts = "lat_ts";
59
static const char *lon_0 = "lon_0";
60
static const char *lon_1 = "lon_1";
61
static const char *lon_2 = "lon_2";
62
static const char *lonc = "lonc";
63
static const char *alpha = "alpha";
64
static const char *gamma = "gamma";
65
static const char *k_0 = "k_0";
66
static const char *k = "k";
67
static const char *x_0 = "x_0";
68
static const char *y_0 = "y_0";
69
static const char *h = "h";
70
71
// ---------------------------------------------------------------------------
72
73
const ParamMapping paramLatitudeNatOrigin = {
74
    EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
75
    EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, WKT1_LATITUDE_OF_ORIGIN,
76
    common::UnitOfMeasure::Type::ANGULAR, lat_0};
77
78
static const ParamMapping paramLongitudeNatOrigin = {
79
    EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
80
    EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, WKT1_CENTRAL_MERIDIAN,
81
    common::UnitOfMeasure::Type::ANGULAR, lon_0};
82
83
static const ParamMapping paramScaleFactor = {
84
    EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN,
85
    EPSG_CODE_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN, WKT1_SCALE_FACTOR,
86
    common::UnitOfMeasure::Type::SCALE, k_0};
87
88
static const ParamMapping paramScaleFactorK = {
89
    EPSG_NAME_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN,
90
    EPSG_CODE_PARAMETER_SCALE_FACTOR_AT_NATURAL_ORIGIN, WKT1_SCALE_FACTOR,
91
    common::UnitOfMeasure::Type::SCALE, k};
92
93
static const ParamMapping paramFalseEasting = {
94
    EPSG_NAME_PARAMETER_FALSE_EASTING, EPSG_CODE_PARAMETER_FALSE_EASTING,
95
    WKT1_FALSE_EASTING, common::UnitOfMeasure::Type::LINEAR, x_0};
96
97
static const ParamMapping paramFalseNorthing = {
98
    EPSG_NAME_PARAMETER_FALSE_NORTHING, EPSG_CODE_PARAMETER_FALSE_NORTHING,
99
    WKT1_FALSE_NORTHING, common::UnitOfMeasure::Type::LINEAR, y_0};
100
101
static const ParamMapping paramLatitudeFalseOrigin = {
102
    EPSG_NAME_PARAMETER_LATITUDE_FALSE_ORIGIN,
103
    EPSG_CODE_PARAMETER_LATITUDE_FALSE_ORIGIN, WKT1_LATITUDE_OF_ORIGIN,
104
    common::UnitOfMeasure::Type::ANGULAR, lat_0};
105
106
static const ParamMapping paramLongitudeFalseOrigin = {
107
    EPSG_NAME_PARAMETER_LONGITUDE_FALSE_ORIGIN,
108
    EPSG_CODE_PARAMETER_LONGITUDE_FALSE_ORIGIN, WKT1_CENTRAL_MERIDIAN,
109
    common::UnitOfMeasure::Type::ANGULAR, lon_0};
110
111
static const ParamMapping paramEastingFalseOrigin = {
112
    EPSG_NAME_PARAMETER_EASTING_FALSE_ORIGIN,
113
    EPSG_CODE_PARAMETER_EASTING_FALSE_ORIGIN, WKT1_FALSE_EASTING,
114
    common::UnitOfMeasure::Type::LINEAR, x_0};
115
116
static const ParamMapping paramNorthingFalseOrigin = {
117
    EPSG_NAME_PARAMETER_NORTHING_FALSE_ORIGIN,
118
    EPSG_CODE_PARAMETER_NORTHING_FALSE_ORIGIN, WKT1_FALSE_NORTHING,
119
    common::UnitOfMeasure::Type::LINEAR, y_0};
120
121
static const ParamMapping paramLatitude1stStdParallel = {
122
    EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
123
    EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, WKT1_STANDARD_PARALLEL_1,
124
    common::UnitOfMeasure::Type::ANGULAR, lat_1};
125
126
static const ParamMapping paramLatitude2ndStdParallel = {
127
    EPSG_NAME_PARAMETER_LATITUDE_2ND_STD_PARALLEL,
128
    EPSG_CODE_PARAMETER_LATITUDE_2ND_STD_PARALLEL, WKT1_STANDARD_PARALLEL_2,
129
    common::UnitOfMeasure::Type::ANGULAR, lat_2};
130
131
static const ParamMapping *const paramsNatOriginScale[] = {
132
    &paramLatitudeNatOrigin, &paramLongitudeNatOrigin, &paramScaleFactor,
133
    &paramFalseEasting,      &paramFalseNorthing,      nullptr};
134
135
static const ParamMapping *const paramsNatOriginScaleK[] = {
136
    &paramLatitudeNatOrigin, &paramLongitudeNatOrigin, &paramScaleFactorK,
137
    &paramFalseEasting,      &paramFalseNorthing,      nullptr};
138
139
static const ParamMapping paramLatFirstPoint = {
140
    "Latitude of 1st point", 0, "Latitude_Of_1st_Point",
141
    common::UnitOfMeasure::Type::ANGULAR, lat_1};
142
static const ParamMapping paramLongFirstPoint = {
143
    "Longitude of 1st point", 0, "Longitude_Of_1st_Point",
144
    common::UnitOfMeasure::Type::ANGULAR, lon_1};
145
static const ParamMapping paramLatSecondPoint = {
146
    "Latitude of 2nd point", 0, "Latitude_Of_2nd_Point",
147
    common::UnitOfMeasure::Type::ANGULAR, lat_2};
148
static const ParamMapping paramLongSecondPoint = {
149
    "Longitude of 2nd point", 0, "Longitude_Of_2nd_Point",
150
    common::UnitOfMeasure::Type::ANGULAR, lon_2};
151
152
static const ParamMapping *const paramsTPEQD[] = {&paramLatFirstPoint,
153
                                                  &paramLongFirstPoint,
154
                                                  &paramLatSecondPoint,
155
                                                  &paramLongSecondPoint,
156
                                                  &paramFalseEasting,
157
                                                  &paramFalseNorthing,
158
                                                  nullptr};
159
160
static const ParamMapping *const paramsTMG[] = {
161
    &paramLatitudeFalseOrigin, &paramLongitudeFalseOrigin,
162
    &paramEastingFalseOrigin, &paramNorthingFalseOrigin, nullptr};
163
164
static const ParamMapping paramLatFalseOriginLatOfCenter = {
165
    EPSG_NAME_PARAMETER_LATITUDE_FALSE_ORIGIN,
166
    EPSG_CODE_PARAMETER_LATITUDE_FALSE_ORIGIN, WKT1_LATITUDE_OF_CENTER,
167
    common::UnitOfMeasure::Type::ANGULAR, lat_0};
168
169
static const ParamMapping paramLongFalseOriginLongOfCenter = {
170
    EPSG_NAME_PARAMETER_LONGITUDE_FALSE_ORIGIN,
171
    EPSG_CODE_PARAMETER_LONGITUDE_FALSE_ORIGIN, WKT1_LONGITUDE_OF_CENTER,
172
    common::UnitOfMeasure::Type::ANGULAR, lon_0};
173
174
static const ParamMapping *const paramsAEA_EQDC[] = {
175
    &paramLatFalseOriginLatOfCenter,
176
    &paramLongFalseOriginLongOfCenter,
177
    &paramLatitude1stStdParallel,
178
    &paramLatitude2ndStdParallel,
179
    &paramEastingFalseOrigin,
180
    &paramNorthingFalseOrigin,
181
    nullptr};
182
183
static const ParamMapping paramLatitudeNatOriginLCC1SP = {
184
    EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
185
    EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, WKT1_LATITUDE_OF_ORIGIN,
186
    common::UnitOfMeasure::Type::ANGULAR, lat_1};
187
188
static const ParamMapping *const paramsLCC1SP[] = {
189
    &paramLatitudeNatOriginLCC1SP,
190
    &paramLongitudeNatOrigin,
191
    &paramScaleFactor,
192
    &paramFalseEasting,
193
    &paramFalseNorthing,
194
    nullptr};
195
196
static const ParamMapping *const paramsLCC1SPVariantB[] = {
197
    &paramLatitudeNatOriginLCC1SP,
198
    &paramScaleFactor,
199
    &paramLatitudeFalseOrigin,
200
    &paramLongitudeFalseOrigin,
201
    &paramEastingFalseOrigin,
202
    &paramNorthingFalseOrigin,
203
    nullptr,
204
};
205
206
static const ParamMapping *const paramsLCC2SP[] = {
207
    &paramLatitudeFalseOrigin,
208
    &paramLongitudeFalseOrigin,
209
    &paramLatitude1stStdParallel,
210
    &paramLatitude2ndStdParallel,
211
    &paramEastingFalseOrigin,
212
    &paramNorthingFalseOrigin,
213
    nullptr,
214
};
215
216
static const ParamMapping paramEllipsoidScaleFactor = {
217
    EPSG_NAME_PARAMETER_ELLIPSOID_SCALE_FACTOR,
218
    EPSG_CODE_PARAMETER_ELLIPSOID_SCALE_FACTOR, nullptr,
219
    common::UnitOfMeasure::Type::SCALE, k_0};
220
221
static const ParamMapping *const paramsLCC2SPMichigan[] = {
222
    &paramLatitudeFalseOrigin,    &paramLongitudeFalseOrigin,
223
    &paramLatitude1stStdParallel, &paramLatitude2ndStdParallel,
224
    &paramEastingFalseOrigin,     &paramNorthingFalseOrigin,
225
    &paramEllipsoidScaleFactor,   nullptr,
226
};
227
228
static const ParamMapping paramLatNatLatCenter = {
229
    EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
230
    EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, WKT1_LATITUDE_OF_CENTER,
231
    common::UnitOfMeasure::Type::ANGULAR, lat_0};
232
233
static const ParamMapping paramLongNatLongCenter = {
234
    EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
235
    EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, WKT1_LONGITUDE_OF_CENTER,
236
    common::UnitOfMeasure::Type::ANGULAR, lon_0};
237
238
static const ParamMapping *const paramsAEQD[]{
239
    &paramLatNatLatCenter, &paramLongNatLongCenter, &paramFalseEasting,
240
    &paramFalseNorthing, nullptr};
241
242
static const ParamMapping *const paramsNatOrigin[] = {
243
    &paramLatitudeNatOrigin, &paramLongitudeNatOrigin, &paramFalseEasting,
244
    &paramFalseNorthing, nullptr};
245
246
static const ParamMapping paramLatNatOriginLat1 = {
247
    EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
248
    EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, WKT1_STANDARD_PARALLEL_1,
249
    common::UnitOfMeasure::Type::ANGULAR, lat_1};
250
251
static const ParamMapping *const paramsBonne[] = {
252
    &paramLatNatOriginLat1, &paramLongitudeNatOrigin, &paramFalseEasting,
253
    &paramFalseNorthing, nullptr};
254
255
static const ParamMapping paramLat1stParallelLatTs = {
256
    EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
257
    EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, WKT1_STANDARD_PARALLEL_1,
258
    common::UnitOfMeasure::Type::ANGULAR, lat_ts};
259
260
static const ParamMapping *const paramsCEA[] = {
261
    &paramLat1stParallelLatTs, &paramLongitudeNatOrigin, &paramFalseEasting,
262
    &paramFalseNorthing, nullptr};
263
264
static const ParamMapping *const paramsEQDC[] = {&paramLatNatLatCenter,
265
                                                 &paramLongNatLongCenter,
266
                                                 &paramLatitude1stStdParallel,
267
                                                 &paramLatitude2ndStdParallel,
268
                                                 &paramFalseEasting,
269
                                                 &paramFalseNorthing,
270
                                                 nullptr};
271
272
static const ParamMapping *const paramsLongNatOrigin[] = {
273
    &paramLongitudeNatOrigin, &paramFalseEasting, &paramFalseNorthing, nullptr};
274
275
static const ParamMapping *const paramsEqc[] = {
276
    &paramLat1stParallelLatTs,
277
    &paramLatitudeNatOrigin, // extension of EPSG, but used by GDAL / PROJ
278
    &paramLongitudeNatOrigin,  &paramFalseEasting,
279
    &paramFalseNorthing,       nullptr};
280
281
static const ParamMapping paramSatelliteHeight = {
282
    "Satellite Height", 0, "satellite_height",
283
    common::UnitOfMeasure::Type::LINEAR, h};
284
285
static const ParamMapping *const paramsGeos[] = {
286
    &paramLongitudeNatOrigin, &paramSatelliteHeight, &paramFalseEasting,
287
    &paramFalseNorthing, nullptr};
288
289
static const ParamMapping paramLatCentreLatCenter = {
290
    EPSG_NAME_PARAMETER_LATITUDE_PROJECTION_CENTRE,
291
    EPSG_CODE_PARAMETER_LATITUDE_PROJECTION_CENTRE, WKT1_LATITUDE_OF_CENTER,
292
    common::UnitOfMeasure::Type::ANGULAR, lat_0};
293
294
static const ParamMapping paramLonCentreLonCenterLonc = {
295
    EPSG_NAME_PARAMETER_LONGITUDE_PROJECTION_CENTRE,
296
    EPSG_CODE_PARAMETER_LONGITUDE_PROJECTION_CENTRE, WKT1_LONGITUDE_OF_CENTER,
297
    common::UnitOfMeasure::Type::ANGULAR, lonc};
298
299
static const ParamMapping paramAzimuth = {
300
    EPSG_NAME_PARAMETER_AZIMUTH_PROJECTION_CENTRE,
301
    EPSG_CODE_PARAMETER_AZIMUTH_PROJECTION_CENTRE, WKT1_AZIMUTH,
302
    common::UnitOfMeasure::Type::ANGULAR, alpha};
303
304
static const ParamMapping paramAngleToSkewGrid = {
305
    EPSG_NAME_PARAMETER_ANGLE_RECTIFIED_TO_SKEW_GRID,
306
    EPSG_CODE_PARAMETER_ANGLE_RECTIFIED_TO_SKEW_GRID, WKT1_RECTIFIED_GRID_ANGLE,
307
    common::UnitOfMeasure::Type::ANGULAR, gamma};
308
static const ParamMapping paramScaleFactorProjectionCentre = {
309
    EPSG_NAME_PARAMETER_SCALE_FACTOR_PROJECTION_CENTRE,
310
    EPSG_CODE_PARAMETER_SCALE_FACTOR_PROJECTION_CENTRE, WKT1_SCALE_FACTOR,
311
    common::UnitOfMeasure::Type::SCALE, k};
312
313
static const ParamMapping *const paramsHomVariantA[] = {
314
    &paramLatCentreLatCenter,
315
    &paramLonCentreLonCenterLonc,
316
    &paramAzimuth,
317
    &paramAngleToSkewGrid,
318
    &paramScaleFactorProjectionCentre,
319
    &paramFalseEasting,
320
    &paramFalseNorthing,
321
    nullptr};
322
323
static const ParamMapping paramFalseEastingProjectionCentre = {
324
    EPSG_NAME_PARAMETER_EASTING_PROJECTION_CENTRE,
325
    EPSG_CODE_PARAMETER_EASTING_PROJECTION_CENTRE, WKT1_FALSE_EASTING,
326
    common::UnitOfMeasure::Type::LINEAR, x_0};
327
328
static const ParamMapping paramFalseNorthingProjectionCentre = {
329
    EPSG_NAME_PARAMETER_NORTHING_PROJECTION_CENTRE,
330
    EPSG_CODE_PARAMETER_NORTHING_PROJECTION_CENTRE, WKT1_FALSE_NORTHING,
331
    common::UnitOfMeasure::Type::LINEAR, y_0};
332
333
static const ParamMapping *const paramsHomVariantB[] = {
334
    &paramLatCentreLatCenter,
335
    &paramLonCentreLonCenterLonc,
336
    &paramAzimuth,
337
    &paramAngleToSkewGrid,
338
    &paramScaleFactorProjectionCentre,
339
    &paramFalseEastingProjectionCentre,
340
    &paramFalseNorthingProjectionCentre,
341
    nullptr};
342
343
static const ParamMapping paramLatPoint1 = {
344
    "Latitude of 1st point", 0, "latitude_of_point_1",
345
    common::UnitOfMeasure::Type::ANGULAR, lat_1};
346
347
static const ParamMapping paramLongPoint1 = {
348
    "Longitude of 1st point", 0, "longitude_of_point_1",
349
    common::UnitOfMeasure::Type::ANGULAR, lon_1};
350
351
static const ParamMapping paramLatPoint2 = {
352
    "Latitude of 2nd point", 0, "latitude_of_point_2",
353
    common::UnitOfMeasure::Type::ANGULAR, lat_2};
354
355
static const ParamMapping paramLongPoint2 = {
356
    "Longitude of 2nd point", 0, "longitude_of_point_2",
357
    common::UnitOfMeasure::Type::ANGULAR, lon_2};
358
359
static const ParamMapping *const paramsHomTwoPoint[] = {
360
    &paramLatCentreLatCenter,
361
    &paramLatPoint1,
362
    &paramLongPoint1,
363
    &paramLatPoint2,
364
    &paramLongPoint2,
365
    &paramScaleFactorProjectionCentre,
366
    &paramFalseEastingProjectionCentre,
367
    &paramFalseNorthingProjectionCentre,
368
    nullptr};
369
370
static const ParamMapping *const paramsIMWP[] = {
371
    &paramLongitudeNatOrigin, &paramLatFirstPoint, &paramLatSecondPoint,
372
    &paramFalseEasting,       &paramFalseNorthing, nullptr};
373
374
static const ParamMapping paramLongCentre = {
375
    EPSG_NAME_PARAMETER_LONGITUDE_PROJECTION_CENTRE,
376
    EPSG_CODE_PARAMETER_LONGITUDE_PROJECTION_CENTRE, WKT1_LONGITUDE_OF_CENTER,
377
    common::UnitOfMeasure::Type::ANGULAR, lon_0};
378
379
static const ParamMapping *const paramsLocalOrthographic[] = {
380
    &paramLatCentreLatCenter,
381
    &paramLongCentre,
382
    &paramAzimuth,
383
    &paramScaleFactorProjectionCentre,
384
    &paramFalseEastingProjectionCentre,
385
    &paramFalseNorthingProjectionCentre,
386
    nullptr};
387
388
static const ParamMapping paramColatitudeConeAxis = {
389
    EPSG_NAME_PARAMETER_COLATITUDE_CONE_AXIS,
390
    EPSG_CODE_PARAMETER_COLATITUDE_CONE_AXIS, WKT1_AZIMUTH,
391
    common::UnitOfMeasure::Type::ANGULAR,
392
    "alpha"}; /* ignored by PROJ currently */
393
394
static const ParamMapping paramLatitudePseudoStdParallel = {
395
    EPSG_NAME_PARAMETER_LATITUDE_PSEUDO_STANDARD_PARALLEL,
396
    EPSG_CODE_PARAMETER_LATITUDE_PSEUDO_STANDARD_PARALLEL,
397
    "pseudo_standard_parallel_1", common::UnitOfMeasure::Type::ANGULAR,
398
    nullptr}; /* ignored by PROJ currently */
399
400
static const ParamMapping paramScaleFactorPseudoStdParallel = {
401
    EPSG_NAME_PARAMETER_SCALE_FACTOR_PSEUDO_STANDARD_PARALLEL,
402
    EPSG_CODE_PARAMETER_SCALE_FACTOR_PSEUDO_STANDARD_PARALLEL,
403
    WKT1_SCALE_FACTOR, common::UnitOfMeasure::Type::SCALE,
404
    k}; /* ignored by PROJ currently */
405
406
static const ParamMapping paramLongCentreLongCenter = {
407
    EPSG_NAME_PARAMETER_LONGITUDE_OF_ORIGIN,
408
    EPSG_CODE_PARAMETER_LONGITUDE_OF_ORIGIN, WKT1_LONGITUDE_OF_CENTER,
409
    common::UnitOfMeasure::Type::ANGULAR, lon_0};
410
411
static const ParamMapping *const krovakParameters[] = {
412
    &paramLatCentreLatCenter,
413
    &paramLongCentreLongCenter,
414
    &paramColatitudeConeAxis,
415
    &paramLatitudePseudoStdParallel,
416
    &paramScaleFactorPseudoStdParallel,
417
    &paramFalseEasting,
418
    &paramFalseNorthing,
419
    nullptr};
420
421
static const ParamMapping *const paramsLaea[] = {
422
    &paramLatNatLatCenter, &paramLongNatLongCenter, &paramFalseEasting,
423
    &paramFalseNorthing, nullptr};
424
425
static const ParamMapping *const paramsMiller[] = {
426
    &paramLongNatLongCenter, &paramFalseEasting, &paramFalseNorthing, nullptr};
427
428
static const ParamMapping paramLatMerc1SP = {
429
    EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
430
    EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
431
    nullptr, // always set to zero, not to be exported in WKT1
432
    common::UnitOfMeasure::Type::ANGULAR,
433
    nullptr}; // always set to zero, not to be exported in PROJ strings
434
435
static const ParamMapping *const paramsMerc1SP[] = {
436
    &paramLatMerc1SP,   &paramLongitudeNatOrigin, &paramScaleFactorK,
437
    &paramFalseEasting, &paramFalseNorthing,      nullptr};
438
439
static const ParamMapping *const paramsMerc2SP[] = {
440
    &paramLat1stParallelLatTs, &paramLongitudeNatOrigin, &paramFalseEasting,
441
    &paramFalseNorthing, nullptr};
442
443
static const ParamMapping *const paramsObliqueStereo[] = {
444
    &paramLatitudeNatOrigin, &paramLongitudeNatOrigin, &paramScaleFactorK,
445
    &paramFalseEasting,      &paramFalseNorthing,      nullptr};
446
447
static const ParamMapping paramLatStdParallel = {
448
    EPSG_NAME_PARAMETER_LATITUDE_STD_PARALLEL,
449
    EPSG_CODE_PARAMETER_LATITUDE_STD_PARALLEL, WKT1_LATITUDE_OF_ORIGIN,
450
    common::UnitOfMeasure::Type::ANGULAR, lat_ts};
451
452
static const ParamMapping paramsLongOrigin = {
453
    EPSG_NAME_PARAMETER_LONGITUDE_OF_ORIGIN,
454
    EPSG_CODE_PARAMETER_LONGITUDE_OF_ORIGIN, WKT1_CENTRAL_MERIDIAN,
455
    common::UnitOfMeasure::Type::ANGULAR, lon_0};
456
457
static const ParamMapping *const paramsPolarStereo[] = {
458
    &paramLatStdParallel, &paramsLongOrigin, &paramFalseEasting,
459
    &paramFalseNorthing, nullptr};
460
461
static const ParamMapping *const paramsLongNatOriginLongitudeCentre[] = {
462
    &paramLongNatLongCenter, &paramFalseEasting, &paramFalseNorthing, nullptr};
463
464
static const ParamMapping paramLatTrueScaleWag3 = {
465
    "Latitude of true scale", 0, WKT1_LATITUDE_OF_ORIGIN,
466
    common::UnitOfMeasure::Type::ANGULAR, lat_ts};
467
468
static const ParamMapping *const paramsWag3[] = {
469
    &paramLatTrueScaleWag3, &paramLongitudeNatOrigin, &paramFalseEasting,
470
    &paramFalseNorthing, nullptr};
471
472
static const ParamMapping paramPegLat = {
473
    "Peg point latitude", 0, "peg_point_latitude",
474
    common::UnitOfMeasure::Type::ANGULAR, "plat_0"};
475
476
static const ParamMapping paramPegLong = {
477
    "Peg point longitude", 0, "peg_point_longitude",
478
    common::UnitOfMeasure::Type::ANGULAR, "plon_0"};
479
480
static const ParamMapping paramPegHeading = {
481
    "Peg point heading", 0, "peg_point_heading",
482
    common::UnitOfMeasure::Type::ANGULAR, "phdg_0"};
483
484
static const ParamMapping paramPegHeight = {
485
    "Peg point height", 0, "peg_point_height",
486
    common::UnitOfMeasure::Type::LINEAR, "h_0"};
487
488
static const ParamMapping *const paramsSch[] = {
489
    &paramPegLat, &paramPegLong, &paramPegHeading, &paramPegHeight, nullptr};
490
491
static const ParamMapping *const paramsWink1[] = {
492
    &paramLongitudeNatOrigin, &paramLat1stParallelLatTs, &paramFalseEasting,
493
    &paramFalseNorthing, nullptr};
494
495
static const ParamMapping *const paramsWink2[] = {
496
    &paramLongitudeNatOrigin, &paramLatitude1stStdParallel, &paramFalseEasting,
497
    &paramFalseNorthing, nullptr};
498
499
static const ParamMapping paramLatLoxim = {
500
    EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
501
    EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, WKT1_LATITUDE_OF_ORIGIN,
502
    common::UnitOfMeasure::Type::ANGULAR, lat_1};
503
504
static const ParamMapping *const paramsLoxim[] = {
505
    &paramLatLoxim, &paramLongitudeNatOrigin, &paramFalseEasting,
506
    &paramFalseNorthing, nullptr};
507
508
static const ParamMapping paramLabordeObliqueMercatorAzimuth = {
509
    EPSG_NAME_PARAMETER_AZIMUTH_PROJECTION_CENTRE,
510
    EPSG_CODE_PARAMETER_AZIMUTH_PROJECTION_CENTRE, WKT1_AZIMUTH,
511
    common::UnitOfMeasure::Type::ANGULAR, "azi"};
512
513
static const ParamMapping *const paramsLabordeObliqueMercator[] = {
514
    &paramLatCentreLatCenter,
515
    &paramLongCentre,
516
    &paramLabordeObliqueMercatorAzimuth,
517
    &paramScaleFactorProjectionCentre,
518
    &paramFalseEasting,
519
    &paramFalseNorthing,
520
    nullptr};
521
522
static const ParamMapping paramLatTopoOrigin = {
523
    EPSG_NAME_PARAMETER_LATITUDE_TOPOGRAPHIC_ORIGIN,
524
    EPSG_CODE_PARAMETER_LATITUDE_TOPOGRAPHIC_ORIGIN, nullptr,
525
    common::UnitOfMeasure::Type::ANGULAR, lat_0};
526
527
static const ParamMapping paramLongTopoOrigin = {
528
    EPSG_NAME_PARAMETER_LONGITUDE_TOPOGRAPHIC_ORIGIN,
529
    EPSG_CODE_PARAMETER_LONGITUDE_TOPOGRAPHIC_ORIGIN, nullptr,
530
    common::UnitOfMeasure::Type::ANGULAR, lon_0};
531
532
static const ParamMapping paramHeightTopoOrigin = {
533
    EPSG_NAME_PARAMETER_ELLIPSOIDAL_HEIGHT_TOPOCENTRIC_ORIGIN,
534
    EPSG_CODE_PARAMETER_ELLIPSOIDAL_HEIGHT_TOPOCENTRIC_ORIGIN, nullptr,
535
    common::UnitOfMeasure::Type::LINEAR,
536
    nullptr}; // unsupported by PROJ right now
537
538
static const ParamMapping paramViewpointHeight = {
539
    EPSG_NAME_PARAMETER_VIEWPOINT_HEIGHT, EPSG_CODE_PARAMETER_VIEWPOINT_HEIGHT,
540
    nullptr, common::UnitOfMeasure::Type::LINEAR, "h"};
541
542
static const ParamMapping *const paramsVerticalPerspective[] = {
543
    &paramLatTopoOrigin,
544
    &paramLongTopoOrigin,
545
    &paramHeightTopoOrigin, // unsupported by PROJ right now
546
    &paramViewpointHeight,
547
    &paramFalseEasting,  // PROJ addition
548
    &paramFalseNorthing, // PROJ addition
549
    nullptr};
550
551
static const ParamMapping paramProjectionPlaneOriginHeight = {
552
    EPSG_NAME_PARAMETER_PROJECTION_PLANE_ORIGIN_HEIGHT,
553
    EPSG_CODE_PARAMETER_PROJECTION_PLANE_ORIGIN_HEIGHT, nullptr,
554
    common::UnitOfMeasure::Type::LINEAR, "h_0"};
555
556
static const ParamMapping *const paramsColombiaUrban[] = {
557
    &paramLatitudeNatOrigin,
558
    &paramLongitudeNatOrigin,
559
    &paramFalseEasting,
560
    &paramFalseNorthing,
561
    &paramProjectionPlaneOriginHeight,
562
    nullptr};
563
564
static const ParamMapping paramGeocentricXTopocentricOrigin = {
565
    EPSG_NAME_PARAMETER_GEOCENTRIC_X_TOPOCENTRIC_ORIGIN,
566
    EPSG_CODE_PARAMETER_GEOCENTRIC_X_TOPOCENTRIC_ORIGIN, nullptr,
567
    common::UnitOfMeasure::Type::LINEAR, "X_0"};
568
569
static const ParamMapping paramGeocentricYTopocentricOrigin = {
570
    EPSG_NAME_PARAMETER_GEOCENTRIC_Y_TOPOCENTRIC_ORIGIN,
571
    EPSG_CODE_PARAMETER_GEOCENTRIC_Y_TOPOCENTRIC_ORIGIN, nullptr,
572
    common::UnitOfMeasure::Type::LINEAR, "Y_0"};
573
574
static const ParamMapping paramGeocentricZTopocentricOrigin = {
575
    EPSG_NAME_PARAMETER_GEOCENTRIC_Z_TOPOCENTRIC_ORIGIN,
576
    EPSG_CODE_PARAMETER_GEOCENTRIC_Z_TOPOCENTRIC_ORIGIN, nullptr,
577
    common::UnitOfMeasure::Type::LINEAR, "Z_0"};
578
579
static const ParamMapping *const paramsGeocentricTopocentric[] = {
580
    &paramGeocentricXTopocentricOrigin, &paramGeocentricYTopocentricOrigin,
581
    &paramGeocentricZTopocentricOrigin, nullptr};
582
583
static const ParamMapping paramHeightTopoOriginWithH0 = {
584
    EPSG_NAME_PARAMETER_ELLIPSOIDAL_HEIGHT_TOPOCENTRIC_ORIGIN,
585
    EPSG_CODE_PARAMETER_ELLIPSOIDAL_HEIGHT_TOPOCENTRIC_ORIGIN, nullptr,
586
    common::UnitOfMeasure::Type::LINEAR, "h_0"};
587
588
static const ParamMapping *const paramsGeographicTopocentric[] = {
589
    &paramLatTopoOrigin, &paramLongTopoOrigin, &paramHeightTopoOriginWithH0,
590
    nullptr};
591
592
static const MethodMapping gProjectionMethodMappings[] = {
593
    {EPSG_NAME_METHOD_TRANSVERSE_MERCATOR, EPSG_CODE_METHOD_TRANSVERSE_MERCATOR,
594
     "Transverse_Mercator", "tmerc", nullptr, paramsNatOriginScaleK},
595
596
    {EPSG_NAME_METHOD_TRANSVERSE_MERCATOR_3D,
597
     EPSG_CODE_METHOD_TRANSVERSE_MERCATOR_3D, "Transverse_Mercator", "tmerc",
598
     nullptr, paramsNatOriginScaleK},
599
600
    {EPSG_NAME_METHOD_TRANSVERSE_MERCATOR_SOUTH_ORIENTATED,
601
     EPSG_CODE_METHOD_TRANSVERSE_MERCATOR_SOUTH_ORIENTATED,
602
     "Transverse_Mercator_South_Orientated", "tmerc", "axis=wsu",
603
     paramsNatOriginScaleK},
604
605
    {PROJ_WKT2_NAME_METHOD_TWO_POINT_EQUIDISTANT, 0, "Two_Point_Equidistant",
606
     "tpeqd", nullptr, paramsTPEQD},
607
608
    {EPSG_NAME_METHOD_TUNISIA_MINING_GRID, EPSG_CODE_METHOD_TUNISIA_MINING_GRID,
609
     "Tunisia_Mining_Grid", nullptr,
610
     nullptr, // no proj equivalent
611
     paramsTMG},
612
613
    // Deprecated. Use EPSG_NAME_METHOD_TUNISIA_MINING_GRID instead
614
    {EPSG_NAME_METHOD_TUNISIA_MAPPING_GRID,
615
     EPSG_CODE_METHOD_TUNISIA_MAPPING_GRID, "Tunisia_Mapping_Grid", nullptr,
616
     nullptr, // no proj equivalent
617
     paramsTMG},
618
619
    {EPSG_NAME_METHOD_ALBERS_EQUAL_AREA, EPSG_CODE_METHOD_ALBERS_EQUAL_AREA,
620
     "Albers_Conic_Equal_Area", "aea", nullptr, paramsAEA_EQDC},
621
622
    // Variant used by Oracle WKT:
623
    // https://lists.osgeo.org/pipermail/qgis-user/2024-June/054599.html
624
    {EPSG_NAME_METHOD_ALBERS_EQUAL_AREA, EPSG_CODE_METHOD_ALBERS_EQUAL_AREA,
625
     "Albers_Conical_Equal_Area", "aea", nullptr, paramsAEA_EQDC},
626
627
    {EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_1SP,
628
     EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP,
629
     "Lambert_Conformal_Conic_1SP", "lcc", nullptr, paramsLCC1SP},
630
631
    {EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_1SP_VARIANT_B,
632
     EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP_VARIANT_B,
633
     nullptr, // no mapping to WKT1_GDAL
634
     "lcc", nullptr, paramsLCC1SPVariantB},
635
636
    {EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_2SP,
637
     EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP,
638
     "Lambert_Conformal_Conic_2SP", "lcc", nullptr, paramsLCC2SP},
639
640
    {EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_MICHIGAN,
641
     EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_MICHIGAN,
642
     nullptr, // no mapping to WKT1_GDAL
643
     "lcc", nullptr, paramsLCC2SPMichigan},
644
645
    {EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_BELGIUM,
646
     EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_BELGIUM,
647
     "Lambert_Conformal_Conic_2SP_Belgium", "lcc",
648
     nullptr, // FIXME: this is what is done in GDAL, but the formula of
649
              // LCC 2SP
650
     // Belgium in the EPSG 7.2 guidance is difference from the regular
651
     // LCC 2SP
652
     paramsLCC2SP},
653
654
    {EPSG_NAME_METHOD_AZIMUTHAL_EQUIDISTANT,
655
     EPSG_CODE_METHOD_AZIMUTHAL_EQUIDISTANT, "Azimuthal_Equidistant", "aeqd",
656
     nullptr, paramsAEQD},
657
658
    // We don't actually implement the Modified variant of Azimuthal Equidistant
659
    // but the exact one. The difference between both is neglectable in a few
660
    // hundred of kilometers away from the center of projection
661
    {EPSG_NAME_METHOD_MODIFIED_AZIMUTHAL_EQUIDISTANT,
662
     EPSG_CODE_METHOD_MODIFIED_AZIMUTHAL_EQUIDISTANT, "Azimuthal_Equidistant",
663
     "aeqd", nullptr, paramsAEQD},
664
665
    {EPSG_NAME_METHOD_GUAM_PROJECTION, EPSG_CODE_METHOD_GUAM_PROJECTION,
666
     nullptr, // no mapping to GDAL WKT1
667
     "aeqd", "guam", paramsNatOrigin},
668
669
    {EPSG_NAME_METHOD_BONNE, EPSG_CODE_METHOD_BONNE, "Bonne", "bonne", nullptr,
670
     paramsBonne},
671
672
    {PROJ_WKT2_NAME_METHOD_COMPACT_MILLER, 0, "Compact_Miller", "comill",
673
     nullptr, paramsLongNatOrigin},
674
675
    {EPSG_NAME_METHOD_LAMBERT_CYLINDRICAL_EQUAL_AREA,
676
     EPSG_CODE_METHOD_LAMBERT_CYLINDRICAL_EQUAL_AREA, "Cylindrical_Equal_Area",
677
     "cea", nullptr, paramsCEA},
678
679
    {EPSG_NAME_METHOD_LAMBERT_CYLINDRICAL_EQUAL_AREA_SPHERICAL,
680
     EPSG_CODE_METHOD_LAMBERT_CYLINDRICAL_EQUAL_AREA_SPHERICAL,
681
     "Cylindrical_Equal_Area", "cea", "R_A", paramsCEA},
682
683
    {EPSG_NAME_METHOD_CASSINI_SOLDNER, EPSG_CODE_METHOD_CASSINI_SOLDNER,
684
     "Cassini_Soldner", "cass", nullptr, paramsNatOrigin},
685
686
    {EPSG_NAME_METHOD_HYPERBOLIC_CASSINI_SOLDNER,
687
     EPSG_CODE_METHOD_HYPERBOLIC_CASSINI_SOLDNER, nullptr, "cass", "hyperbolic",
688
     paramsNatOrigin},
689
690
    // Definition to be put before PROJ_WKT2_NAME_METHOD_EQUIDISTANT_CONIC
691
    {EPSG_NAME_METHOD_EQUIDISTANT_CONIC, EPSG_CODE_METHOD_EQUIDISTANT_CONIC,
692
     "Equidistant_Conic", "eqdc", nullptr, paramsAEA_EQDC},
693
694
    // Definition before EPSG codified it. To be put after entry for
695
    // EPSG_NAME_METHOD_EQUIDISTANT_CONIC
696
    {PROJ_WKT2_NAME_METHOD_EQUIDISTANT_CONIC, 0, "Equidistant_Conic", "eqdc",
697
     nullptr, paramsEQDC},
698
699
    {PROJ_WKT2_NAME_METHOD_ECKERT_I, 0, "Eckert_I", "eck1", nullptr,
700
     paramsLongNatOrigin},
701
702
    {PROJ_WKT2_NAME_METHOD_ECKERT_II, 0, "Eckert_II", "eck2", nullptr,
703
     paramsLongNatOrigin},
704
705
    {PROJ_WKT2_NAME_METHOD_ECKERT_III, 0, "Eckert_III", "eck3", nullptr,
706
     paramsLongNatOrigin},
707
708
    {PROJ_WKT2_NAME_METHOD_ECKERT_IV, 0, "Eckert_IV", "eck4", nullptr,
709
     paramsLongNatOrigin},
710
711
    {PROJ_WKT2_NAME_METHOD_ECKERT_V, 0, "Eckert_V", "eck5", nullptr,
712
     paramsLongNatOrigin},
713
714
    {PROJ_WKT2_NAME_METHOD_ECKERT_VI, 0, "Eckert_VI", "eck6", nullptr,
715
     paramsLongNatOrigin},
716
717
    {EPSG_NAME_METHOD_EQUIDISTANT_CYLINDRICAL,
718
     EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL, "Equirectangular", "eqc",
719
     nullptr, paramsEqc},
720
721
    {EPSG_NAME_METHOD_EQUIDISTANT_CYLINDRICAL_SPHERICAL,
722
     EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL_SPHERICAL, "Equirectangular",
723
     "eqc", nullptr, paramsEqc},
724
725
    {PROJ_WKT2_NAME_METHOD_FLAT_POLAR_QUARTIC, 0, "Flat_Polar_Quartic",
726
     "mbtfpq", nullptr, paramsLongNatOrigin},
727
728
    {PROJ_WKT2_NAME_METHOD_GALL_STEREOGRAPHIC, 0, "Gall_Stereographic", "gall",
729
     nullptr, paramsLongNatOrigin},
730
731
    {PROJ_WKT2_NAME_METHOD_GOODE_HOMOLOSINE, 0, "Goode_Homolosine", "goode",
732
     nullptr, paramsLongNatOrigin},
733
734
    {PROJ_WKT2_NAME_METHOD_INTERRUPTED_GOODE_HOMOLOSINE, 0,
735
     "Interrupted_Goode_Homolosine", "igh", nullptr, paramsLongNatOrigin},
736
737
    {PROJ_WKT2_NAME_METHOD_INTERRUPTED_GOODE_HOMOLOSINE_OCEAN, 0, nullptr,
738
     "igh_o", nullptr, paramsLongNatOrigin},
739
740
    // No proper WKT1 representation fr sweep=x
741
    {PROJ_WKT2_NAME_METHOD_GEOSTATIONARY_SATELLITE_SWEEP_X, 0, nullptr, "geos",
742
     "sweep=x", paramsGeos},
743
744
    {PROJ_WKT2_NAME_METHOD_GEOSTATIONARY_SATELLITE_SWEEP_Y, 0,
745
     "Geostationary_Satellite", "geos", nullptr, paramsGeos},
746
747
    {PROJ_WKT2_NAME_METHOD_GAUSS_SCHREIBER_TRANSVERSE_MERCATOR, 0,
748
     "Gauss_Schreiber_Transverse_Mercator", "gstmerc", nullptr,
749
     paramsNatOriginScale},
750
751
    {PROJ_WKT2_NAME_METHOD_GNOMONIC, 0, "Gnomonic", "gnom", nullptr,
752
     paramsNatOrigin},
753
754
    {EPSG_NAME_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_A,
755
     EPSG_CODE_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_A,
756
     "Hotine_Oblique_Mercator", "omerc", "no_uoff", paramsHomVariantA},
757
758
    {EPSG_NAME_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_B,
759
     EPSG_CODE_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_B,
760
     "Hotine_Oblique_Mercator_Azimuth_Center", "omerc", nullptr,
761
     paramsHomVariantB},
762
763
    {PROJ_WKT2_NAME_METHOD_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN, 0,
764
     "Hotine_Oblique_Mercator_Two_Point_Natural_Origin", "omerc", nullptr,
765
     paramsHomTwoPoint},
766
767
    {PROJ_WKT2_NAME_INTERNATIONAL_MAP_WORLD_POLYCONIC, 0,
768
     "International_Map_of_the_World_Polyconic", "imw_p", nullptr, paramsIMWP},
769
770
    {EPSG_NAME_METHOD_KROVAK_NORTH_ORIENTED,
771
     EPSG_CODE_METHOD_KROVAK_NORTH_ORIENTED, "Krovak", "krovak", nullptr,
772
     krovakParameters},
773
774
    {EPSG_NAME_METHOD_KROVAK, EPSG_CODE_METHOD_KROVAK, "Krovak", "krovak",
775
     "axis=swu", krovakParameters},
776
777
    {EPSG_NAME_METHOD_KROVAK_MODIFIED_NORTH_ORIENTED,
778
     EPSG_CODE_METHOD_KROVAK_MODIFIED_NORTH_ORIENTED, nullptr, "mod_krovak",
779
     nullptr, krovakParameters},
780
781
    {EPSG_NAME_METHOD_KROVAK_MODIFIED, EPSG_CODE_METHOD_KROVAK_MODIFIED,
782
     nullptr, "mod_krovak", "axis=swu", krovakParameters},
783
784
    {EPSG_NAME_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA,
785
     EPSG_CODE_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA,
786
     "Lambert_Azimuthal_Equal_Area", "laea", nullptr, paramsLaea},
787
788
    {EPSG_NAME_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA_SPHERICAL,
789
     EPSG_CODE_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA_SPHERICAL,
790
     "Lambert_Azimuthal_Equal_Area", "laea", "R_A", paramsLaea},
791
792
    {PROJ_WKT2_NAME_METHOD_MILLER_CYLINDRICAL, 0, "Miller_Cylindrical", "mill",
793
     "R_A", paramsMiller},
794
795
    {EPSG_NAME_METHOD_MERCATOR_VARIANT_A, EPSG_CODE_METHOD_MERCATOR_VARIANT_A,
796
     "Mercator_1SP", "merc", nullptr, paramsMerc1SP},
797
798
    {EPSG_NAME_METHOD_MERCATOR_VARIANT_B, EPSG_CODE_METHOD_MERCATOR_VARIANT_B,
799
     "Mercator_2SP", "merc", nullptr, paramsMerc2SP},
800
801
    {EPSG_NAME_METHOD_POPULAR_VISUALISATION_PSEUDO_MERCATOR,
802
     EPSG_CODE_METHOD_POPULAR_VISUALISATION_PSEUDO_MERCATOR,
803
     "Popular_Visualisation_Pseudo_Mercator", // particular case actually
804
                                              // handled manually
805
     "webmerc", nullptr, paramsNatOrigin},
806
807
    {EPSG_NAME_METHOD_MERCATOR_SPHERICAL, EPSG_CODE_METHOD_MERCATOR_SPHERICAL,
808
     nullptr, "merc", "R_C", paramsNatOrigin},
809
810
    {PROJ_WKT2_NAME_METHOD_MOLLWEIDE, 0, "Mollweide", "moll", nullptr,
811
     paramsLongNatOrigin},
812
813
    {PROJ_WKT2_NAME_METHOD_NATURAL_EARTH, 0, "Natural_Earth", "natearth",
814
     nullptr, paramsLongNatOrigin},
815
816
    {PROJ_WKT2_NAME_METHOD_NATURAL_EARTH_II, 0, "Natural_Earth_II", "natearth2",
817
     nullptr, paramsLongNatOrigin},
818
819
    {EPSG_NAME_METHOD_NZMG, EPSG_CODE_METHOD_NZMG, "New_Zealand_Map_Grid",
820
     "nzmg", nullptr, paramsNatOrigin},
821
822
    {
823
        EPSG_NAME_METHOD_OBLIQUE_STEREOGRAPHIC,
824
        EPSG_CODE_METHOD_OBLIQUE_STEREOGRAPHIC,
825
        "Oblique_Stereographic",
826
        "sterea",
827
        nullptr,
828
        paramsObliqueStereo,
829
    },
830
831
    {EPSG_NAME_METHOD_ORTHOGRAPHIC, EPSG_CODE_METHOD_ORTHOGRAPHIC,
832
     "Orthographic", "ortho", nullptr, paramsNatOrigin},
833
834
    {EPSG_NAME_METHOD_LOCAL_ORTHOGRAPHIC, EPSG_CODE_METHOD_LOCAL_ORTHOGRAPHIC,
835
     "Local Orthographic", "ortho", nullptr, paramsLocalOrthographic},
836
837
    {PROJ_WKT2_NAME_ORTHOGRAPHIC_SPHERICAL, 0, "Orthographic", "ortho", "f=0",
838
     paramsNatOrigin},
839
840
    {PROJ_WKT2_NAME_METHOD_PATTERSON, 0, "Patterson", "patterson", nullptr,
841
     paramsLongNatOrigin},
842
843
    {EPSG_NAME_METHOD_AMERICAN_POLYCONIC, EPSG_CODE_METHOD_AMERICAN_POLYCONIC,
844
     "Polyconic", "poly", nullptr, paramsNatOrigin},
845
846
    {EPSG_NAME_METHOD_POLAR_STEREOGRAPHIC_VARIANT_A,
847
     EPSG_CODE_METHOD_POLAR_STEREOGRAPHIC_VARIANT_A, "Polar_Stereographic",
848
     "stere", nullptr, paramsObliqueStereo},
849
850
    {EPSG_NAME_METHOD_POLAR_STEREOGRAPHIC_VARIANT_B,
851
     EPSG_CODE_METHOD_POLAR_STEREOGRAPHIC_VARIANT_B, "Polar_Stereographic",
852
     "stere", nullptr, paramsPolarStereo},
853
854
    {PROJ_WKT2_NAME_METHOD_ROBINSON, 0, "Robinson", "robin", nullptr,
855
     paramsLongNatOriginLongitudeCentre},
856
857
    {PROJ_WKT2_NAME_METHOD_PEIRCE_QUINCUNCIAL_SQUARE, 0, nullptr, "peirce_q",
858
     "shape=square", paramsNatOriginScale},
859
860
    {PROJ_WKT2_NAME_METHOD_PEIRCE_QUINCUNCIAL_DIAMOND, 0, nullptr, "peirce_q",
861
     "shape=diamond", paramsNatOriginScale},
862
863
    {PROJ_WKT2_NAME_METHOD_SINUSOIDAL, 0, "Sinusoidal", "sinu", nullptr,
864
     paramsLongNatOriginLongitudeCentre},
865
866
    {PROJ_WKT2_NAME_METHOD_STEREOGRAPHIC, 0, "Stereographic", "stere", nullptr,
867
     paramsObliqueStereo},
868
869
    {PROJ_WKT2_NAME_METHOD_TIMES, 0, "Times", "times", nullptr,
870
     paramsLongNatOrigin},
871
872
    {PROJ_WKT2_NAME_METHOD_VAN_DER_GRINTEN, 0, "VanDerGrinten", "vandg", "R_A",
873
     paramsLongNatOrigin},
874
875
    {PROJ_WKT2_NAME_METHOD_WAGNER_I, 0, "Wagner_I", "wag1", nullptr,
876
     paramsLongNatOrigin},
877
878
    {PROJ_WKT2_NAME_METHOD_WAGNER_II, 0, "Wagner_II", "wag2", nullptr,
879
     paramsLongNatOrigin},
880
881
    {PROJ_WKT2_NAME_METHOD_WAGNER_III, 0, "Wagner_III", "wag3", nullptr,
882
     paramsWag3},
883
884
    {PROJ_WKT2_NAME_METHOD_WAGNER_IV, 0, "Wagner_IV", "wag4", nullptr,
885
     paramsLongNatOrigin},
886
887
    {PROJ_WKT2_NAME_METHOD_WAGNER_V, 0, "Wagner_V", "wag5", nullptr,
888
     paramsLongNatOrigin},
889
890
    {PROJ_WKT2_NAME_METHOD_WAGNER_VI, 0, "Wagner_VI", "wag6", nullptr,
891
     paramsLongNatOrigin},
892
893
    {PROJ_WKT2_NAME_METHOD_WAGNER_VII, 0, "Wagner_VII", "wag7", nullptr,
894
     paramsLongNatOrigin},
895
896
    {PROJ_WKT2_NAME_METHOD_QUADRILATERALIZED_SPHERICAL_CUBE, 0,
897
     "Quadrilateralized_Spherical_Cube", "qsc", nullptr, paramsNatOrigin},
898
899
    {PROJ_WKT2_NAME_METHOD_SPHERICAL_CROSS_TRACK_HEIGHT, 0,
900
     "Spherical_Cross_Track_Height", "sch", nullptr, paramsSch},
901
902
    // The following methods have just the WKT <--> PROJ string mapping, but
903
    // no setter. Similarly to GDAL
904
905
    {"Aitoff", 0, "Aitoff", "aitoff", nullptr, paramsLongNatOrigin},
906
907
    {"Winkel I", 0, "Winkel_I", "wink1", nullptr, paramsWink1},
908
909
    {"Winkel II", 0, "Winkel_II", "wink2", nullptr, paramsWink2},
910
911
    {"Winkel Tripel", 0, "Winkel_Tripel", "wintri", nullptr, paramsWink2},
912
913
    {"Craster Parabolic", 0, "Craster_Parabolic", "crast", nullptr,
914
     paramsLongNatOrigin},
915
916
    {"Loximuthal", 0, "Loximuthal", "loxim", nullptr, paramsLoxim},
917
918
    {"Quartic Authalic", 0, "Quartic_Authalic", "qua_aut", nullptr,
919
     paramsLongNatOrigin},
920
921
    {"Transverse Cylindrical Equal Area", 0,
922
     "Transverse_Cylindrical_Equal_Area", "tcea", nullptr, paramsObliqueStereo},
923
924
    {EPSG_NAME_METHOD_EQUAL_EARTH, EPSG_CODE_METHOD_EQUAL_EARTH, nullptr,
925
     "eqearth", nullptr, paramsLongNatOrigin},
926
927
    {EPSG_NAME_METHOD_LABORDE_OBLIQUE_MERCATOR,
928
     EPSG_CODE_METHOD_LABORDE_OBLIQUE_MERCATOR, "Laborde_Oblique_Mercator",
929
     "labrd", nullptr, paramsLabordeObliqueMercator},
930
931
    {EPSG_NAME_METHOD_VERTICAL_PERSPECTIVE,
932
     EPSG_CODE_METHOD_VERTICAL_PERSPECTIVE, nullptr, "nsper", nullptr,
933
     paramsVerticalPerspective},
934
935
    {EPSG_NAME_METHOD_COLOMBIA_URBAN, EPSG_CODE_METHOD_COLOMBIA_URBAN, nullptr,
936
     "col_urban", nullptr, paramsColombiaUrban},
937
938
    {EPSG_NAME_METHOD_GEOCENTRIC_TOPOCENTRIC,
939
     EPSG_CODE_METHOD_GEOCENTRIC_TOPOCENTRIC, nullptr, "topocentric", nullptr,
940
     paramsGeocentricTopocentric},
941
942
    {EPSG_NAME_METHOD_GEOGRAPHIC_TOPOCENTRIC,
943
     EPSG_CODE_METHOD_GEOGRAPHIC_TOPOCENTRIC, nullptr, nullptr, nullptr,
944
     paramsGeographicTopocentric},
945
};
946
947
0
const MethodMapping *getProjectionMethodMappings(size_t &nElts) {
948
0
    nElts = sizeof(gProjectionMethodMappings) /
949
0
            sizeof(gProjectionMethodMappings[0]);
950
0
    return gProjectionMethodMappings;
951
0
}
952
953
#define METHOD_NAME_CODE(method)                                               \
954
    { EPSG_NAME_METHOD_##method, EPSG_CODE_METHOD_##method }
955
956
const struct MethodNameCode methodNameCodesList[] = {
957
    // Projection methods
958
    METHOD_NAME_CODE(TRANSVERSE_MERCATOR),
959
    METHOD_NAME_CODE(TRANSVERSE_MERCATOR_SOUTH_ORIENTATED),
960
    METHOD_NAME_CODE(LAMBERT_CONIC_CONFORMAL_1SP),
961
    METHOD_NAME_CODE(NZMG),
962
    METHOD_NAME_CODE(TUNISIA_MINING_GRID),
963
    METHOD_NAME_CODE(ALBERS_EQUAL_AREA),
964
    METHOD_NAME_CODE(LAMBERT_CONIC_CONFORMAL_2SP),
965
    METHOD_NAME_CODE(LAMBERT_CONIC_CONFORMAL_2SP_BELGIUM),
966
    METHOD_NAME_CODE(LAMBERT_CONIC_CONFORMAL_2SP_MICHIGAN),
967
    METHOD_NAME_CODE(MODIFIED_AZIMUTHAL_EQUIDISTANT),
968
    METHOD_NAME_CODE(GUAM_PROJECTION),
969
    METHOD_NAME_CODE(BONNE),
970
    METHOD_NAME_CODE(LAMBERT_CYLINDRICAL_EQUAL_AREA_SPHERICAL),
971
    METHOD_NAME_CODE(LAMBERT_CYLINDRICAL_EQUAL_AREA),
972
    METHOD_NAME_CODE(CASSINI_SOLDNER),
973
    METHOD_NAME_CODE(EQUIDISTANT_CYLINDRICAL),
974
    METHOD_NAME_CODE(EQUIDISTANT_CYLINDRICAL_SPHERICAL),
975
    METHOD_NAME_CODE(HOTINE_OBLIQUE_MERCATOR_VARIANT_A),
976
    METHOD_NAME_CODE(HOTINE_OBLIQUE_MERCATOR_VARIANT_B),
977
    METHOD_NAME_CODE(KROVAK_NORTH_ORIENTED),
978
    METHOD_NAME_CODE(KROVAK),
979
    METHOD_NAME_CODE(LAMBERT_AZIMUTHAL_EQUAL_AREA),
980
    METHOD_NAME_CODE(POPULAR_VISUALISATION_PSEUDO_MERCATOR),
981
    METHOD_NAME_CODE(MERCATOR_SPHERICAL),
982
    METHOD_NAME_CODE(MERCATOR_VARIANT_A),
983
    METHOD_NAME_CODE(MERCATOR_VARIANT_B),
984
    METHOD_NAME_CODE(OBLIQUE_STEREOGRAPHIC),
985
    METHOD_NAME_CODE(AMERICAN_POLYCONIC),
986
    METHOD_NAME_CODE(POLAR_STEREOGRAPHIC_VARIANT_A),
987
    METHOD_NAME_CODE(POLAR_STEREOGRAPHIC_VARIANT_B),
988
    METHOD_NAME_CODE(EQUAL_EARTH),
989
    METHOD_NAME_CODE(LABORDE_OBLIQUE_MERCATOR),
990
    METHOD_NAME_CODE(VERTICAL_PERSPECTIVE),
991
    METHOD_NAME_CODE(COLOMBIA_URBAN),
992
    // Other conversions
993
    METHOD_NAME_CODE(CHANGE_VERTICAL_UNIT),
994
    METHOD_NAME_CODE(CHANGE_VERTICAL_UNIT_NO_CONV_FACTOR),
995
    METHOD_NAME_CODE(HEIGHT_DEPTH_REVERSAL),
996
    METHOD_NAME_CODE(AXIS_ORDER_REVERSAL_2D),
997
    METHOD_NAME_CODE(AXIS_ORDER_REVERSAL_3D),
998
    METHOD_NAME_CODE(GEOGRAPHIC_GEOCENTRIC),
999
    METHOD_NAME_CODE(GEOCENTRIC_TOPOCENTRIC),
1000
    METHOD_NAME_CODE(GEOGRAPHIC_TOPOCENTRIC),
1001
    // Transformations
1002
    METHOD_NAME_CODE(LONGITUDE_ROTATION),
1003
    METHOD_NAME_CODE(AFFINE_PARAMETRIC_TRANSFORMATION),
1004
    METHOD_NAME_CODE(SIMILARITY_TRANSFORMATION),
1005
    METHOD_NAME_CODE(COORDINATE_FRAME_GEOCENTRIC),
1006
    METHOD_NAME_CODE(COORDINATE_FRAME_FULL_MATRIX_GEOCENTRIC),
1007
    METHOD_NAME_CODE(COORDINATE_FRAME_GEOGRAPHIC_2D),
1008
    METHOD_NAME_CODE(COORDINATE_FRAME_FULL_MATRIX_GEOGRAPHIC_2D),
1009
    METHOD_NAME_CODE(COORDINATE_FRAME_GEOGRAPHIC_3D),
1010
    METHOD_NAME_CODE(COORDINATE_FRAME_FULL_MATRIX_GEOGRAPHIC_3D),
1011
    METHOD_NAME_CODE(COORDINATE_FRAME_GEOG3D_TO_COMPOUND),
1012
    METHOD_NAME_CODE(POSITION_VECTOR_GEOCENTRIC),
1013
    METHOD_NAME_CODE(POSITION_VECTOR_GEOGRAPHIC_2D),
1014
    METHOD_NAME_CODE(POSITION_VECTOR_GEOGRAPHIC_3D),
1015
    METHOD_NAME_CODE(GEOCENTRIC_TRANSLATION_GEOCENTRIC),
1016
    METHOD_NAME_CODE(GEOCENTRIC_TRANSLATION_GEOGRAPHIC_2D),
1017
    METHOD_NAME_CODE(GEOCENTRIC_TRANSLATION_GEOGRAPHIC_3D),
1018
    METHOD_NAME_CODE(TIME_DEPENDENT_COORDINATE_FRAME_GEOCENTRIC),
1019
    METHOD_NAME_CODE(TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_2D),
1020
    METHOD_NAME_CODE(TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_3D),
1021
    METHOD_NAME_CODE(TIME_DEPENDENT_POSITION_VECTOR_GEOCENTRIC),
1022
    METHOD_NAME_CODE(TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_2D),
1023
    METHOD_NAME_CODE(TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_3D),
1024
    METHOD_NAME_CODE(MOLODENSKY_BADEKAS_CF_GEOCENTRIC),
1025
    METHOD_NAME_CODE(MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_2D),
1026
    METHOD_NAME_CODE(MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_3D),
1027
    METHOD_NAME_CODE(MOLODENSKY_BADEKAS_PV_GEOCENTRIC),
1028
    METHOD_NAME_CODE(MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_2D),
1029
    METHOD_NAME_CODE(MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_3D),
1030
    METHOD_NAME_CODE(MOLODENSKY),
1031
    METHOD_NAME_CODE(ABRIDGED_MOLODENSKY),
1032
    METHOD_NAME_CODE(GEOGRAPHIC2D_OFFSETS),
1033
    METHOD_NAME_CODE(GEOGRAPHIC2D_WITH_HEIGHT_OFFSETS),
1034
    METHOD_NAME_CODE(GEOGRAPHIC3D_OFFSETS),
1035
    METHOD_NAME_CODE(CARTESIAN_GRID_OFFSETS),
1036
    METHOD_NAME_CODE(VERTICAL_OFFSET),
1037
    METHOD_NAME_CODE(VERTICAL_OFFSET_AND_SLOPE),
1038
    METHOD_NAME_CODE(NTV2),
1039
    METHOD_NAME_CODE(NTV1),
1040
    METHOD_NAME_CODE(VERTICAL_OFFSET_BY_TIN_INTERPOLATION_JSON),
1041
    METHOD_NAME_CODE(CARTESIAN_GRID_OFFSETS_BY_TIN_INTERPOLATION_JSON),
1042
    METHOD_NAME_CODE(GEOGRAPHIC2D_OFFSETS_BY_TIN_INTERPOLATION_JSON),
1043
    METHOD_NAME_CODE(NADCON),
1044
    METHOD_NAME_CODE(NADCON5_2D),
1045
    METHOD_NAME_CODE(NADCON5_3D),
1046
    METHOD_NAME_CODE(VERTCON),
1047
    // Since EPSG 12.019
1048
    METHOD_NAME_CODE(GEOCENTRIC_TRANSLATIONS_GEOG2D_DOMAIN_BY_GRID_IGN),
1049
    // Before EPSG 12.019
1050
    METHOD_NAME_CODE(GEOCENTRIC_TRANSLATION_BY_GRID_INTERPOLATION_IGN),
1051
    METHOD_NAME_CODE(VERTICALGRID_NZLVD),
1052
    METHOD_NAME_CODE(VERTICALGRID_BEV_AT),
1053
    METHOD_NAME_CODE(VERTICALGRID_GTX),
1054
    METHOD_NAME_CODE(VERTICALGRID_ASC),
1055
    METHOD_NAME_CODE(VERTICALGRID_GTG),
1056
    METHOD_NAME_CODE(VERTICALGRID_PL_TXT),
1057
    // Since EPSG 12.019
1058
    METHOD_NAME_CODE(VERTICAL_OFFSET_USING_NEU_VELOCITY_GRID_NTV2_VEL),
1059
    // Before EPSG 12.019
1060
    METHOD_NAME_CODE(VERTICAL_OFFSET_BY_VELOCITY_GRID_NRCAN),
1061
    // PointMotionOperation
1062
    METHOD_NAME_CODE(POINT_MOTION_BY_GRID_CANADA_NTV2_VEL),
1063
    // Since EPSG 12.019
1064
    METHOD_NAME_CODE(POINT_MOTION_BY_GRID_CANADA_NEU_DOMAIN_NTV2_VEL),
1065
    // Before EPSG 12.019
1066
    METHOD_NAME_CODE(
1067
        POINT_MOTION_GEOG3D_DOMAIN_USING_NEU_VELOCITY_GRID_NTV2_VEL),
1068
    METHOD_NAME_CODE(
1069
        POINT_MOTION_GEOCEN_DOMAIN_USING_NEU_VELOCITY_GRID_GRAVSOFT),
1070
    METHOD_NAME_CODE(
1071
        POSITION_VECTOR_GEOCENTRIC_AND_GEOCENTRIC_TRANSLATIONS_NEU_VELOCITIES_GTG),
1072
    METHOD_NAME_CODE(
1073
        GEOCENTRIC_TRANSLATIONS_BY_GRID_GTG_AND_GEOCENTRIC_TRANSLATIONS_NEU_VELOCITIES_GTG),
1074
    METHOD_NAME_CODE(GEOCENTRIC_TRANSLATIONS_USING_NEU_VELOCITY_GRID_GTG),
1075
};
1076
1077
1.97M
const MethodNameCode *getMethodNameCodes(size_t &nElts) {
1078
1.97M
    nElts = sizeof(methodNameCodesList) / sizeof(methodNameCodesList[0]);
1079
1.97M
    return methodNameCodesList;
1080
1.97M
}
1081
1082
#define PARAM_NAME_CODE(method)                                                \
1083
    { EPSG_NAME_PARAMETER_##method, EPSG_CODE_PARAMETER_##method }
1084
1085
const struct ParamNameCode gParamNameCodes[] = {
1086
    // Parameters of projection methods
1087
    PARAM_NAME_CODE(COLATITUDE_CONE_AXIS),
1088
    PARAM_NAME_CODE(LATITUDE_OF_NATURAL_ORIGIN),
1089
    PARAM_NAME_CODE(LONGITUDE_OF_NATURAL_ORIGIN),
1090
    PARAM_NAME_CODE(SCALE_FACTOR_AT_NATURAL_ORIGIN),
1091
    PARAM_NAME_CODE(FALSE_EASTING),
1092
    PARAM_NAME_CODE(FALSE_NORTHING),
1093
    PARAM_NAME_CODE(LATITUDE_PROJECTION_CENTRE),
1094
    PARAM_NAME_CODE(LONGITUDE_PROJECTION_CENTRE),
1095
    PARAM_NAME_CODE(AZIMUTH_PROJECTION_CENTRE),
1096
    PARAM_NAME_CODE(ANGLE_RECTIFIED_TO_SKEW_GRID),
1097
    PARAM_NAME_CODE(SCALE_FACTOR_PROJECTION_CENTRE),
1098
    PARAM_NAME_CODE(EASTING_PROJECTION_CENTRE),
1099
    PARAM_NAME_CODE(NORTHING_PROJECTION_CENTRE),
1100
    PARAM_NAME_CODE(LATITUDE_PSEUDO_STANDARD_PARALLEL),
1101
    PARAM_NAME_CODE(SCALE_FACTOR_PSEUDO_STANDARD_PARALLEL),
1102
    PARAM_NAME_CODE(LATITUDE_FALSE_ORIGIN),
1103
    PARAM_NAME_CODE(LONGITUDE_FALSE_ORIGIN),
1104
    PARAM_NAME_CODE(LATITUDE_1ST_STD_PARALLEL),
1105
    PARAM_NAME_CODE(LATITUDE_2ND_STD_PARALLEL),
1106
    PARAM_NAME_CODE(EASTING_FALSE_ORIGIN),
1107
    PARAM_NAME_CODE(NORTHING_FALSE_ORIGIN),
1108
    PARAM_NAME_CODE(LATITUDE_STD_PARALLEL),
1109
    PARAM_NAME_CODE(LONGITUDE_OF_ORIGIN),
1110
    PARAM_NAME_CODE(ELLIPSOID_SCALE_FACTOR),
1111
    PARAM_NAME_CODE(PROJECTION_PLANE_ORIGIN_HEIGHT),
1112
    PARAM_NAME_CODE(GEOCENTRIC_X_TOPOCENTRIC_ORIGIN),
1113
    PARAM_NAME_CODE(GEOCENTRIC_Y_TOPOCENTRIC_ORIGIN),
1114
    PARAM_NAME_CODE(GEOCENTRIC_Z_TOPOCENTRIC_ORIGIN),
1115
    // Parameters of transformations
1116
    PARAM_NAME_CODE(SEMI_MAJOR_AXIS_DIFFERENCE),
1117
    PARAM_NAME_CODE(FLATTENING_DIFFERENCE),
1118
    PARAM_NAME_CODE(LATITUDE_LONGITUDE_DIFFERENCE_FILE),
1119
    PARAM_NAME_CODE(GEOID_CORRECTION_FILENAME),
1120
    PARAM_NAME_CODE(VERTICAL_OFFSET_FILE),
1121
    PARAM_NAME_CODE(GEOID_MODEL_DIFFERENCE_FILE),
1122
    PARAM_NAME_CODE(LATITUDE_DIFFERENCE_FILE),
1123
    PARAM_NAME_CODE(LONGITUDE_DIFFERENCE_FILE),
1124
    PARAM_NAME_CODE(UNIT_CONVERSION_SCALAR),
1125
    PARAM_NAME_CODE(LATITUDE_OFFSET),
1126
    PARAM_NAME_CODE(LONGITUDE_OFFSET),
1127
    PARAM_NAME_CODE(VERTICAL_OFFSET),
1128
    PARAM_NAME_CODE(EASTING_OFFSET),
1129
    PARAM_NAME_CODE(NORTHING_OFFSET),
1130
    PARAM_NAME_CODE(GEOID_HEIGHT),
1131
    PARAM_NAME_CODE(GEOID_UNDULATION), // deprecated
1132
    PARAM_NAME_CODE(A0),
1133
    PARAM_NAME_CODE(A1),
1134
    PARAM_NAME_CODE(A2),
1135
    PARAM_NAME_CODE(B0),
1136
    PARAM_NAME_CODE(B1),
1137
    PARAM_NAME_CODE(B2),
1138
    PARAM_NAME_CODE(X_AXIS_TRANSLATION),
1139
    PARAM_NAME_CODE(Y_AXIS_TRANSLATION),
1140
    PARAM_NAME_CODE(Z_AXIS_TRANSLATION),
1141
    PARAM_NAME_CODE(X_AXIS_ROTATION),
1142
    PARAM_NAME_CODE(Y_AXIS_ROTATION),
1143
    PARAM_NAME_CODE(Z_AXIS_ROTATION),
1144
    PARAM_NAME_CODE(SCALE_DIFFERENCE),
1145
    PARAM_NAME_CODE(RATE_X_AXIS_TRANSLATION),
1146
    PARAM_NAME_CODE(RATE_Y_AXIS_TRANSLATION),
1147
    PARAM_NAME_CODE(RATE_Z_AXIS_TRANSLATION),
1148
    PARAM_NAME_CODE(RATE_X_AXIS_ROTATION),
1149
    PARAM_NAME_CODE(RATE_Y_AXIS_ROTATION),
1150
    PARAM_NAME_CODE(RATE_Z_AXIS_ROTATION),
1151
    PARAM_NAME_CODE(RATE_SCALE_DIFFERENCE),
1152
    PARAM_NAME_CODE(REFERENCE_EPOCH),
1153
    PARAM_NAME_CODE(TRANSFORMATION_REFERENCE_EPOCH),
1154
    PARAM_NAME_CODE(ORDINATE_1_EVAL_POINT),
1155
    PARAM_NAME_CODE(ORDINATE_2_EVAL_POINT),
1156
    PARAM_NAME_CODE(ORDINATE_3_EVAL_POINT),
1157
    PARAM_NAME_CODE(GEOCENTRIC_TRANSLATION_FILE),
1158
    PARAM_NAME_CODE(INCLINATION_IN_LATITUDE),
1159
    PARAM_NAME_CODE(INCLINATION_IN_LONGITUDE),
1160
    PARAM_NAME_CODE(EPSG_CODE_FOR_HORIZONTAL_CRS),
1161
    PARAM_NAME_CODE(EPSG_CODE_FOR_INTERPOLATION_CRS),
1162
    // Parameters of point motion operations
1163
    PARAM_NAME_CODE(POINT_MOTION_VELOCITY_GRID_FILE),
1164
    PARAM_NAME_CODE(POINT_MOTION_VELOCITY_NORTH_GRID_FILE),
1165
    PARAM_NAME_CODE(SOURCE_EPOCH),
1166
    PARAM_NAME_CODE(TARGET_EPOCH),
1167
};
1168
1169
797k
const ParamNameCode *getParamNameCodes(size_t &nElts) {
1170
797k
    nElts = sizeof(gParamNameCodes) / sizeof(gParamNameCodes[0]);
1171
797k
    return gParamNameCodes;
1172
797k
}
1173
1174
static const ParamMapping paramUnitConversionScalar = {
1175
    EPSG_NAME_PARAMETER_UNIT_CONVERSION_SCALAR,
1176
    EPSG_CODE_PARAMETER_UNIT_CONVERSION_SCALAR, nullptr,
1177
    common::UnitOfMeasure::Type::SCALE, nullptr};
1178
1179
static const ParamMapping *const paramsChangeVerticalUnit[] = {
1180
    &paramUnitConversionScalar, nullptr};
1181
1182
static const ParamMapping paramLongitudeOffset = {
1183
    EPSG_NAME_PARAMETER_LONGITUDE_OFFSET, EPSG_CODE_PARAMETER_LONGITUDE_OFFSET,
1184
    nullptr, common::UnitOfMeasure::Type::ANGULAR, nullptr};
1185
1186
static const ParamMapping *const paramsLongitudeRotation[] = {
1187
    &paramLongitudeOffset, nullptr};
1188
1189
static const ParamMapping paramA0 = {
1190
    EPSG_NAME_PARAMETER_A0, EPSG_CODE_PARAMETER_A0, nullptr,
1191
    common::UnitOfMeasure::Type::UNKNOWN, nullptr};
1192
1193
static const ParamMapping paramA1 = {
1194
    EPSG_NAME_PARAMETER_A1, EPSG_CODE_PARAMETER_A1, nullptr,
1195
    common::UnitOfMeasure::Type::UNKNOWN, nullptr};
1196
1197
static const ParamMapping paramA2 = {
1198
    EPSG_NAME_PARAMETER_A2, EPSG_CODE_PARAMETER_A2, nullptr,
1199
    common::UnitOfMeasure::Type::UNKNOWN, nullptr};
1200
1201
static const ParamMapping paramA3 = {PROJ_WKT2_NAME_PARAMETER_A3, 0, nullptr,
1202
                                     common::UnitOfMeasure::Type::UNKNOWN,
1203
                                     nullptr};
1204
1205
static const ParamMapping paramB0 = {
1206
    EPSG_NAME_PARAMETER_B0, EPSG_CODE_PARAMETER_B0, nullptr,
1207
    common::UnitOfMeasure::Type::UNKNOWN, nullptr};
1208
1209
static const ParamMapping paramB1 = {
1210
    EPSG_NAME_PARAMETER_B1, EPSG_CODE_PARAMETER_B1, nullptr,
1211
    common::UnitOfMeasure::Type::UNKNOWN, nullptr};
1212
1213
static const ParamMapping paramB2 = {
1214
    EPSG_NAME_PARAMETER_B2, EPSG_CODE_PARAMETER_B2, nullptr,
1215
    common::UnitOfMeasure::Type::UNKNOWN, nullptr};
1216
1217
static const ParamMapping paramB3 = {PROJ_WKT2_NAME_PARAMETER_B3, 0, nullptr,
1218
                                     common::UnitOfMeasure::Type::UNKNOWN,
1219
                                     nullptr};
1220
1221
static const ParamMapping paramC0 = {PROJ_WKT2_NAME_PARAMETER_C0, 0, nullptr,
1222
                                     common::UnitOfMeasure::Type::UNKNOWN,
1223
                                     nullptr};
1224
1225
static const ParamMapping paramC1 = {PROJ_WKT2_NAME_PARAMETER_C1, 0, nullptr,
1226
                                     common::UnitOfMeasure::Type::UNKNOWN,
1227
                                     nullptr};
1228
1229
static const ParamMapping paramC2 = {PROJ_WKT2_NAME_PARAMETER_C2, 0, nullptr,
1230
                                     common::UnitOfMeasure::Type::UNKNOWN,
1231
                                     nullptr};
1232
1233
static const ParamMapping paramC3 = {PROJ_WKT2_NAME_PARAMETER_C3, 0, nullptr,
1234
                                     common::UnitOfMeasure::Type::UNKNOWN,
1235
                                     nullptr};
1236
1237
static const ParamMapping *const paramsAffineParametricTransformation[] = {
1238
    &paramA0, &paramA1, &paramA2, &paramB0, &paramB1, &paramB2, nullptr};
1239
1240
static const ParamMapping *const params3DAffineParametricTransformation[] = {
1241
    &paramA0, &paramA1, &paramA2, &paramA3, &paramB0, &paramB1, &paramB2,
1242
    &paramB3, &paramC0, &paramC1, &paramC2, &paramC3, nullptr};
1243
1244
static const ParamMapping paramOrdinate1EvalPointTargetCRS = {
1245
    EPSG_NAME_PARAMETER_ORDINATE_1_EVAL_POINT_TARGET_CRS,
1246
    EPSG_CODE_PARAMETER_ORDINATE_1_EVAL_POINT_TARGET_CRS, nullptr,
1247
    common::UnitOfMeasure::Type::UNKNOWN, nullptr};
1248
1249
static const ParamMapping paramOrdinate2EvalPointTargetCRS = {
1250
    EPSG_NAME_PARAMETER_ORDINATE_2_EVAL_POINT_TARGET_CRS,
1251
    EPSG_CODE_PARAMETER_ORDINATE_2_EVAL_POINT_TARGET_CRS, nullptr,
1252
    common::UnitOfMeasure::Type::UNKNOWN, nullptr};
1253
1254
static const ParamMapping paramScaleFactorForSourceCRSAxes = {
1255
    EPSG_NAME_PARAMETER_SCALE_FACTOR_FOR_SOURCE_CRS_AXES,
1256
    EPSG_CODE_PARAMETER_SCALE_FACTOR_FOR_SOURCE_CRS_AXES, nullptr,
1257
    common::UnitOfMeasure::Type::SCALE, nullptr};
1258
1259
static const ParamMapping paramRotationAngleOfSourceCRSAxes = {
1260
    EPSG_NAME_PARAMETER_ROTATION_ANGLE_OF_SOURCE_CRS_AXES,
1261
    EPSG_CODE_PARAMETER_ROTATION_ANGLE_OF_SOURCE_CRS_AXES, nullptr,
1262
    common::UnitOfMeasure::Type::ANGULAR, nullptr};
1263
1264
static const ParamMapping *const paramsSimilarityTransformation[] = {
1265
    &paramOrdinate1EvalPointTargetCRS, &paramOrdinate2EvalPointTargetCRS,
1266
    &paramScaleFactorForSourceCRSAxes, &paramRotationAngleOfSourceCRSAxes,
1267
    nullptr};
1268
1269
static const ParamMapping paramXTranslation = {
1270
    EPSG_NAME_PARAMETER_X_AXIS_TRANSLATION,
1271
    EPSG_CODE_PARAMETER_X_AXIS_TRANSLATION, nullptr,
1272
    common::UnitOfMeasure::Type::LINEAR, nullptr};
1273
1274
static const ParamMapping paramYTranslation = {
1275
    EPSG_NAME_PARAMETER_Y_AXIS_TRANSLATION,
1276
    EPSG_CODE_PARAMETER_Y_AXIS_TRANSLATION, nullptr,
1277
    common::UnitOfMeasure::Type::LINEAR, nullptr};
1278
1279
static const ParamMapping paramZTranslation = {
1280
    EPSG_NAME_PARAMETER_Z_AXIS_TRANSLATION,
1281
    EPSG_CODE_PARAMETER_Z_AXIS_TRANSLATION, nullptr,
1282
    common::UnitOfMeasure::Type::LINEAR, nullptr};
1283
1284
static const ParamMapping paramXRotation = {
1285
    EPSG_NAME_PARAMETER_X_AXIS_ROTATION, EPSG_CODE_PARAMETER_X_AXIS_ROTATION,
1286
    nullptr, common::UnitOfMeasure::Type::LINEAR, nullptr};
1287
1288
static const ParamMapping paramYRotation = {
1289
    EPSG_NAME_PARAMETER_Y_AXIS_ROTATION, EPSG_CODE_PARAMETER_Y_AXIS_ROTATION,
1290
    nullptr, common::UnitOfMeasure::Type::LINEAR, nullptr};
1291
1292
static const ParamMapping paramZRotation = {
1293
    EPSG_NAME_PARAMETER_Z_AXIS_ROTATION, EPSG_CODE_PARAMETER_Z_AXIS_ROTATION,
1294
    nullptr, common::UnitOfMeasure::Type::LINEAR, nullptr};
1295
1296
static const ParamMapping paramScaleDifference = {
1297
    EPSG_NAME_PARAMETER_SCALE_DIFFERENCE, EPSG_CODE_PARAMETER_SCALE_DIFFERENCE,
1298
    nullptr, common::UnitOfMeasure::Type::SCALE, nullptr};
1299
1300
static const ParamMapping *const paramsHelmert3[] = {
1301
    &paramXTranslation, &paramYTranslation, &paramZTranslation, nullptr};
1302
1303
static const ParamMapping *const paramsHelmert7[] = {
1304
    &paramXTranslation,    &paramYTranslation,
1305
    &paramZTranslation,    &paramXRotation,
1306
    &paramYRotation,       &paramZRotation,
1307
    &paramScaleDifference, nullptr};
1308
1309
static const ParamMapping paramRateXTranslation = {
1310
    EPSG_NAME_PARAMETER_RATE_X_AXIS_TRANSLATION,
1311
    EPSG_CODE_PARAMETER_RATE_X_AXIS_TRANSLATION, nullptr,
1312
    common::UnitOfMeasure::Type::LINEAR, nullptr};
1313
1314
static const ParamMapping paramRateYTranslation = {
1315
    EPSG_NAME_PARAMETER_RATE_Y_AXIS_TRANSLATION,
1316
    EPSG_CODE_PARAMETER_RATE_Y_AXIS_TRANSLATION, nullptr,
1317
    common::UnitOfMeasure::Type::LINEAR, nullptr};
1318
1319
static const ParamMapping paramRateZTranslation = {
1320
    EPSG_NAME_PARAMETER_RATE_Z_AXIS_TRANSLATION,
1321
    EPSG_CODE_PARAMETER_RATE_Z_AXIS_TRANSLATION, nullptr,
1322
    common::UnitOfMeasure::Type::LINEAR, nullptr};
1323
1324
static const ParamMapping paramRateXRotation = {
1325
    EPSG_NAME_PARAMETER_RATE_X_AXIS_ROTATION,
1326
    EPSG_CODE_PARAMETER_RATE_X_AXIS_ROTATION, nullptr,
1327
    common::UnitOfMeasure::Type::LINEAR, nullptr};
1328
1329
static const ParamMapping paramRateYRotation = {
1330
    EPSG_NAME_PARAMETER_RATE_Y_AXIS_ROTATION,
1331
    EPSG_CODE_PARAMETER_RATE_Y_AXIS_ROTATION, nullptr,
1332
    common::UnitOfMeasure::Type::LINEAR, nullptr};
1333
1334
static const ParamMapping paramRateZRotation = {
1335
    EPSG_NAME_PARAMETER_RATE_Z_AXIS_ROTATION,
1336
    EPSG_CODE_PARAMETER_RATE_Z_AXIS_ROTATION, nullptr,
1337
    common::UnitOfMeasure::Type::LINEAR, nullptr};
1338
1339
static const ParamMapping paramRateScaleDifference = {
1340
    EPSG_NAME_PARAMETER_RATE_SCALE_DIFFERENCE,
1341
    EPSG_CODE_PARAMETER_RATE_SCALE_DIFFERENCE, nullptr,
1342
    common::UnitOfMeasure::Type::SCALE, nullptr};
1343
1344
static const ParamMapping paramReferenceEpoch = {
1345
    EPSG_NAME_PARAMETER_REFERENCE_EPOCH, EPSG_CODE_PARAMETER_REFERENCE_EPOCH,
1346
    nullptr, common::UnitOfMeasure::Type::TIME, nullptr};
1347
1348
static const ParamMapping *const paramsHelmert15[] = {
1349
    &paramXTranslation,     &paramYTranslation,
1350
    &paramZTranslation,     &paramXRotation,
1351
    &paramYRotation,        &paramZRotation,
1352
    &paramScaleDifference,  &paramRateXTranslation,
1353
    &paramRateYTranslation, &paramRateZTranslation,
1354
    &paramRateXRotation,    &paramRateYRotation,
1355
    &paramRateZRotation,    &paramRateScaleDifference,
1356
    &paramReferenceEpoch,   nullptr};
1357
1358
static const ParamMapping paramOrdinate1EvalPoint = {
1359
    EPSG_NAME_PARAMETER_ORDINATE_1_EVAL_POINT,
1360
    EPSG_CODE_PARAMETER_ORDINATE_1_EVAL_POINT, nullptr,
1361
    common::UnitOfMeasure::Type::LINEAR, nullptr};
1362
1363
static const ParamMapping paramOrdinate2EvalPoint = {
1364
    EPSG_NAME_PARAMETER_ORDINATE_2_EVAL_POINT,
1365
    EPSG_CODE_PARAMETER_ORDINATE_2_EVAL_POINT, nullptr,
1366
    common::UnitOfMeasure::Type::LINEAR, nullptr};
1367
1368
static const ParamMapping paramOrdinate3EvalPoint = {
1369
    EPSG_NAME_PARAMETER_ORDINATE_3_EVAL_POINT,
1370
    EPSG_CODE_PARAMETER_ORDINATE_3_EVAL_POINT, nullptr,
1371
    common::UnitOfMeasure::Type::LINEAR, nullptr};
1372
1373
static const ParamMapping *const paramsMolodenskyBadekas[] = {
1374
    &paramXTranslation,
1375
    &paramYTranslation,
1376
    &paramZTranslation,
1377
    &paramXRotation,
1378
    &paramYRotation,
1379
    &paramZRotation,
1380
    &paramScaleDifference,
1381
    &paramOrdinate1EvalPoint,
1382
    &paramOrdinate2EvalPoint,
1383
    &paramOrdinate3EvalPoint,
1384
    nullptr};
1385
1386
static const ParamMapping paramSemiMajorAxisDifference = {
1387
    EPSG_NAME_PARAMETER_SEMI_MAJOR_AXIS_DIFFERENCE,
1388
    EPSG_CODE_PARAMETER_SEMI_MAJOR_AXIS_DIFFERENCE, nullptr,
1389
    common::UnitOfMeasure::Type::LINEAR, nullptr};
1390
1391
static const ParamMapping paramFlatteningDifference = {
1392
    EPSG_NAME_PARAMETER_FLATTENING_DIFFERENCE,
1393
    EPSG_CODE_PARAMETER_FLATTENING_DIFFERENCE, nullptr,
1394
    common::UnitOfMeasure::Type::NONE, nullptr};
1395
1396
static const ParamMapping *const paramsMolodensky[] = {
1397
    &paramXTranslation,         &paramYTranslation,
1398
    &paramZTranslation,         &paramSemiMajorAxisDifference,
1399
    &paramFlatteningDifference, nullptr};
1400
1401
static const ParamMapping paramLatitudeOffset = {
1402
    EPSG_NAME_PARAMETER_LATITUDE_OFFSET, EPSG_CODE_PARAMETER_LATITUDE_OFFSET,
1403
    nullptr, common::UnitOfMeasure::Type::ANGULAR, nullptr};
1404
1405
static const ParamMapping *const paramsGeographic2DOffsets[] = {
1406
    &paramLatitudeOffset, &paramLongitudeOffset, nullptr};
1407
1408
static const ParamMapping paramGeoidHeight = {
1409
    EPSG_NAME_PARAMETER_GEOID_HEIGHT, EPSG_CODE_PARAMETER_GEOID_HEIGHT, nullptr,
1410
    common::UnitOfMeasure::Type::LINEAR, nullptr};
1411
1412
static const ParamMapping *const paramsGeographic2DWithHeightOffsets[] = {
1413
    &paramLatitudeOffset, &paramLongitudeOffset, &paramGeoidHeight, nullptr};
1414
1415
static const ParamMapping paramVerticalOffset = {
1416
    EPSG_NAME_PARAMETER_VERTICAL_OFFSET, EPSG_CODE_PARAMETER_VERTICAL_OFFSET,
1417
    nullptr, common::UnitOfMeasure::Type::LINEAR, nullptr};
1418
1419
static const ParamMapping *const paramsGeographic3DOffsets[] = {
1420
    &paramLatitudeOffset, &paramLongitudeOffset, &paramVerticalOffset, nullptr};
1421
1422
static const ParamMapping paramEastingOffset = {
1423
    EPSG_NAME_PARAMETER_EASTING_OFFSET, EPSG_CODE_PARAMETER_EASTING_OFFSET,
1424
    nullptr, common::UnitOfMeasure::Type::LINEAR, nullptr};
1425
1426
static const ParamMapping paramNorthingOffset = {
1427
    EPSG_NAME_PARAMETER_NORTHING_OFFSET, EPSG_CODE_PARAMETER_NORTHING_OFFSET,
1428
    nullptr, common::UnitOfMeasure::Type::LINEAR, nullptr};
1429
1430
static const ParamMapping *const paramsCartesianGridOffsets[] = {
1431
    &paramEastingOffset, &paramNorthingOffset, nullptr};
1432
1433
static const ParamMapping *const paramsVerticalOffsets[] = {
1434
    &paramVerticalOffset, nullptr};
1435
1436
static const ParamMapping *const paramsGeographic3DToGravityRelatedHeight[] = {
1437
    &paramGeoidHeight, nullptr};
1438
1439
static const ParamMapping paramInclinationInLatitude = {
1440
    EPSG_NAME_PARAMETER_INCLINATION_IN_LATITUDE,
1441
    EPSG_CODE_PARAMETER_INCLINATION_IN_LATITUDE, nullptr,
1442
    common::UnitOfMeasure::Type::ANGULAR, nullptr};
1443
1444
static const ParamMapping paramInclinationInLongitude = {
1445
    EPSG_NAME_PARAMETER_INCLINATION_IN_LONGITUDE,
1446
    EPSG_CODE_PARAMETER_INCLINATION_IN_LONGITUDE, nullptr,
1447
    common::UnitOfMeasure::Type::ANGULAR, nullptr};
1448
1449
static const ParamMapping *const paramsVerticalOffsetAndSlope[] = {
1450
    &paramOrdinate1EvalPoint,     &paramOrdinate2EvalPoint,
1451
    &paramVerticalOffset,         &paramInclinationInLatitude,
1452
    &paramInclinationInLongitude, nullptr};
1453
1454
static const ParamMapping paramLatitudeLongitudeDifferenceFile = {
1455
    EPSG_NAME_PARAMETER_LATITUDE_LONGITUDE_DIFFERENCE_FILE,
1456
    EPSG_CODE_PARAMETER_LATITUDE_LONGITUDE_DIFFERENCE_FILE, nullptr,
1457
    common::UnitOfMeasure::Type::NONE, nullptr};
1458
1459
static const ParamMapping *const paramsNTV2[] = {
1460
    &paramLatitudeLongitudeDifferenceFile, nullptr};
1461
1462
static const ParamMapping paramGeocentricTranslationFile = {
1463
    EPSG_NAME_PARAMETER_GEOCENTRIC_TRANSLATION_FILE,
1464
    EPSG_CODE_PARAMETER_GEOCENTRIC_TRANSLATION_FILE, nullptr,
1465
    common::UnitOfMeasure::Type::NONE, nullptr};
1466
1467
static const ParamMapping
1468
    *const paramsGeocentricTranslationGridInterpolationIGN[] = {
1469
        &paramGeocentricTranslationFile, nullptr};
1470
1471
static const ParamMapping paramLatitudeDifferenceFile = {
1472
    EPSG_NAME_PARAMETER_LATITUDE_DIFFERENCE_FILE,
1473
    EPSG_CODE_PARAMETER_LATITUDE_DIFFERENCE_FILE, nullptr,
1474
    common::UnitOfMeasure::Type::NONE, nullptr};
1475
1476
static const ParamMapping paramLongitudeDifferenceFile = {
1477
    EPSG_NAME_PARAMETER_LONGITUDE_DIFFERENCE_FILE,
1478
    EPSG_CODE_PARAMETER_LONGITUDE_DIFFERENCE_FILE, nullptr,
1479
    common::UnitOfMeasure::Type::NONE, nullptr};
1480
1481
static const ParamMapping *const paramsNADCON[] = {
1482
    &paramLatitudeDifferenceFile, &paramLongitudeDifferenceFile, nullptr};
1483
1484
static const ParamMapping *const paramsNADCON5_2D[] = {
1485
    &paramLatitudeDifferenceFile, &paramLongitudeDifferenceFile, nullptr};
1486
1487
static const ParamMapping paramEllipsoidalHeightDifference = {
1488
    EPSG_NAME_PARAMETER_ELLIPSOIDAL_HEIGHT_DIFFERENCE_FILE,
1489
    EPSG_CODE_PARAMETER_ELLIPSOIDAL_HEIGHT_DIFFERENCE_FILE, nullptr,
1490
    common::UnitOfMeasure::Type::NONE, nullptr};
1491
1492
static const ParamMapping *const paramsNADCON5_3D[] = {
1493
    &paramLatitudeDifferenceFile, &paramLongitudeDifferenceFile,
1494
    &paramEllipsoidalHeightDifference, nullptr};
1495
1496
static const ParamMapping paramVerticalOffsetFile = {
1497
    EPSG_NAME_PARAMETER_VERTICAL_OFFSET_FILE,
1498
    EPSG_CODE_PARAMETER_VERTICAL_OFFSET_FILE, nullptr,
1499
    common::UnitOfMeasure::Type::NONE, nullptr};
1500
1501
static const ParamMapping *const paramsVERTCON[] = {&paramVerticalOffsetFile,
1502
                                                    nullptr};
1503
1504
static const ParamMapping paramPointMotiionVelocityGridFile = {
1505
    EPSG_NAME_PARAMETER_POINT_MOTION_VELOCITY_GRID_FILE,
1506
    EPSG_CODE_PARAMETER_POINT_MOTION_VELOCITY_GRID_FILE, nullptr,
1507
    common::UnitOfMeasure::Type::NONE, nullptr};
1508
1509
static const ParamMapping *const paramsPointMotionOperationByVelocityGrid[] = {
1510
    &paramPointMotiionVelocityGridFile, nullptr};
1511
1512
static const ParamMapping paramSouthPoleLatGRIB = {
1513
    PROJ_WKT2_NAME_PARAMETER_SOUTH_POLE_LATITUDE_GRIB_CONVENTION, 0, nullptr,
1514
    common::UnitOfMeasure::Type::ANGULAR, nullptr};
1515
1516
static const ParamMapping paramSouthPoleLongGRIB = {
1517
    PROJ_WKT2_NAME_PARAMETER_SOUTH_POLE_LONGITUDE_GRIB_CONVENTION, 0, nullptr,
1518
    common::UnitOfMeasure::Type::ANGULAR, nullptr};
1519
1520
static const ParamMapping paramAxisRotationGRIB = {
1521
    PROJ_WKT2_NAME_PARAMETER_AXIS_ROTATION_GRIB_CONVENTION, 0, nullptr,
1522
    common::UnitOfMeasure::Type::ANGULAR, nullptr};
1523
1524
static const ParamMapping *const paramsPoleRotationGRIBConvention[] = {
1525
    &paramSouthPoleLatGRIB, &paramSouthPoleLongGRIB, &paramAxisRotationGRIB,
1526
    nullptr};
1527
1528
static const ParamMapping paramGridNorthPoleLatitudeNetCDF = {
1529
    PROJ_WKT2_NAME_PARAMETER_GRID_NORTH_POLE_LATITUDE_NETCDF_CONVENTION, 0,
1530
    nullptr, common::UnitOfMeasure::Type::ANGULAR, nullptr};
1531
1532
static const ParamMapping paramGridNorthPoleLongitudeNetCDF = {
1533
    PROJ_WKT2_NAME_PARAMETER_GRID_NORTH_POLE_LONGITUDE_NETCDF_CONVENTION, 0,
1534
    nullptr, common::UnitOfMeasure::Type::ANGULAR, nullptr};
1535
1536
static const ParamMapping paramNorthPoleGridLongitudeNetCDF = {
1537
    PROJ_WKT2_NAME_PARAMETER_NORTH_POLE_GRID_LONGITUDE_NETCDF_CONVENTION, 0,
1538
    nullptr, common::UnitOfMeasure::Type::ANGULAR, nullptr};
1539
1540
static const ParamMapping *const paramsPoleRotationNetCDFCFConvention[] = {
1541
    &paramGridNorthPoleLatitudeNetCDF, &paramGridNorthPoleLongitudeNetCDF,
1542
    &paramNorthPoleGridLongitudeNetCDF, nullptr};
1543
1544
static const ParamMapping paramTINOffsetFile = {
1545
    EPSG_NAME_PARAMETER_TIN_OFFSET_FILE, EPSG_CODE_PARAMETER_TIN_OFFSET_FILE,
1546
    nullptr, common::UnitOfMeasure::Type::NONE, nullptr};
1547
1548
static const ParamMapping *const paramsTINOffsetFile[] = {&paramTINOffsetFile,
1549
                                                          nullptr};
1550
1551
static const MethodMapping gOtherMethodMappings[] = {
1552
    {EPSG_NAME_METHOD_CHANGE_VERTICAL_UNIT,
1553
     EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT, nullptr, nullptr, nullptr,
1554
     paramsChangeVerticalUnit},
1555
    {EPSG_NAME_METHOD_CHANGE_VERTICAL_UNIT_NO_CONV_FACTOR,
1556
     EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT_NO_CONV_FACTOR, nullptr, nullptr,
1557
     nullptr, nullptr},
1558
    {EPSG_NAME_METHOD_HEIGHT_DEPTH_REVERSAL,
1559
     EPSG_CODE_METHOD_HEIGHT_DEPTH_REVERSAL, nullptr, nullptr, nullptr,
1560
     nullptr},
1561
    {EPSG_NAME_METHOD_AXIS_ORDER_REVERSAL_2D,
1562
     EPSG_CODE_METHOD_AXIS_ORDER_REVERSAL_2D, nullptr, nullptr, nullptr,
1563
     nullptr},
1564
    {EPSG_NAME_METHOD_AXIS_ORDER_REVERSAL_3D,
1565
     EPSG_CODE_METHOD_AXIS_ORDER_REVERSAL_3D, nullptr, nullptr, nullptr,
1566
     nullptr},
1567
    {EPSG_NAME_METHOD_GEOGRAPHIC_GEOCENTRIC,
1568
     EPSG_CODE_METHOD_GEOGRAPHIC_GEOCENTRIC, nullptr, nullptr, nullptr,
1569
     nullptr},
1570
    {PROJ_WKT2_NAME_METHOD_GEOGRAPHIC_GEOCENTRIC_LATITUDE, 0, nullptr, nullptr,
1571
     nullptr, nullptr},
1572
    {EPSG_NAME_METHOD_LONGITUDE_ROTATION, EPSG_CODE_METHOD_LONGITUDE_ROTATION,
1573
     nullptr, nullptr, nullptr, paramsLongitudeRotation},
1574
    {EPSG_NAME_METHOD_AFFINE_PARAMETRIC_TRANSFORMATION,
1575
     EPSG_CODE_METHOD_AFFINE_PARAMETRIC_TRANSFORMATION, nullptr, nullptr,
1576
     nullptr, paramsAffineParametricTransformation},
1577
1578
    {PROJ_WKT2_NAME_METHOD_3D_AFFINE_PARAMETRIC_TRANSFORMATION, 0, nullptr,
1579
     nullptr, nullptr, params3DAffineParametricTransformation},
1580
1581
    {EPSG_NAME_METHOD_SIMILARITY_TRANSFORMATION,
1582
     EPSG_CODE_METHOD_SIMILARITY_TRANSFORMATION, nullptr, nullptr, nullptr,
1583
     paramsSimilarityTransformation},
1584
1585
    {PROJ_WKT2_NAME_METHOD_POLE_ROTATION_GRIB_CONVENTION, 0, nullptr, nullptr,
1586
     nullptr, paramsPoleRotationGRIBConvention},
1587
1588
    {PROJ_WKT2_NAME_METHOD_POLE_ROTATION_NETCDF_CF_CONVENTION, 0, nullptr,
1589
     nullptr, nullptr, paramsPoleRotationNetCDFCFConvention},
1590
1591
    {EPSG_NAME_METHOD_GEOCENTRIC_TRANSLATION_GEOCENTRIC,
1592
     EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_GEOCENTRIC, nullptr, nullptr,
1593
     nullptr, paramsHelmert3},
1594
    {EPSG_NAME_METHOD_GEOCENTRIC_TRANSLATION_GEOGRAPHIC_2D,
1595
     EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_GEOGRAPHIC_2D, nullptr, nullptr,
1596
     nullptr, paramsHelmert3},
1597
    {EPSG_NAME_METHOD_GEOCENTRIC_TRANSLATION_GEOGRAPHIC_3D,
1598
     EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_GEOGRAPHIC_3D, nullptr, nullptr,
1599
     nullptr, paramsHelmert3},
1600
1601
    {EPSG_NAME_METHOD_COORDINATE_FRAME_GEOCENTRIC,
1602
     EPSG_CODE_METHOD_COORDINATE_FRAME_GEOCENTRIC, nullptr, nullptr, nullptr,
1603
     paramsHelmert7},
1604
    {EPSG_NAME_METHOD_COORDINATE_FRAME_FULL_MATRIX_GEOCENTRIC,
1605
     EPSG_CODE_METHOD_COORDINATE_FRAME_FULL_MATRIX_GEOCENTRIC, nullptr, nullptr,
1606
     nullptr, paramsHelmert7},
1607
    {EPSG_NAME_METHOD_COORDINATE_FRAME_GEOGRAPHIC_2D,
1608
     EPSG_CODE_METHOD_COORDINATE_FRAME_GEOGRAPHIC_2D, nullptr, nullptr, nullptr,
1609
     paramsHelmert7},
1610
    {EPSG_NAME_METHOD_COORDINATE_FRAME_FULL_MATRIX_GEOGRAPHIC_2D,
1611
     EPSG_CODE_METHOD_COORDINATE_FRAME_FULL_MATRIX_GEOGRAPHIC_2D, nullptr,
1612
     nullptr, nullptr, paramsHelmert7},
1613
    {EPSG_NAME_METHOD_COORDINATE_FRAME_GEOGRAPHIC_3D,
1614
     EPSG_CODE_METHOD_COORDINATE_FRAME_GEOGRAPHIC_3D, nullptr, nullptr, nullptr,
1615
     paramsHelmert7},
1616
    {EPSG_NAME_METHOD_COORDINATE_FRAME_FULL_MATRIX_GEOGRAPHIC_3D,
1617
     EPSG_CODE_METHOD_COORDINATE_FRAME_FULL_MATRIX_GEOGRAPHIC_3D, nullptr,
1618
     nullptr, nullptr, paramsHelmert7},
1619
    {EPSG_NAME_METHOD_COORDINATE_FRAME_GEOG3D_TO_COMPOUND,
1620
     EPSG_CODE_METHOD_COORDINATE_FRAME_GEOG3D_TO_COMPOUND, nullptr, nullptr,
1621
     nullptr, paramsHelmert7},
1622
1623
    {EPSG_NAME_METHOD_POSITION_VECTOR_GEOCENTRIC,
1624
     EPSG_CODE_METHOD_POSITION_VECTOR_GEOCENTRIC, nullptr, nullptr, nullptr,
1625
     paramsHelmert7},
1626
    {EPSG_NAME_METHOD_POSITION_VECTOR_GEOGRAPHIC_2D,
1627
     EPSG_CODE_METHOD_POSITION_VECTOR_GEOGRAPHIC_2D, nullptr, nullptr, nullptr,
1628
     paramsHelmert7},
1629
    {EPSG_NAME_METHOD_POSITION_VECTOR_GEOGRAPHIC_3D,
1630
     EPSG_CODE_METHOD_POSITION_VECTOR_GEOGRAPHIC_3D, nullptr, nullptr, nullptr,
1631
     paramsHelmert7},
1632
1633
    {EPSG_NAME_METHOD_TIME_DEPENDENT_COORDINATE_FRAME_GEOCENTRIC,
1634
     EPSG_CODE_METHOD_TIME_DEPENDENT_COORDINATE_FRAME_GEOCENTRIC, nullptr,
1635
     nullptr, nullptr, paramsHelmert15},
1636
    {EPSG_NAME_METHOD_TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_2D,
1637
     EPSG_CODE_METHOD_TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_2D, nullptr,
1638
     nullptr, nullptr, paramsHelmert15},
1639
    {EPSG_NAME_METHOD_TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_3D,
1640
     EPSG_CODE_METHOD_TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_3D, nullptr,
1641
     nullptr, nullptr, paramsHelmert15},
1642
1643
    {EPSG_NAME_METHOD_TIME_DEPENDENT_POSITION_VECTOR_GEOCENTRIC,
1644
     EPSG_CODE_METHOD_TIME_DEPENDENT_POSITION_VECTOR_GEOCENTRIC, nullptr,
1645
     nullptr, nullptr, paramsHelmert15},
1646
    {EPSG_NAME_METHOD_TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_2D,
1647
     EPSG_CODE_METHOD_TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_2D, nullptr,
1648
     nullptr, nullptr, paramsHelmert15},
1649
    {EPSG_NAME_METHOD_TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_3D,
1650
     EPSG_CODE_METHOD_TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_3D, nullptr,
1651
     nullptr, nullptr, paramsHelmert15},
1652
1653
    {EPSG_NAME_METHOD_MOLODENSKY_BADEKAS_CF_GEOCENTRIC,
1654
     EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_CF_GEOCENTRIC, nullptr, nullptr,
1655
     nullptr, paramsMolodenskyBadekas},
1656
    {EPSG_NAME_METHOD_MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_2D,
1657
     EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_2D, nullptr, nullptr,
1658
     nullptr, paramsMolodenskyBadekas},
1659
    {EPSG_NAME_METHOD_MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_3D,
1660
     EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_3D, nullptr, nullptr,
1661
     nullptr, paramsMolodenskyBadekas},
1662
1663
    {EPSG_NAME_METHOD_MOLODENSKY_BADEKAS_PV_GEOCENTRIC,
1664
     EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_PV_GEOCENTRIC, nullptr, nullptr,
1665
     nullptr, paramsMolodenskyBadekas},
1666
    {EPSG_NAME_METHOD_MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_2D,
1667
     EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_2D, nullptr, nullptr,
1668
     nullptr, paramsMolodenskyBadekas},
1669
    {EPSG_NAME_METHOD_MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_3D,
1670
     EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_3D, nullptr, nullptr,
1671
     nullptr, paramsMolodenskyBadekas},
1672
1673
    {EPSG_NAME_METHOD_MOLODENSKY, EPSG_CODE_METHOD_MOLODENSKY, nullptr, nullptr,
1674
     nullptr, paramsMolodensky},
1675
1676
    {EPSG_NAME_METHOD_ABRIDGED_MOLODENSKY, EPSG_CODE_METHOD_ABRIDGED_MOLODENSKY,
1677
     nullptr, nullptr, nullptr, paramsMolodensky},
1678
1679
    {EPSG_NAME_METHOD_GEOGRAPHIC2D_OFFSETS,
1680
     EPSG_CODE_METHOD_GEOGRAPHIC2D_OFFSETS, nullptr, nullptr, nullptr,
1681
     paramsGeographic2DOffsets},
1682
1683
    {EPSG_NAME_METHOD_GEOGRAPHIC2D_WITH_HEIGHT_OFFSETS,
1684
     EPSG_CODE_METHOD_GEOGRAPHIC2D_WITH_HEIGHT_OFFSETS, nullptr, nullptr,
1685
     nullptr, paramsGeographic2DWithHeightOffsets},
1686
1687
    {EPSG_NAME_METHOD_GEOGRAPHIC3D_OFFSETS,
1688
     EPSG_CODE_METHOD_GEOGRAPHIC3D_OFFSETS, nullptr, nullptr, nullptr,
1689
     paramsGeographic3DOffsets},
1690
1691
    {EPSG_NAME_METHOD_CARTESIAN_GRID_OFFSETS,
1692
     EPSG_CODE_METHOD_CARTESIAN_GRID_OFFSETS, nullptr, nullptr, nullptr,
1693
     paramsCartesianGridOffsets},
1694
1695
    {EPSG_NAME_METHOD_VERTICAL_OFFSET, EPSG_CODE_METHOD_VERTICAL_OFFSET,
1696
     nullptr, nullptr, nullptr, paramsVerticalOffsets},
1697
1698
    {EPSG_NAME_METHOD_GEOGRAPHIC3D_TO_GRAVITYRELATEDHEIGHT,
1699
     EPSG_CODE_METHOD_GEOGRAPHIC3D_TO_GRAVITYRELATEDHEIGHT, nullptr, nullptr,
1700
     nullptr, paramsGeographic3DToGravityRelatedHeight},
1701
1702
    {EPSG_NAME_METHOD_GEOGRAPHIC3D_TO_GEOG2D_GRAVITYRELATEDHEIGHT,
1703
     EPSG_CODE_METHOD_GEOGRAPHIC3D_TO_GEOG2D_GRAVITYRELATEDHEIGHT, nullptr,
1704
     nullptr, nullptr, paramsGeographic3DToGravityRelatedHeight},
1705
1706
    {EPSG_NAME_METHOD_VERTICAL_OFFSET_AND_SLOPE,
1707
     EPSG_CODE_METHOD_VERTICAL_OFFSET_AND_SLOPE, nullptr, nullptr, nullptr,
1708
     paramsVerticalOffsetAndSlope},
1709
1710
    {EPSG_NAME_METHOD_NTV2, EPSG_CODE_METHOD_NTV2, nullptr, nullptr, nullptr,
1711
     paramsNTV2},
1712
1713
    {EPSG_NAME_METHOD_NTV1, EPSG_CODE_METHOD_NTV1, nullptr, nullptr, nullptr,
1714
     paramsNTV2},
1715
1716
    {EPSG_NAME_METHOD_GEOCENTRIC_TRANSLATIONS_GEOG2D_DOMAIN_BY_GRID_IGN,
1717
     EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATIONS_GEOG2D_DOMAIN_BY_GRID_IGN,
1718
     nullptr, nullptr, nullptr,
1719
     paramsGeocentricTranslationGridInterpolationIGN},
1720
1721
    {EPSG_NAME_METHOD_VERTICAL_OFFSET_BY_TIN_INTERPOLATION_JSON,
1722
     EPSG_CODE_METHOD_VERTICAL_OFFSET_BY_TIN_INTERPOLATION_JSON, nullptr,
1723
     nullptr, nullptr, paramsTINOffsetFile},
1724
1725
    {EPSG_NAME_METHOD_CARTESIAN_GRID_OFFSETS_BY_TIN_INTERPOLATION_JSON,
1726
     EPSG_CODE_METHOD_CARTESIAN_GRID_OFFSETS_BY_TIN_INTERPOLATION_JSON, nullptr,
1727
     nullptr, nullptr, paramsTINOffsetFile},
1728
1729
    {EPSG_NAME_METHOD_GEOGRAPHIC2D_OFFSETS_BY_TIN_INTERPOLATION_JSON,
1730
     EPSG_CODE_METHOD_GEOGRAPHIC2D_OFFSETS_BY_TIN_INTERPOLATION_JSON, nullptr,
1731
     nullptr, nullptr, paramsTINOffsetFile},
1732
1733
    {EPSG_NAME_METHOD_NADCON, EPSG_CODE_METHOD_NADCON, nullptr, nullptr,
1734
     nullptr, paramsNADCON},
1735
1736
    {EPSG_NAME_METHOD_NADCON5_2D, EPSG_CODE_METHOD_NADCON5_2D, nullptr, nullptr,
1737
     nullptr, paramsNADCON5_2D},
1738
1739
    {EPSG_NAME_METHOD_NADCON5_3D, EPSG_CODE_METHOD_NADCON5_3D, nullptr, nullptr,
1740
     nullptr, paramsNADCON5_3D},
1741
1742
    {EPSG_NAME_METHOD_VERTCON, EPSG_CODE_METHOD_VERTCON, nullptr, nullptr,
1743
     nullptr, paramsVERTCON},
1744
    {EPSG_NAME_METHOD_VERTCON_OLDNAME, EPSG_CODE_METHOD_VERTCON, nullptr,
1745
     nullptr, nullptr, paramsVERTCON},
1746
1747
    {EPSG_NAME_METHOD_POINT_MOTION_BY_GRID_CANADA_NTV2_VEL,
1748
     EPSG_CODE_METHOD_POINT_MOTION_BY_GRID_CANADA_NTV2_VEL, nullptr, nullptr,
1749
     nullptr, paramsPointMotionOperationByVelocityGrid},
1750
1751
    {EPSG_NAME_METHOD_POINT_MOTION_GEOG3D_DOMAIN_USING_NEU_VELOCITY_GRID_NTV2_VEL,
1752
     EPSG_CODE_METHOD_POINT_MOTION_GEOG3D_DOMAIN_USING_NEU_VELOCITY_GRID_NTV2_VEL,
1753
     nullptr, nullptr, nullptr, paramsPointMotionOperationByVelocityGrid},
1754
};
1755
1756
0
const MethodMapping *getOtherMethodMappings(size_t &nElts) {
1757
0
    nElts = sizeof(gOtherMethodMappings) / sizeof(gOtherMethodMappings[0]);
1758
0
    return gOtherMethodMappings;
1759
0
}
1760
1761
// ---------------------------------------------------------------------------
1762
1763
985
PROJ_NO_INLINE const MethodMapping *getMapping(int epsg_code) noexcept {
1764
37.5k
    for (const auto &mapping : gProjectionMethodMappings) {
1765
37.5k
        if (mapping.epsg_code == epsg_code) {
1766
985
            return &mapping;
1767
985
        }
1768
37.5k
    }
1769
0
    return nullptr;
1770
985
}
1771
1772
// ---------------------------------------------------------------------------
1773
1774
234k
const MethodMapping *getMapping(const OperationMethod *method) noexcept {
1775
234k
    const std::string &name(method->nameStr());
1776
234k
    const int epsg_code = method->getEPSGCode();
1777
20.8M
    for (const auto &mapping : gProjectionMethodMappings) {
1778
20.8M
        if ((epsg_code != 0 && mapping.epsg_code == epsg_code) ||
1779
20.8M
            metadata::Identifier::isEquivalentName(mapping.wkt2_name,
1780
20.8M
                                                   name.c_str())) {
1781
42.2k
            return &mapping;
1782
42.2k
        }
1783
20.8M
    }
1784
192k
    return nullptr;
1785
234k
}
1786
1787
// ---------------------------------------------------------------------------
1788
1789
247
const MethodMapping *getMappingFromWKT1(const std::string &wkt1_name) noexcept {
1790
    // Unusual for a WKT1 projection name, but mentioned in OGC 12-063r5 C.4.2
1791
247
    if (ci_starts_with(wkt1_name, "UTM zone")) {
1792
0
        return getMapping(EPSG_CODE_METHOD_TRANSVERSE_MERCATOR);
1793
0
    }
1794
1795
19.7k
    for (const auto &mapping : gProjectionMethodMappings) {
1796
19.7k
        if (mapping.wkt1_name && metadata::Identifier::isEquivalentName(
1797
16.6k
                                     mapping.wkt1_name, wkt1_name.c_str())) {
1798
79
            return &mapping;
1799
79
        }
1800
19.7k
    }
1801
168
    return nullptr;
1802
247
}
1803
// ---------------------------------------------------------------------------
1804
1805
1.93k
const MethodMapping *getMapping(const char *wkt2_name) noexcept {
1806
165k
    for (const auto &mapping : gProjectionMethodMappings) {
1807
165k
        if (metadata::Identifier::isEquivalentName(mapping.wkt2_name,
1808
165k
                                                   wkt2_name)) {
1809
554
            return &mapping;
1810
554
        }
1811
165k
    }
1812
9.64k
    for (const auto &mapping : gOtherMethodMappings) {
1813
9.64k
        if (metadata::Identifier::isEquivalentName(mapping.wkt2_name,
1814
9.64k
                                                   wkt2_name)) {
1815
1.37k
            return &mapping;
1816
1.37k
        }
1817
9.64k
    }
1818
0
    return nullptr;
1819
1.37k
}
1820
1821
// ---------------------------------------------------------------------------
1822
1823
std::vector<const MethodMapping *>
1824
20.6k
getMappingsFromPROJName(const std::string &projName) {
1825
20.6k
    std::vector<const MethodMapping *> res;
1826
2.02M
    for (const auto &mapping : gProjectionMethodMappings) {
1827
2.02M
        if (mapping.proj_name_main && projName == mapping.proj_name_main) {
1828
13.7k
            res.push_back(&mapping);
1829
13.7k
        }
1830
2.02M
    }
1831
20.6k
    return res;
1832
20.6k
}
1833
1834
// ---------------------------------------------------------------------------
1835
1836
const ParamMapping *getMapping(const MethodMapping *mapping,
1837
0
                               const OperationParameterNNPtr &param) {
1838
0
    if (mapping->params == nullptr) {
1839
0
        return nullptr;
1840
0
    }
1841
1842
    // First try with id
1843
0
    const int epsg_code = param->getEPSGCode();
1844
0
    if (epsg_code) {
1845
0
        for (int i = 0; mapping->params[i] != nullptr; ++i) {
1846
0
            const auto *paramMapping = mapping->params[i];
1847
0
            if (paramMapping->epsg_code == epsg_code) {
1848
0
                return paramMapping;
1849
0
            }
1850
0
        }
1851
0
    }
1852
1853
    // then equivalent name
1854
0
    const std::string &name = param->nameStr();
1855
0
    for (int i = 0; mapping->params[i] != nullptr; ++i) {
1856
0
        const auto *paramMapping = mapping->params[i];
1857
0
        if (metadata::Identifier::isEquivalentName(paramMapping->wkt2_name,
1858
0
                                                   name.c_str())) {
1859
0
            return paramMapping;
1860
0
        }
1861
0
    }
1862
1863
    // and finally different name, but equivalent parameter
1864
0
    for (int i = 0; mapping->params[i] != nullptr; ++i) {
1865
0
        const auto *paramMapping = mapping->params[i];
1866
0
        if (areEquivalentParameters(paramMapping->wkt2_name, name)) {
1867
0
            return paramMapping;
1868
0
        }
1869
0
    }
1870
1871
0
    return nullptr;
1872
0
}
1873
1874
// ---------------------------------------------------------------------------
1875
1876
const ParamMapping *getMappingFromWKT1(const MethodMapping *mapping,
1877
279
                                       const std::string &wkt1_name) {
1878
2.11k
    for (int i = 0; mapping->params[i] != nullptr; ++i) {
1879
1.84k
        const auto *paramMapping = mapping->params[i];
1880
1.84k
        if (paramMapping->wkt1_name &&
1881
1.84k
            (metadata::Identifier::isEquivalentName(paramMapping->wkt1_name,
1882
1.84k
                                                    wkt1_name.c_str()) ||
1883
1.84k
             areEquivalentParameters(paramMapping->wkt1_name, wkt1_name))) {
1884
10
            return paramMapping;
1885
10
        }
1886
1.84k
    }
1887
269
    return nullptr;
1888
279
}
1889
1890
//! @endcond
1891
1892
// ---------------------------------------------------------------------------
1893
1894
} // namespace operation
1895
NS_PROJ_END