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 paramFalseEastingOrigin = {
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 paramFalseNorthingOrigin = {
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 ¶mLatitudeNatOrigin, ¶mLongitudeNatOrigin, ¶mScaleFactor,
133 ¶mFalseEasting, ¶mFalseNorthing, nullptr};
134
135 static const ParamMapping *const paramsNatOriginScaleK[] = {
136 ¶mLatitudeNatOrigin, ¶mLongitudeNatOrigin, ¶mScaleFactorK,
137 ¶mFalseEasting, ¶mFalseNorthing, 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[] = {¶mLatFirstPoint,
153 ¶mLongFirstPoint,
154 ¶mLatSecondPoint,
155 ¶mLongSecondPoint,
156 ¶mFalseEasting,
157 ¶mFalseNorthing,
158 nullptr};
159
160 static const ParamMapping *const paramsTMG[] = {
161 ¶mLatitudeFalseOrigin, ¶mLongitudeFalseOrigin,
162 ¶mFalseEastingOrigin, ¶mFalseNorthingOrigin, 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[] = {
175 ¶mLatFalseOriginLatOfCenter,
176 ¶mLongFalseOriginLongOfCenter,
177 ¶mLatitude1stStdParallel,
178 ¶mLatitude2ndStdParallel,
179 ¶mFalseEastingOrigin,
180 ¶mFalseNorthingOrigin,
181 nullptr};
182
183 static const ParamMapping *const paramsLCC2SP[] = {
184 ¶mLatitudeFalseOrigin,
185 ¶mLongitudeFalseOrigin,
186 ¶mLatitude1stStdParallel,
187 ¶mLatitude2ndStdParallel,
188 ¶mFalseEastingOrigin,
189 ¶mFalseNorthingOrigin,
190 nullptr,
191 };
192
193 static const ParamMapping paramEllipsoidScaleFactor = {
194 EPSG_NAME_PARAMETER_ELLIPSOID_SCALE_FACTOR,
195 EPSG_CODE_PARAMETER_ELLIPSOID_SCALE_FACTOR, nullptr,
196 common::UnitOfMeasure::Type::SCALE, k_0};
197
198 static const ParamMapping *const paramsLCC2SPMichigan[] = {
199 ¶mLatitudeFalseOrigin, ¶mLongitudeFalseOrigin,
200 ¶mLatitude1stStdParallel, ¶mLatitude2ndStdParallel,
201 ¶mFalseEastingOrigin, ¶mFalseNorthingOrigin,
202 ¶mEllipsoidScaleFactor, nullptr,
203 };
204
205 static const ParamMapping paramLatNatLatCenter = {
206 EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
207 EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, WKT1_LATITUDE_OF_CENTER,
208 common::UnitOfMeasure::Type::ANGULAR, lat_0};
209
210 static const ParamMapping paramLonNatLonCenter = {
211 EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
212 EPSG_CODE_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN, WKT1_LONGITUDE_OF_CENTER,
213 common::UnitOfMeasure::Type::ANGULAR, lon_0};
214
215 static const ParamMapping *const paramsAEQD[]{
216 ¶mLatNatLatCenter, ¶mLonNatLonCenter, ¶mFalseEasting,
217 ¶mFalseNorthing, nullptr};
218
219 static const ParamMapping *const paramsNatOrigin[] = {
220 ¶mLatitudeNatOrigin, ¶mLongitudeNatOrigin, ¶mFalseEasting,
221 ¶mFalseNorthing, nullptr};
222
223 static const ParamMapping paramLatNatOriginLat1 = {
224 EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
225 EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, WKT1_STANDARD_PARALLEL_1,
226 common::UnitOfMeasure::Type::ANGULAR, lat_1};
227
228 static const ParamMapping *const paramsBonne[] = {
229 ¶mLatNatOriginLat1, ¶mLongitudeNatOrigin, ¶mFalseEasting,
230 ¶mFalseNorthing, nullptr};
231
232 static const ParamMapping paramLat1stParallelLatTs = {
233 EPSG_NAME_PARAMETER_LATITUDE_1ST_STD_PARALLEL,
234 EPSG_CODE_PARAMETER_LATITUDE_1ST_STD_PARALLEL, WKT1_STANDARD_PARALLEL_1,
235 common::UnitOfMeasure::Type::ANGULAR, lat_ts};
236
237 static const ParamMapping *const paramsCEA[] = {
238 ¶mLat1stParallelLatTs, ¶mLongitudeNatOrigin, ¶mFalseEasting,
239 ¶mFalseNorthing, nullptr};
240
241 static const ParamMapping *const paramsEQDC[] = {¶mLatNatLatCenter,
242 ¶mLonNatLonCenter,
243 ¶mLatitude1stStdParallel,
244 ¶mLatitude2ndStdParallel,
245 ¶mFalseEasting,
246 ¶mFalseNorthing,
247 nullptr};
248
249 static const ParamMapping *const paramsLonNatOrigin[] = {
250 ¶mLongitudeNatOrigin, ¶mFalseEasting, ¶mFalseNorthing, nullptr};
251
252 static const ParamMapping *const paramsEqc[] = {
253 ¶mLat1stParallelLatTs,
254 ¶mLatitudeNatOrigin, // extension of EPSG, but used by GDAL / PROJ
255 ¶mLongitudeNatOrigin, ¶mFalseEasting,
256 ¶mFalseNorthing, nullptr};
257
258 static const ParamMapping paramSatelliteHeight = {
259 "Satellite Height", 0, "satellite_height",
260 common::UnitOfMeasure::Type::LINEAR, h};
261
262 static const ParamMapping *const paramsGeos[] = {
263 ¶mLongitudeNatOrigin, ¶mSatelliteHeight, ¶mFalseEasting,
264 ¶mFalseNorthing, nullptr};
265
266 static const ParamMapping paramLatCentreLatCenter = {
267 EPSG_NAME_PARAMETER_LATITUDE_PROJECTION_CENTRE,
268 EPSG_CODE_PARAMETER_LATITUDE_PROJECTION_CENTRE, WKT1_LATITUDE_OF_CENTER,
269 common::UnitOfMeasure::Type::ANGULAR, lat_0};
270
271 static const ParamMapping paramLonCentreLonCenterLonc = {
272 EPSG_NAME_PARAMETER_LONGITUDE_PROJECTION_CENTRE,
273 EPSG_CODE_PARAMETER_LONGITUDE_PROJECTION_CENTRE, WKT1_LONGITUDE_OF_CENTER,
274 common::UnitOfMeasure::Type::ANGULAR, lonc};
275
276 static const ParamMapping paramAzimuth = {
277 EPSG_NAME_PARAMETER_AZIMUTH_INITIAL_LINE,
278 EPSG_CODE_PARAMETER_AZIMUTH_INITIAL_LINE, WKT1_AZIMUTH,
279 common::UnitOfMeasure::Type::ANGULAR, alpha};
280
281 static const ParamMapping paramAngleToSkewGrid = {
282 EPSG_NAME_PARAMETER_ANGLE_RECTIFIED_TO_SKEW_GRID,
283 EPSG_CODE_PARAMETER_ANGLE_RECTIFIED_TO_SKEW_GRID, WKT1_RECTIFIED_GRID_ANGLE,
284 common::UnitOfMeasure::Type::ANGULAR, gamma};
285 static const ParamMapping paramScaleFactorInitialLine = {
286 EPSG_NAME_PARAMETER_SCALE_FACTOR_INITIAL_LINE,
287 EPSG_CODE_PARAMETER_SCALE_FACTOR_INITIAL_LINE, WKT1_SCALE_FACTOR,
288 common::UnitOfMeasure::Type::SCALE, k};
289
290 static const ParamMapping *const paramsHomVariantA[] = {
291 ¶mLatCentreLatCenter,
292 ¶mLonCentreLonCenterLonc,
293 ¶mAzimuth,
294 ¶mAngleToSkewGrid,
295 ¶mScaleFactorInitialLine,
296 ¶mFalseEasting,
297 ¶mFalseNorthing,
298 nullptr};
299
300 static const ParamMapping paramFalseEastingProjectionCentre = {
301 EPSG_NAME_PARAMETER_EASTING_PROJECTION_CENTRE,
302 EPSG_CODE_PARAMETER_EASTING_PROJECTION_CENTRE, WKT1_FALSE_EASTING,
303 common::UnitOfMeasure::Type::LINEAR, x_0};
304
305 static const ParamMapping paramFalseNorthingProjectionCentre = {
306 EPSG_NAME_PARAMETER_NORTHING_PROJECTION_CENTRE,
307 EPSG_CODE_PARAMETER_NORTHING_PROJECTION_CENTRE, WKT1_FALSE_NORTHING,
308 common::UnitOfMeasure::Type::LINEAR, y_0};
309
310 static const ParamMapping *const paramsHomVariantB[] = {
311 ¶mLatCentreLatCenter,
312 ¶mLonCentreLonCenterLonc,
313 ¶mAzimuth,
314 ¶mAngleToSkewGrid,
315 ¶mScaleFactorInitialLine,
316 ¶mFalseEastingProjectionCentre,
317 ¶mFalseNorthingProjectionCentre,
318 nullptr};
319
320 static const ParamMapping paramLatPoint1 = {
321 "Latitude of 1st point", 0, "latitude_of_point_1",
322 common::UnitOfMeasure::Type::ANGULAR, lat_1};
323
324 static const ParamMapping paramLonPoint1 = {
325 "Longitude of 1st point", 0, "longitude_of_point_1",
326 common::UnitOfMeasure::Type::ANGULAR, lon_1};
327
328 static const ParamMapping paramLatPoint2 = {
329 "Latitude of 2nd point", 0, "latitude_of_point_2",
330 common::UnitOfMeasure::Type::ANGULAR, lat_2};
331
332 static const ParamMapping paramLonPoint2 = {
333 "Longitude of 2nd point", 0, "longitude_of_point_2",
334 common::UnitOfMeasure::Type::ANGULAR, lon_2};
335
336 static const ParamMapping *const paramsHomTwoPoint[] = {
337 ¶mLatCentreLatCenter,
338 ¶mLatPoint1,
339 ¶mLonPoint1,
340 ¶mLatPoint2,
341 ¶mLonPoint2,
342 ¶mScaleFactorInitialLine,
343 ¶mFalseEastingProjectionCentre,
344 ¶mFalseNorthingProjectionCentre,
345 nullptr};
346
347 static const ParamMapping *const paramsIMWP[] = {
348 ¶mLongitudeNatOrigin, ¶mLatFirstPoint, ¶mLatSecondPoint,
349 ¶mFalseEasting, ¶mFalseNorthing, nullptr};
350
351 static const ParamMapping paramLonCentreLonCenter = {
352 EPSG_NAME_PARAMETER_LONGITUDE_OF_ORIGIN,
353 EPSG_CODE_PARAMETER_LONGITUDE_OF_ORIGIN, WKT1_LONGITUDE_OF_CENTER,
354 common::UnitOfMeasure::Type::ANGULAR, lon_0};
355
356 static const ParamMapping paramColatitudeConeAxis = {
357 EPSG_NAME_PARAMETER_COLATITUDE_CONE_AXIS,
358 EPSG_CODE_PARAMETER_COLATITUDE_CONE_AXIS, WKT1_AZIMUTH,
359 common::UnitOfMeasure::Type::ANGULAR,
360 "alpha"}; /* ignored by PROJ currently */
361
362 static const ParamMapping paramLatitudePseudoStdParallel = {
363 EPSG_NAME_PARAMETER_LATITUDE_PSEUDO_STANDARD_PARALLEL,
364 EPSG_CODE_PARAMETER_LATITUDE_PSEUDO_STANDARD_PARALLEL,
365 "pseudo_standard_parallel_1", common::UnitOfMeasure::Type::ANGULAR,
366 nullptr}; /* ignored by PROJ currently */
367
368 static const ParamMapping paramScaleFactorPseudoStdParallel = {
369 EPSG_NAME_PARAMETER_SCALE_FACTOR_PSEUDO_STANDARD_PARALLEL,
370 EPSG_CODE_PARAMETER_SCALE_FACTOR_PSEUDO_STANDARD_PARALLEL,
371 WKT1_SCALE_FACTOR, common::UnitOfMeasure::Type::SCALE,
372 k}; /* ignored by PROJ currently */
373
374 static const ParamMapping *const krovakParameters[] = {
375 ¶mLatCentreLatCenter,
376 ¶mLonCentreLonCenter,
377 ¶mColatitudeConeAxis,
378 ¶mLatitudePseudoStdParallel,
379 ¶mScaleFactorPseudoStdParallel,
380 ¶mFalseEasting,
381 ¶mFalseNorthing,
382 nullptr};
383
384 static const ParamMapping *const paramsLaea[] = {
385 ¶mLatNatLatCenter, ¶mLonNatLonCenter, ¶mFalseEasting,
386 ¶mFalseNorthing, nullptr};
387
388 static const ParamMapping *const paramsMiller[] = {
389 ¶mLonNatLonCenter, ¶mFalseEasting, ¶mFalseNorthing, nullptr};
390
391 static const ParamMapping paramLatMerc1SP = {
392 EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
393 EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
394 nullptr, // always set to zero, not to be exported in WKT1
395 common::UnitOfMeasure::Type::ANGULAR,
396 nullptr}; // always set to zero, not to be exported in PROJ strings
397
398 static const ParamMapping *const paramsMerc1SP[] = {
399 ¶mLatMerc1SP, ¶mLongitudeNatOrigin, ¶mScaleFactorK,
400 ¶mFalseEasting, ¶mFalseNorthing, nullptr};
401
402 static const ParamMapping *const paramsMerc2SP[] = {
403 ¶mLat1stParallelLatTs, ¶mLongitudeNatOrigin, ¶mFalseEasting,
404 ¶mFalseNorthing, nullptr};
405
406 static const ParamMapping *const paramsObliqueStereo[] = {
407 ¶mLatitudeNatOrigin, ¶mLongitudeNatOrigin, ¶mScaleFactorK,
408 ¶mFalseEasting, ¶mFalseNorthing, nullptr};
409
410 static const ParamMapping paramLatStdParallel = {
411 EPSG_NAME_PARAMETER_LATITUDE_STD_PARALLEL,
412 EPSG_CODE_PARAMETER_LATITUDE_STD_PARALLEL, WKT1_LATITUDE_OF_ORIGIN,
413 common::UnitOfMeasure::Type::ANGULAR, lat_ts};
414
415 static const ParamMapping paramsLonOrigin = {
416 EPSG_NAME_PARAMETER_LONGITUDE_OF_ORIGIN,
417 EPSG_CODE_PARAMETER_LONGITUDE_OF_ORIGIN, WKT1_CENTRAL_MERIDIAN,
418 common::UnitOfMeasure::Type::ANGULAR, lon_0};
419
420 static const ParamMapping *const paramsPolarStereo[] = {
421 ¶mLatStdParallel, ¶msLonOrigin, ¶mFalseEasting,
422 ¶mFalseNorthing, nullptr};
423
424 static const ParamMapping *const paramsLonNatOriginLongitudeCentre[] = {
425 ¶mLonNatLonCenter, ¶mFalseEasting, ¶mFalseNorthing, nullptr};
426
427 static const ParamMapping paramLatTrueScaleWag3 = {
428 "Latitude of true scale", 0, WKT1_LATITUDE_OF_ORIGIN,
429 common::UnitOfMeasure::Type::ANGULAR, lat_ts};
430
431 static const ParamMapping *const paramsWag3[] = {
432 ¶mLatTrueScaleWag3, ¶mLongitudeNatOrigin, ¶mFalseEasting,
433 ¶mFalseNorthing, nullptr};
434
435 static const ParamMapping paramPegLat = {
436 "Peg point latitude", 0, "peg_point_latitude",
437 common::UnitOfMeasure::Type::ANGULAR, "plat_0"};
438
439 static const ParamMapping paramPegLon = {
440 "Peg point longitude", 0, "peg_point_longitude",
441 common::UnitOfMeasure::Type::ANGULAR, "plon_0"};
442
443 static const ParamMapping paramPegHeading = {
444 "Peg point heading", 0, "peg_point_heading",
445 common::UnitOfMeasure::Type::ANGULAR, "phdg_0"};
446
447 static const ParamMapping paramPegHeight = {
448 "Peg point height", 0, "peg_point_height",
449 common::UnitOfMeasure::Type::LINEAR, "h_0"};
450
451 static const ParamMapping *const paramsSch[] = {
452 ¶mPegLat, ¶mPegLon, ¶mPegHeading, ¶mPegHeight, nullptr};
453
454 static const ParamMapping *const paramsWink1[] = {
455 ¶mLongitudeNatOrigin, ¶mLat1stParallelLatTs, ¶mFalseEasting,
456 ¶mFalseNorthing, nullptr};
457
458 static const ParamMapping *const paramsWink2[] = {
459 ¶mLongitudeNatOrigin, ¶mLatitude1stStdParallel, ¶mFalseEasting,
460 ¶mFalseNorthing, nullptr};
461
462 static const ParamMapping paramLatLoxim = {
463 EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
464 EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN, WKT1_LATITUDE_OF_ORIGIN,
465 common::UnitOfMeasure::Type::ANGULAR, lat_1};
466
467 static const ParamMapping *const paramsLoxim[] = {
468 ¶mLatLoxim, ¶mLongitudeNatOrigin, ¶mFalseEasting,
469 ¶mFalseNorthing, nullptr};
470
471 static const ParamMapping paramLonCentre = {
472 EPSG_NAME_PARAMETER_LONGITUDE_PROJECTION_CENTRE,
473 EPSG_CODE_PARAMETER_LONGITUDE_PROJECTION_CENTRE, WKT1_LONGITUDE_OF_CENTER,
474 common::UnitOfMeasure::Type::ANGULAR, lon_0};
475
476 static const ParamMapping paramLabordeObliqueMercatorAzimuth = {
477 EPSG_NAME_PARAMETER_AZIMUTH_INITIAL_LINE,
478 EPSG_CODE_PARAMETER_AZIMUTH_INITIAL_LINE, WKT1_AZIMUTH,
479 common::UnitOfMeasure::Type::ANGULAR, "azi"};
480
481 static const ParamMapping *const paramsLabordeObliqueMercator[] = {
482 ¶mLatCentreLatCenter,
483 ¶mLonCentre,
484 ¶mLabordeObliqueMercatorAzimuth,
485 ¶mScaleFactorInitialLine,
486 ¶mFalseEasting,
487 ¶mFalseNorthing,
488 nullptr};
489
490 static const ParamMapping paramLatTopoOrigin = {
491 EPSG_NAME_PARAMETER_LATITUDE_TOPOGRAPHIC_ORIGIN,
492 EPSG_CODE_PARAMETER_LATITUDE_TOPOGRAPHIC_ORIGIN, nullptr,
493 common::UnitOfMeasure::Type::ANGULAR, lat_0};
494
495 static const ParamMapping paramLonTopoOrigin = {
496 EPSG_NAME_PARAMETER_LONGITUDE_TOPOGRAPHIC_ORIGIN,
497 EPSG_CODE_PARAMETER_LONGITUDE_TOPOGRAPHIC_ORIGIN, nullptr,
498 common::UnitOfMeasure::Type::ANGULAR, lon_0};
499
500 static const ParamMapping paramHeightTopoOrigin = {
501 EPSG_NAME_PARAMETER_ELLIPSOIDAL_HEIGHT_TOPOCENTRIC_ORIGIN,
502 EPSG_CODE_PARAMETER_ELLIPSOIDAL_HEIGHT_TOPOCENTRIC_ORIGIN, nullptr,
503 common::UnitOfMeasure::Type::LINEAR,
504 nullptr}; // unsupported by PROJ right now
505
506 static const ParamMapping paramViewpointHeight = {
507 EPSG_NAME_PARAMETER_VIEWPOINT_HEIGHT, EPSG_CODE_PARAMETER_VIEWPOINT_HEIGHT,
508 nullptr, common::UnitOfMeasure::Type::LINEAR, "h"};
509
510 static const ParamMapping *const paramsVerticalPerspective[] = {
511 ¶mLatTopoOrigin,
512 ¶mLonTopoOrigin,
513 ¶mHeightTopoOrigin, // unsupported by PROJ right now
514 ¶mViewpointHeight,
515 ¶mFalseEasting, // PROJ addition
516 ¶mFalseNorthing, // PROJ addition
517 nullptr};
518
519 static const ParamMapping paramProjectionPlaneOriginHeight = {
520 EPSG_NAME_PARAMETER_PROJECTION_PLANE_ORIGIN_HEIGHT,
521 EPSG_CODE_PARAMETER_PROJECTION_PLANE_ORIGIN_HEIGHT, nullptr,
522 common::UnitOfMeasure::Type::LINEAR, "h_0"};
523
524 static const ParamMapping *const paramsColombiaUrban[] = {
525 ¶mLatitudeNatOrigin,
526 ¶mLongitudeNatOrigin,
527 ¶mFalseEasting,
528 ¶mFalseNorthing,
529 ¶mProjectionPlaneOriginHeight,
530 nullptr};
531
532 static const MethodMapping projectionMethodMappings[] = {
533 {EPSG_NAME_METHOD_TRANSVERSE_MERCATOR, EPSG_CODE_METHOD_TRANSVERSE_MERCATOR,
534 "Transverse_Mercator", "tmerc", nullptr, paramsNatOriginScaleK},
535
536 {EPSG_NAME_METHOD_TRANSVERSE_MERCATOR_SOUTH_ORIENTATED,
537 EPSG_CODE_METHOD_TRANSVERSE_MERCATOR_SOUTH_ORIENTATED,
538 "Transverse_Mercator_South_Orientated", "tmerc", "axis=wsu",
539 paramsNatOriginScaleK},
540
541 {PROJ_WKT2_NAME_METHOD_TWO_POINT_EQUIDISTANT, 0, "Two_Point_Equidistant",
542 "tpeqd", nullptr, paramsTPEQD},
543
544 {EPSG_NAME_METHOD_TUNISIA_MAPPING_GRID,
545 EPSG_CODE_METHOD_TUNISIA_MAPPING_GRID, "Tunisia_Mapping_Grid", nullptr,
546 nullptr, // no proj equivalent
547 paramsTMG},
548
549 {EPSG_NAME_METHOD_ALBERS_EQUAL_AREA, EPSG_CODE_METHOD_ALBERS_EQUAL_AREA,
550 "Albers_Conic_Equal_Area", "aea", nullptr, paramsAEA},
551
552 {EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_1SP,
553 EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP,
554 "Lambert_Conformal_Conic_1SP", "lcc", nullptr,
__anonf1886f500102() 555 []() {
556 static const ParamMapping paramLatLCC1SP = {
557 EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
558 EPSG_CODE_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
559 WKT1_LATITUDE_OF_ORIGIN, common::UnitOfMeasure::Type::ANGULAR,
560 lat_1};
561
562 static const ParamMapping *const x[] = {
563 ¶mLatLCC1SP, ¶mLongitudeNatOrigin, ¶mScaleFactor,
564 ¶mFalseEasting, ¶mFalseNorthing, nullptr,
565 };
566 return x;
567 }()},
568
569 {EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_2SP,
570 EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP,
571 "Lambert_Conformal_Conic_2SP", "lcc", nullptr, paramsLCC2SP},
572
573 // Oracle WKT
574 {EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_2SP,
575 EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP, "Lambert Conformal Conic",
576 "lcc", nullptr, paramsLCC2SP},
577
578 {EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_MICHIGAN,
579 EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_MICHIGAN,
580 nullptr, // no mapping to WKT1_GDAL
581 "lcc", nullptr, paramsLCC2SPMichigan},
582
583 {EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_BELGIUM,
584 EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_BELGIUM,
585 "Lambert_Conformal_Conic_2SP_Belgium", "lcc",
586 nullptr, // FIXME: this is what is done in GDAL, but the formula of
587 // LCC 2SP
588 // Belgium in the EPSG 7.2 guidance is difference from the regular
589 // LCC 2SP
590 paramsLCC2SP},
591
592 {EPSG_NAME_METHOD_MODIFIED_AZIMUTHAL_EQUIDISTANT,
593 EPSG_CODE_METHOD_MODIFIED_AZIMUTHAL_EQUIDISTANT, "Azimuthal_Equidistant",
594 "aeqd", nullptr, paramsAEQD},
595
596 {EPSG_NAME_METHOD_GUAM_PROJECTION, EPSG_CODE_METHOD_GUAM_PROJECTION,
597 nullptr, // no mapping to GDAL WKT1
598 "aeqd", "guam", paramsNatOrigin},
599
600 {EPSG_NAME_METHOD_BONNE, EPSG_CODE_METHOD_BONNE, "Bonne", "bonne", nullptr,
601 paramsBonne},
602
603 {PROJ_WKT2_NAME_METHOD_COMPACT_MILLER, 0, "Compact_Miller", "comill",
604 nullptr, paramsLonNatOrigin},
605
606 {EPSG_NAME_METHOD_LAMBERT_CYLINDRICAL_EQUAL_AREA_SPHERICAL,
607 EPSG_CODE_METHOD_LAMBERT_CYLINDRICAL_EQUAL_AREA_SPHERICAL,
608 "Cylindrical_Equal_Area", "cea", nullptr, paramsCEA},
609
610 {EPSG_NAME_METHOD_LAMBERT_CYLINDRICAL_EQUAL_AREA,
611 EPSG_CODE_METHOD_LAMBERT_CYLINDRICAL_EQUAL_AREA, "Cylindrical_Equal_Area",
612 "cea", nullptr, paramsCEA},
613
614 {EPSG_NAME_METHOD_CASSINI_SOLDNER, EPSG_CODE_METHOD_CASSINI_SOLDNER,
615 "Cassini_Soldner", "cass", nullptr, paramsNatOrigin},
616
617 {PROJ_WKT2_NAME_METHOD_EQUIDISTANT_CONIC, 0, "Equidistant_Conic", "eqdc",
618 nullptr, paramsEQDC},
619
620 {PROJ_WKT2_NAME_METHOD_ECKERT_I, 0, "Eckert_I", "eck1", nullptr,
621 paramsLonNatOrigin},
622
623 {PROJ_WKT2_NAME_METHOD_ECKERT_II, 0, "Eckert_II", "eck2", nullptr,
624 paramsLonNatOrigin},
625
626 {PROJ_WKT2_NAME_METHOD_ECKERT_III, 0, "Eckert_III", "eck3", nullptr,
627 paramsLonNatOrigin},
628
629 {PROJ_WKT2_NAME_METHOD_ECKERT_IV, 0, "Eckert_IV", "eck4", nullptr,
630 paramsLonNatOrigin},
631
632 {PROJ_WKT2_NAME_METHOD_ECKERT_V, 0, "Eckert_V", "eck5", nullptr,
633 paramsLonNatOrigin},
634
635 {PROJ_WKT2_NAME_METHOD_ECKERT_VI, 0, "Eckert_VI", "eck6", nullptr,
636 paramsLonNatOrigin},
637
638 {EPSG_NAME_METHOD_EQUIDISTANT_CYLINDRICAL,
639 EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL, "Equirectangular", "eqc",
640 nullptr, paramsEqc},
641
642 {EPSG_NAME_METHOD_EQUIDISTANT_CYLINDRICAL_SPHERICAL,
643 EPSG_CODE_METHOD_EQUIDISTANT_CYLINDRICAL_SPHERICAL, "Equirectangular",
644 "eqc", nullptr, paramsEqc},
645
646 {PROJ_WKT2_NAME_METHOD_FLAT_POLAR_QUARTIC, 0, "Flat_Polar_Quartic",
647 "mbtfpq", nullptr, paramsLonNatOrigin},
648
649 {PROJ_WKT2_NAME_METHOD_GALL_STEREOGRAPHIC, 0, "Gall_Stereographic", "gall",
650 nullptr, paramsLonNatOrigin},
651
652 {PROJ_WKT2_NAME_METHOD_GOODE_HOMOLOSINE, 0, "Goode_Homolosine", "goode",
653 nullptr, paramsLonNatOrigin},
654
655 {PROJ_WKT2_NAME_METHOD_INTERRUPTED_GOODE_HOMOLOSINE, 0,
656 "Interrupted_Goode_Homolosine", "igh", nullptr, paramsLonNatOrigin},
657
658 {PROJ_WKT2_NAME_METHOD_INTERRUPTED_GOODE_HOMOLOSINE_OCEAN, 0, nullptr,
659 "igh_o", nullptr, paramsLonNatOrigin},
660
661 // No proper WKT1 representation fr sweep=x
662 {PROJ_WKT2_NAME_METHOD_GEOSTATIONARY_SATELLITE_SWEEP_X, 0, nullptr, "geos",
663 "sweep=x", paramsGeos},
664
665 {PROJ_WKT2_NAME_METHOD_GEOSTATIONARY_SATELLITE_SWEEP_Y, 0,
666 "Geostationary_Satellite", "geos", nullptr, paramsGeos},
667
668 {PROJ_WKT2_NAME_METHOD_GAUSS_SCHREIBER_TRANSVERSE_MERCATOR, 0,
669 "Gauss_Schreiber_Transverse_Mercator", "gstmerc", nullptr,
670 paramsNatOriginScale},
671
672 {PROJ_WKT2_NAME_METHOD_GNOMONIC, 0, "Gnomonic", "gnom", nullptr,
673 paramsNatOrigin},
674
675 {EPSG_NAME_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_A,
676 EPSG_CODE_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_A,
677 "Hotine_Oblique_Mercator", "omerc", "no_uoff", paramsHomVariantA},
678
679 {EPSG_NAME_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_B,
680 EPSG_CODE_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_B,
681 "Hotine_Oblique_Mercator_Azimuth_Center", "omerc", nullptr,
682 paramsHomVariantB},
683
684 {PROJ_WKT2_NAME_METHOD_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN, 0,
685 "Hotine_Oblique_Mercator_Two_Point_Natural_Origin", "omerc", nullptr,
686 paramsHomTwoPoint},
687
688 {PROJ_WKT2_NAME_INTERNATIONAL_MAP_WORLD_POLYCONIC, 0,
689 "International_Map_of_the_World_Polyconic", "imw_p", nullptr, paramsIMWP},
690
691 {EPSG_NAME_METHOD_KROVAK_NORTH_ORIENTED,
692 EPSG_CODE_METHOD_KROVAK_NORTH_ORIENTED, "Krovak", "krovak", nullptr,
693 krovakParameters},
694
695 {EPSG_NAME_METHOD_KROVAK, EPSG_CODE_METHOD_KROVAK, "Krovak", "krovak",
696 "axis=swu", krovakParameters},
697
698 {EPSG_NAME_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA,
699 EPSG_CODE_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA,
700 "Lambert_Azimuthal_Equal_Area", "laea", nullptr, paramsLaea},
701
702 {EPSG_NAME_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA_SPHERICAL,
703 EPSG_CODE_METHOD_LAMBERT_AZIMUTHAL_EQUAL_AREA_SPHERICAL,
704 "Lambert_Azimuthal_Equal_Area", "laea", nullptr, paramsLaea},
705
706 {PROJ_WKT2_NAME_METHOD_MILLER_CYLINDRICAL, 0, "Miller_Cylindrical", "mill",
707 "R_A", paramsMiller},
708
709 {EPSG_NAME_METHOD_MERCATOR_VARIANT_A, EPSG_CODE_METHOD_MERCATOR_VARIANT_A,
710 "Mercator_1SP", "merc", nullptr, paramsMerc1SP},
711
712 {EPSG_NAME_METHOD_MERCATOR_VARIANT_B, EPSG_CODE_METHOD_MERCATOR_VARIANT_B,
713 "Mercator_2SP", "merc", nullptr, paramsMerc2SP},
714
715 {EPSG_NAME_METHOD_POPULAR_VISUALISATION_PSEUDO_MERCATOR,
716 EPSG_CODE_METHOD_POPULAR_VISUALISATION_PSEUDO_MERCATOR,
717 "Popular_Visualisation_Pseudo_Mercator", // particular case actually
718 // handled manually
719 "webmerc", nullptr, paramsNatOrigin},
720
721 {PROJ_WKT2_NAME_METHOD_MOLLWEIDE, 0, "Mollweide", "moll", nullptr,
722 paramsLonNatOrigin},
723
724 {PROJ_WKT2_NAME_METHOD_NATURAL_EARTH, 0, "Natural_Earth", "natearth",
725 nullptr, paramsLonNatOrigin},
726
727 {PROJ_WKT2_NAME_METHOD_NATURAL_EARTH_II, 0, "Natural_Earth_II", "natearth2",
728 nullptr, paramsLonNatOrigin},
729
730 {EPSG_NAME_METHOD_NZMG, EPSG_CODE_METHOD_NZMG, "New_Zealand_Map_Grid",
731 "nzmg", nullptr, paramsNatOrigin},
732
733 {
734 EPSG_NAME_METHOD_OBLIQUE_STEREOGRAPHIC,
735 EPSG_CODE_METHOD_OBLIQUE_STEREOGRAPHIC, "Oblique_Stereographic",
736 "sterea", nullptr, paramsObliqueStereo,
737 },
738
739 {EPSG_NAME_METHOD_ORTHOGRAPHIC, EPSG_CODE_METHOD_ORTHOGRAPHIC,
740 "Orthographic", "ortho", nullptr, paramsNatOrigin},
741
742 {PROJ_WKT2_NAME_ORTHOGRAPHIC_SPHERICAL, 0, "Orthographic", "ortho", "f=0",
743 paramsNatOrigin},
744
745 {PROJ_WKT2_NAME_METHOD_PATTERSON, 0, "Patterson", "patterson", nullptr,
746 paramsLonNatOrigin},
747
748 {EPSG_NAME_METHOD_AMERICAN_POLYCONIC, EPSG_CODE_METHOD_AMERICAN_POLYCONIC,
749 "Polyconic", "poly", nullptr, paramsNatOrigin},
750
751 {EPSG_NAME_METHOD_POLAR_STEREOGRAPHIC_VARIANT_A,
752 EPSG_CODE_METHOD_POLAR_STEREOGRAPHIC_VARIANT_A, "Polar_Stereographic",
753 "stere", nullptr, paramsObliqueStereo},
754
755 {EPSG_NAME_METHOD_POLAR_STEREOGRAPHIC_VARIANT_B,
756 EPSG_CODE_METHOD_POLAR_STEREOGRAPHIC_VARIANT_B, "Polar_Stereographic",
757 "stere", nullptr, paramsPolarStereo},
758
759 {PROJ_WKT2_NAME_METHOD_ROBINSON, 0, "Robinson", "robin", nullptr,
760 paramsLonNatOriginLongitudeCentre},
761
762 {PROJ_WKT2_NAME_METHOD_SINUSOIDAL, 0, "Sinusoidal", "sinu", nullptr,
763 paramsLonNatOriginLongitudeCentre},
764
765 {PROJ_WKT2_NAME_METHOD_STEREOGRAPHIC, 0, "Stereographic", "stere", nullptr,
766 paramsObliqueStereo},
767
768 {PROJ_WKT2_NAME_METHOD_TIMES, 0, "Times", "times", nullptr,
769 paramsLonNatOrigin},
770
771 {PROJ_WKT2_NAME_METHOD_VAN_DER_GRINTEN, 0, "VanDerGrinten", "vandg", "R_A",
772 paramsLonNatOrigin},
773
774 {PROJ_WKT2_NAME_METHOD_WAGNER_I, 0, "Wagner_I", "wag1", nullptr,
775 paramsLonNatOrigin},
776
777 {PROJ_WKT2_NAME_METHOD_WAGNER_II, 0, "Wagner_II", "wag2", nullptr,
778 paramsLonNatOrigin},
779
780 {PROJ_WKT2_NAME_METHOD_WAGNER_III, 0, "Wagner_III", "wag3", nullptr,
781 paramsWag3},
782
783 {PROJ_WKT2_NAME_METHOD_WAGNER_IV, 0, "Wagner_IV", "wag4", nullptr,
784 paramsLonNatOrigin},
785
786 {PROJ_WKT2_NAME_METHOD_WAGNER_V, 0, "Wagner_V", "wag5", nullptr,
787 paramsLonNatOrigin},
788
789 {PROJ_WKT2_NAME_METHOD_WAGNER_VI, 0, "Wagner_VI", "wag6", nullptr,
790 paramsLonNatOrigin},
791
792 {PROJ_WKT2_NAME_METHOD_WAGNER_VII, 0, "Wagner_VII", "wag7", nullptr,
793 paramsLonNatOrigin},
794
795 {PROJ_WKT2_NAME_METHOD_QUADRILATERALIZED_SPHERICAL_CUBE, 0,
796 "Quadrilateralized_Spherical_Cube", "qsc", nullptr, paramsNatOrigin},
797
798 {PROJ_WKT2_NAME_METHOD_SPHERICAL_CROSS_TRACK_HEIGHT, 0,
799 "Spherical_Cross_Track_Height", "sch", nullptr, paramsSch},
800
801 // The following methods have just the WKT <--> PROJ string mapping, but
802 // no setter. Similarly to GDAL
803
804 {"Aitoff", 0, "Aitoff", "aitoff", nullptr, paramsLonNatOrigin},
805
806 {"Winkel I", 0, "Winkel_I", "wink1", nullptr, paramsWink1},
807
808 {"Winkel II", 0, "Winkel_II", "wink2", nullptr, paramsWink2},
809
810 {"Winkel Tripel", 0, "Winkel_Tripel", "wintri", nullptr, paramsWink2},
811
812 {"Craster Parabolic", 0, "Craster_Parabolic", "crast", nullptr,
813 paramsLonNatOrigin},
814
815 {"Loximuthal", 0, "Loximuthal", "loxim", nullptr, paramsLoxim},
816
817 {"Quartic Authalic", 0, "Quartic_Authalic", "qua_aut", nullptr,
818 paramsLonNatOrigin},
819
820 {"Transverse Cylindrical Equal Area", 0,
821 "Transverse_Cylindrical_Equal_Area", "tcea", nullptr, paramsObliqueStereo},
822
823 {EPSG_NAME_METHOD_EQUAL_EARTH, EPSG_CODE_METHOD_EQUAL_EARTH, nullptr,
824 "eqearth", nullptr, paramsLonNatOrigin},
825
826 {EPSG_NAME_METHOD_LABORDE_OBLIQUE_MERCATOR,
827 EPSG_CODE_METHOD_LABORDE_OBLIQUE_MERCATOR, "Laborde_Oblique_Mercator",
828 "labrd", nullptr, paramsLabordeObliqueMercator},
829
830 {EPSG_NAME_METHOD_VERTICAL_PERSPECTIVE,
831 EPSG_CODE_METHOD_VERTICAL_PERSPECTIVE, nullptr, "nsper", nullptr,
832 paramsVerticalPerspective},
833
834 {EPSG_NAME_METHOD_COLOMBIA_URBAN, EPSG_CODE_METHOD_COLOMBIA_URBAN, nullptr,
835 "col_urban", nullptr, paramsColombiaUrban},
836 };
837
getProjectionMethodMappings(size_t & nElts)838 const MethodMapping *getProjectionMethodMappings(size_t &nElts) {
839 nElts =
840 sizeof(projectionMethodMappings) / sizeof(projectionMethodMappings[0]);
841 return projectionMethodMappings;
842 }
843
844 #define METHOD_NAME_CODE(method) \
845 { EPSG_NAME_METHOD_##method, EPSG_CODE_METHOD_##method }
846
847 const struct MethodNameCode methodNameCodes[] = {
848 // Projection methods
849 METHOD_NAME_CODE(TRANSVERSE_MERCATOR),
850 METHOD_NAME_CODE(TRANSVERSE_MERCATOR_SOUTH_ORIENTATED),
851 METHOD_NAME_CODE(LAMBERT_CONIC_CONFORMAL_1SP), METHOD_NAME_CODE(NZMG),
852 METHOD_NAME_CODE(TUNISIA_MAPPING_GRID), METHOD_NAME_CODE(ALBERS_EQUAL_AREA),
853 METHOD_NAME_CODE(LAMBERT_CONIC_CONFORMAL_2SP),
854 METHOD_NAME_CODE(LAMBERT_CONIC_CONFORMAL_2SP_BELGIUM),
855 METHOD_NAME_CODE(LAMBERT_CONIC_CONFORMAL_2SP_MICHIGAN),
856 METHOD_NAME_CODE(MODIFIED_AZIMUTHAL_EQUIDISTANT),
857 METHOD_NAME_CODE(GUAM_PROJECTION), METHOD_NAME_CODE(BONNE),
858 METHOD_NAME_CODE(LAMBERT_CYLINDRICAL_EQUAL_AREA_SPHERICAL),
859 METHOD_NAME_CODE(LAMBERT_CYLINDRICAL_EQUAL_AREA),
860 METHOD_NAME_CODE(CASSINI_SOLDNER),
861 METHOD_NAME_CODE(EQUIDISTANT_CYLINDRICAL),
862 METHOD_NAME_CODE(EQUIDISTANT_CYLINDRICAL_SPHERICAL),
863 METHOD_NAME_CODE(HOTINE_OBLIQUE_MERCATOR_VARIANT_A),
864 METHOD_NAME_CODE(HOTINE_OBLIQUE_MERCATOR_VARIANT_B),
865 METHOD_NAME_CODE(KROVAK_NORTH_ORIENTED), METHOD_NAME_CODE(KROVAK),
866 METHOD_NAME_CODE(LAMBERT_AZIMUTHAL_EQUAL_AREA),
867 METHOD_NAME_CODE(POPULAR_VISUALISATION_PSEUDO_MERCATOR),
868 METHOD_NAME_CODE(MERCATOR_VARIANT_A), METHOD_NAME_CODE(MERCATOR_VARIANT_B),
869 METHOD_NAME_CODE(OBLIQUE_STEREOGRAPHIC),
870 METHOD_NAME_CODE(AMERICAN_POLYCONIC),
871 METHOD_NAME_CODE(POLAR_STEREOGRAPHIC_VARIANT_A),
872 METHOD_NAME_CODE(POLAR_STEREOGRAPHIC_VARIANT_B),
873 METHOD_NAME_CODE(EQUAL_EARTH), METHOD_NAME_CODE(LABORDE_OBLIQUE_MERCATOR),
874 METHOD_NAME_CODE(VERTICAL_PERSPECTIVE), METHOD_NAME_CODE(COLOMBIA_URBAN),
875 // Other conversions
876 METHOD_NAME_CODE(CHANGE_VERTICAL_UNIT),
877 METHOD_NAME_CODE(HEIGHT_DEPTH_REVERSAL),
878 METHOD_NAME_CODE(AXIS_ORDER_REVERSAL_2D),
879 METHOD_NAME_CODE(AXIS_ORDER_REVERSAL_3D),
880 METHOD_NAME_CODE(GEOGRAPHIC_GEOCENTRIC),
881 // Transformations
882 METHOD_NAME_CODE(LONGITUDE_ROTATION),
883 METHOD_NAME_CODE(AFFINE_PARAMETRIC_TRANSFORMATION),
884 METHOD_NAME_CODE(COORDINATE_FRAME_GEOCENTRIC),
885 METHOD_NAME_CODE(COORDINATE_FRAME_GEOGRAPHIC_2D),
886 METHOD_NAME_CODE(COORDINATE_FRAME_GEOGRAPHIC_3D),
887 METHOD_NAME_CODE(POSITION_VECTOR_GEOCENTRIC),
888 METHOD_NAME_CODE(POSITION_VECTOR_GEOGRAPHIC_2D),
889 METHOD_NAME_CODE(POSITION_VECTOR_GEOGRAPHIC_3D),
890 METHOD_NAME_CODE(GEOCENTRIC_TRANSLATION_GEOCENTRIC),
891 METHOD_NAME_CODE(GEOCENTRIC_TRANSLATION_GEOGRAPHIC_2D),
892 METHOD_NAME_CODE(GEOCENTRIC_TRANSLATION_GEOGRAPHIC_3D),
893 METHOD_NAME_CODE(TIME_DEPENDENT_COORDINATE_FRAME_GEOCENTRIC),
894 METHOD_NAME_CODE(TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_2D),
895 METHOD_NAME_CODE(TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_3D),
896 METHOD_NAME_CODE(TIME_DEPENDENT_POSITION_VECTOR_GEOCENTRIC),
897 METHOD_NAME_CODE(TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_2D),
898 METHOD_NAME_CODE(TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_3D),
899 METHOD_NAME_CODE(MOLODENSKY_BADEKAS_CF_GEOCENTRIC),
900 METHOD_NAME_CODE(MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_2D),
901 METHOD_NAME_CODE(MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_3D),
902 METHOD_NAME_CODE(MOLODENSKY_BADEKAS_PV_GEOCENTRIC),
903 METHOD_NAME_CODE(MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_2D),
904 METHOD_NAME_CODE(MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_3D),
905 METHOD_NAME_CODE(MOLODENSKY), METHOD_NAME_CODE(ABRIDGED_MOLODENSKY),
906 METHOD_NAME_CODE(GEOGRAPHIC2D_OFFSETS),
907 METHOD_NAME_CODE(GEOGRAPHIC2D_WITH_HEIGHT_OFFSETS),
908 METHOD_NAME_CODE(GEOGRAPHIC3D_OFFSETS), METHOD_NAME_CODE(VERTICAL_OFFSET),
909 METHOD_NAME_CODE(NTV2), METHOD_NAME_CODE(NTV1), METHOD_NAME_CODE(NADCON),
910 METHOD_NAME_CODE(VERTCON),
911 METHOD_NAME_CODE(GEOCENTRIC_TRANSLATION_BY_GRID_INTERPOLATION_IGN),
912 };
913
getMethodNameCodes(size_t & nElts)914 const MethodNameCode *getMethodNameCodes(size_t &nElts) {
915 nElts = sizeof(methodNameCodes) / sizeof(methodNameCodes[0]);
916 return methodNameCodes;
917 }
918
919 #define PARAM_NAME_CODE(method) \
920 { EPSG_NAME_PARAMETER_##method, EPSG_CODE_PARAMETER_##method }
921
922 const struct ParamNameCode paramNameCodes[] = {
923 // Parameters of projection methods
924 PARAM_NAME_CODE(COLATITUDE_CONE_AXIS),
925 PARAM_NAME_CODE(LATITUDE_OF_NATURAL_ORIGIN),
926 PARAM_NAME_CODE(LONGITUDE_OF_NATURAL_ORIGIN),
927 PARAM_NAME_CODE(SCALE_FACTOR_AT_NATURAL_ORIGIN),
928 PARAM_NAME_CODE(FALSE_EASTING), PARAM_NAME_CODE(FALSE_NORTHING),
929 PARAM_NAME_CODE(LATITUDE_PROJECTION_CENTRE),
930 PARAM_NAME_CODE(LONGITUDE_PROJECTION_CENTRE),
931 PARAM_NAME_CODE(AZIMUTH_INITIAL_LINE),
932 PARAM_NAME_CODE(ANGLE_RECTIFIED_TO_SKEW_GRID),
933 PARAM_NAME_CODE(SCALE_FACTOR_INITIAL_LINE),
934 PARAM_NAME_CODE(EASTING_PROJECTION_CENTRE),
935 PARAM_NAME_CODE(NORTHING_PROJECTION_CENTRE),
936 PARAM_NAME_CODE(LATITUDE_PSEUDO_STANDARD_PARALLEL),
937 PARAM_NAME_CODE(SCALE_FACTOR_PSEUDO_STANDARD_PARALLEL),
938 PARAM_NAME_CODE(LATITUDE_FALSE_ORIGIN),
939 PARAM_NAME_CODE(LONGITUDE_FALSE_ORIGIN),
940 PARAM_NAME_CODE(LATITUDE_1ST_STD_PARALLEL),
941 PARAM_NAME_CODE(LATITUDE_2ND_STD_PARALLEL),
942 PARAM_NAME_CODE(EASTING_FALSE_ORIGIN),
943 PARAM_NAME_CODE(NORTHING_FALSE_ORIGIN),
944 PARAM_NAME_CODE(LATITUDE_STD_PARALLEL),
945 PARAM_NAME_CODE(LONGITUDE_OF_ORIGIN),
946 PARAM_NAME_CODE(ELLIPSOID_SCALE_FACTOR),
947 PARAM_NAME_CODE(PROJECTION_PLANE_ORIGIN_HEIGHT),
948 // Parameters of transformations
949 PARAM_NAME_CODE(SEMI_MAJOR_AXIS_DIFFERENCE),
950 PARAM_NAME_CODE(FLATTENING_DIFFERENCE),
951 PARAM_NAME_CODE(LATITUDE_LONGITUDE_DIFFERENCE_FILE),
952 PARAM_NAME_CODE(GEOID_CORRECTION_FILENAME),
953 PARAM_NAME_CODE(VERTICAL_OFFSET_FILE),
954 PARAM_NAME_CODE(LATITUDE_DIFFERENCE_FILE),
955 PARAM_NAME_CODE(LONGITUDE_DIFFERENCE_FILE),
956 PARAM_NAME_CODE(UNIT_CONVERSION_SCALAR), PARAM_NAME_CODE(LATITUDE_OFFSET),
957 PARAM_NAME_CODE(LONGITUDE_OFFSET), PARAM_NAME_CODE(VERTICAL_OFFSET),
958 PARAM_NAME_CODE(GEOID_UNDULATION), PARAM_NAME_CODE(A0), PARAM_NAME_CODE(A1),
959 PARAM_NAME_CODE(A2), PARAM_NAME_CODE(B0), PARAM_NAME_CODE(B1),
960 PARAM_NAME_CODE(B2), PARAM_NAME_CODE(X_AXIS_TRANSLATION),
961 PARAM_NAME_CODE(Y_AXIS_TRANSLATION), PARAM_NAME_CODE(Z_AXIS_TRANSLATION),
962 PARAM_NAME_CODE(X_AXIS_ROTATION), PARAM_NAME_CODE(Y_AXIS_ROTATION),
963 PARAM_NAME_CODE(Z_AXIS_ROTATION), PARAM_NAME_CODE(SCALE_DIFFERENCE),
964 PARAM_NAME_CODE(RATE_X_AXIS_TRANSLATION),
965 PARAM_NAME_CODE(RATE_Y_AXIS_TRANSLATION),
966 PARAM_NAME_CODE(RATE_Z_AXIS_TRANSLATION),
967 PARAM_NAME_CODE(RATE_X_AXIS_ROTATION),
968 PARAM_NAME_CODE(RATE_Y_AXIS_ROTATION),
969 PARAM_NAME_CODE(RATE_Z_AXIS_ROTATION),
970 PARAM_NAME_CODE(RATE_SCALE_DIFFERENCE), PARAM_NAME_CODE(REFERENCE_EPOCH),
971 PARAM_NAME_CODE(TRANSFORMATION_REFERENCE_EPOCH),
972 PARAM_NAME_CODE(ORDINATE_1_EVAL_POINT),
973 PARAM_NAME_CODE(ORDINATE_2_EVAL_POINT),
974 PARAM_NAME_CODE(ORDINATE_3_EVAL_POINT),
975 PARAM_NAME_CODE(GEOCENTRIC_TRANSLATION_FILE),
976 };
977
getParamNameCodes(size_t & nElts)978 const ParamNameCode *getParamNameCodes(size_t &nElts) {
979 nElts = sizeof(paramNameCodes) / sizeof(paramNameCodes[0]);
980 return paramNameCodes;
981 }
982
983 static const ParamMapping paramUnitConversionScalar = {
984 EPSG_NAME_PARAMETER_UNIT_CONVERSION_SCALAR,
985 EPSG_CODE_PARAMETER_UNIT_CONVERSION_SCALAR, nullptr,
986 common::UnitOfMeasure::Type::SCALE, nullptr};
987
988 static const ParamMapping *const paramsChangeVerticalUnit[] = {
989 ¶mUnitConversionScalar, nullptr};
990
991 static const ParamMapping paramLongitudeOffset = {
992 EPSG_NAME_PARAMETER_LONGITUDE_OFFSET, EPSG_CODE_PARAMETER_LONGITUDE_OFFSET,
993 nullptr, common::UnitOfMeasure::Type::ANGULAR, nullptr};
994
995 static const ParamMapping *const paramsLongitudeRotation[] = {
996 ¶mLongitudeOffset, nullptr};
997
998 static const ParamMapping paramA0 = {
999 EPSG_NAME_PARAMETER_A0, EPSG_CODE_PARAMETER_A0, nullptr,
1000 common::UnitOfMeasure::Type::UNKNOWN, nullptr};
1001
1002 static const ParamMapping paramA1 = {
1003 EPSG_NAME_PARAMETER_A1, EPSG_CODE_PARAMETER_A1, nullptr,
1004 common::UnitOfMeasure::Type::UNKNOWN, nullptr};
1005
1006 static const ParamMapping paramA2 = {
1007 EPSG_NAME_PARAMETER_A2, EPSG_CODE_PARAMETER_A2, nullptr,
1008 common::UnitOfMeasure::Type::UNKNOWN, nullptr};
1009
1010 static const ParamMapping paramB0 = {
1011 EPSG_NAME_PARAMETER_B0, EPSG_CODE_PARAMETER_B0, nullptr,
1012 common::UnitOfMeasure::Type::UNKNOWN, nullptr};
1013
1014 static const ParamMapping paramB1 = {
1015 EPSG_NAME_PARAMETER_B1, EPSG_CODE_PARAMETER_B1, nullptr,
1016 common::UnitOfMeasure::Type::UNKNOWN, nullptr};
1017
1018 static const ParamMapping paramB2 = {
1019 EPSG_NAME_PARAMETER_B2, EPSG_CODE_PARAMETER_B2, nullptr,
1020 common::UnitOfMeasure::Type::UNKNOWN, nullptr};
1021
1022 static const ParamMapping *const paramsAffineParametricTransformation[] = {
1023 ¶mA0, ¶mA1, ¶mA2, ¶mB0, ¶mB1, ¶mB2, nullptr};
1024
1025 static const ParamMapping paramXTranslation = {
1026 EPSG_NAME_PARAMETER_X_AXIS_TRANSLATION,
1027 EPSG_CODE_PARAMETER_X_AXIS_TRANSLATION, nullptr,
1028 common::UnitOfMeasure::Type::LINEAR, nullptr};
1029
1030 static const ParamMapping paramYTranslation = {
1031 EPSG_NAME_PARAMETER_Y_AXIS_TRANSLATION,
1032 EPSG_CODE_PARAMETER_Y_AXIS_TRANSLATION, nullptr,
1033 common::UnitOfMeasure::Type::LINEAR, nullptr};
1034
1035 static const ParamMapping paramZTranslation = {
1036 EPSG_NAME_PARAMETER_Z_AXIS_TRANSLATION,
1037 EPSG_CODE_PARAMETER_Z_AXIS_TRANSLATION, nullptr,
1038 common::UnitOfMeasure::Type::LINEAR, nullptr};
1039
1040 static const ParamMapping paramXRotation = {
1041 EPSG_NAME_PARAMETER_X_AXIS_ROTATION, EPSG_CODE_PARAMETER_X_AXIS_ROTATION,
1042 nullptr, common::UnitOfMeasure::Type::LINEAR, nullptr};
1043
1044 static const ParamMapping paramYRotation = {
1045 EPSG_NAME_PARAMETER_Y_AXIS_ROTATION, EPSG_CODE_PARAMETER_Y_AXIS_ROTATION,
1046 nullptr, common::UnitOfMeasure::Type::LINEAR, nullptr};
1047
1048 static const ParamMapping paramZRotation = {
1049 EPSG_NAME_PARAMETER_Z_AXIS_ROTATION, EPSG_CODE_PARAMETER_Z_AXIS_ROTATION,
1050 nullptr, common::UnitOfMeasure::Type::LINEAR, nullptr};
1051
1052 static const ParamMapping paramScaleDifference = {
1053 EPSG_NAME_PARAMETER_SCALE_DIFFERENCE, EPSG_CODE_PARAMETER_SCALE_DIFFERENCE,
1054 nullptr, common::UnitOfMeasure::Type::SCALE, nullptr};
1055
1056 static const ParamMapping *const paramsHelmert3[] = {
1057 ¶mXTranslation, ¶mYTranslation, ¶mZTranslation, nullptr};
1058
1059 static const ParamMapping *const paramsHelmert7[] = {
1060 ¶mXTranslation, ¶mYTranslation,
1061 ¶mZTranslation, ¶mXRotation,
1062 ¶mYRotation, ¶mZRotation,
1063 ¶mScaleDifference, nullptr};
1064
1065 static const ParamMapping paramRateXTranslation = {
1066 EPSG_NAME_PARAMETER_RATE_X_AXIS_TRANSLATION,
1067 EPSG_CODE_PARAMETER_RATE_X_AXIS_TRANSLATION, nullptr,
1068 common::UnitOfMeasure::Type::LINEAR, nullptr};
1069
1070 static const ParamMapping paramRateYTranslation = {
1071 EPSG_NAME_PARAMETER_RATE_Y_AXIS_TRANSLATION,
1072 EPSG_CODE_PARAMETER_RATE_Y_AXIS_TRANSLATION, nullptr,
1073 common::UnitOfMeasure::Type::LINEAR, nullptr};
1074
1075 static const ParamMapping paramRateZTranslation = {
1076 EPSG_NAME_PARAMETER_RATE_Z_AXIS_TRANSLATION,
1077 EPSG_CODE_PARAMETER_RATE_Z_AXIS_TRANSLATION, nullptr,
1078 common::UnitOfMeasure::Type::LINEAR, nullptr};
1079
1080 static const ParamMapping paramRateXRotation = {
1081 EPSG_NAME_PARAMETER_RATE_X_AXIS_ROTATION,
1082 EPSG_CODE_PARAMETER_RATE_X_AXIS_ROTATION, nullptr,
1083 common::UnitOfMeasure::Type::LINEAR, nullptr};
1084
1085 static const ParamMapping paramRateYRotation = {
1086 EPSG_NAME_PARAMETER_RATE_Y_AXIS_ROTATION,
1087 EPSG_CODE_PARAMETER_RATE_Y_AXIS_ROTATION, nullptr,
1088 common::UnitOfMeasure::Type::LINEAR, nullptr};
1089
1090 static const ParamMapping paramRateZRotation = {
1091 EPSG_NAME_PARAMETER_RATE_Z_AXIS_ROTATION,
1092 EPSG_CODE_PARAMETER_RATE_Z_AXIS_ROTATION, nullptr,
1093 common::UnitOfMeasure::Type::LINEAR, nullptr};
1094
1095 static const ParamMapping paramRateScaleDifference = {
1096 EPSG_NAME_PARAMETER_RATE_SCALE_DIFFERENCE,
1097 EPSG_CODE_PARAMETER_RATE_SCALE_DIFFERENCE, nullptr,
1098 common::UnitOfMeasure::Type::SCALE, nullptr};
1099
1100 static const ParamMapping paramReferenceEpoch = {
1101 EPSG_NAME_PARAMETER_REFERENCE_EPOCH, EPSG_CODE_PARAMETER_REFERENCE_EPOCH,
1102 nullptr, common::UnitOfMeasure::Type::TIME, nullptr};
1103
1104 static const ParamMapping *const paramsHelmert15[] = {
1105 ¶mXTranslation, ¶mYTranslation,
1106 ¶mZTranslation, ¶mXRotation,
1107 ¶mYRotation, ¶mZRotation,
1108 ¶mScaleDifference, ¶mRateXTranslation,
1109 ¶mRateYTranslation, ¶mRateZTranslation,
1110 ¶mRateXRotation, ¶mRateYRotation,
1111 ¶mRateZRotation, ¶mRateScaleDifference,
1112 ¶mReferenceEpoch, nullptr};
1113
1114 static const ParamMapping paramOrdinate1EvalPoint = {
1115 EPSG_NAME_PARAMETER_ORDINATE_1_EVAL_POINT,
1116 EPSG_CODE_PARAMETER_ORDINATE_1_EVAL_POINT, nullptr,
1117 common::UnitOfMeasure::Type::LINEAR, nullptr};
1118
1119 static const ParamMapping paramOrdinate2EvalPoint = {
1120 EPSG_NAME_PARAMETER_ORDINATE_2_EVAL_POINT,
1121 EPSG_CODE_PARAMETER_ORDINATE_2_EVAL_POINT, nullptr,
1122 common::UnitOfMeasure::Type::LINEAR, nullptr};
1123
1124 static const ParamMapping paramOrdinate3EvalPoint = {
1125 EPSG_NAME_PARAMETER_ORDINATE_3_EVAL_POINT,
1126 EPSG_CODE_PARAMETER_ORDINATE_3_EVAL_POINT, nullptr,
1127 common::UnitOfMeasure::Type::LINEAR, nullptr};
1128
1129 static const ParamMapping *const paramsMolodenskyBadekas[] = {
1130 ¶mXTranslation,
1131 ¶mYTranslation,
1132 ¶mZTranslation,
1133 ¶mXRotation,
1134 ¶mYRotation,
1135 ¶mZRotation,
1136 ¶mScaleDifference,
1137 ¶mOrdinate1EvalPoint,
1138 ¶mOrdinate2EvalPoint,
1139 ¶mOrdinate3EvalPoint,
1140 nullptr};
1141
1142 static const ParamMapping paramSemiMajorAxisDifference = {
1143 EPSG_NAME_PARAMETER_SEMI_MAJOR_AXIS_DIFFERENCE,
1144 EPSG_CODE_PARAMETER_SEMI_MAJOR_AXIS_DIFFERENCE, nullptr,
1145 common::UnitOfMeasure::Type::LINEAR, nullptr};
1146
1147 static const ParamMapping paramFlatteningDifference = {
1148 EPSG_NAME_PARAMETER_FLATTENING_DIFFERENCE,
1149 EPSG_CODE_PARAMETER_FLATTENING_DIFFERENCE, nullptr,
1150 common::UnitOfMeasure::Type::NONE, nullptr};
1151
1152 static const ParamMapping *const paramsMolodensky[] = {
1153 ¶mXTranslation, ¶mYTranslation,
1154 ¶mZTranslation, ¶mSemiMajorAxisDifference,
1155 ¶mFlatteningDifference, nullptr};
1156
1157 static const ParamMapping paramLatitudeOffset = {
1158 EPSG_NAME_PARAMETER_LATITUDE_OFFSET, EPSG_CODE_PARAMETER_LATITUDE_OFFSET,
1159 nullptr, common::UnitOfMeasure::Type::ANGULAR, nullptr};
1160
1161 static const ParamMapping *const paramsGeographic2DOffsets[] = {
1162 ¶mLatitudeOffset, ¶mLongitudeOffset, nullptr};
1163
1164 static const ParamMapping paramGeoidUndulation = {
1165 EPSG_NAME_PARAMETER_GEOID_UNDULATION, EPSG_CODE_PARAMETER_GEOID_UNDULATION,
1166 nullptr, common::UnitOfMeasure::Type::LINEAR, nullptr};
1167
1168 static const ParamMapping *const paramsGeographic2DWithHeightOffsets[] = {
1169 ¶mLatitudeOffset, ¶mLongitudeOffset, ¶mGeoidUndulation,
1170 nullptr};
1171
1172 static const ParamMapping paramVerticalOffset = {
1173 EPSG_NAME_PARAMETER_VERTICAL_OFFSET, EPSG_CODE_PARAMETER_VERTICAL_OFFSET,
1174 nullptr, common::UnitOfMeasure::Type::LINEAR, nullptr};
1175
1176 static const ParamMapping *const paramsGeographic3DOffsets[] = {
1177 ¶mLatitudeOffset, ¶mLongitudeOffset, ¶mVerticalOffset, nullptr};
1178
1179 static const ParamMapping *const paramsVerticalOffsets[] = {
1180 ¶mVerticalOffset, nullptr};
1181
1182 static const ParamMapping paramLatitudeLongitudeDifferenceFile = {
1183 EPSG_NAME_PARAMETER_LATITUDE_LONGITUDE_DIFFERENCE_FILE,
1184 EPSG_CODE_PARAMETER_LATITUDE_LONGITUDE_DIFFERENCE_FILE, nullptr,
1185 common::UnitOfMeasure::Type::NONE, nullptr};
1186
1187 static const ParamMapping *const paramsNTV2[] = {
1188 ¶mLatitudeLongitudeDifferenceFile, nullptr};
1189
1190 static const ParamMapping paramGeocentricTranslationFile = {
1191 EPSG_NAME_PARAMETER_GEOCENTRIC_TRANSLATION_FILE,
1192 EPSG_CODE_PARAMETER_GEOCENTRIC_TRANSLATION_FILE, nullptr,
1193 common::UnitOfMeasure::Type::NONE, nullptr};
1194
1195 static const ParamMapping
1196 *const paramsGeocentricTranslationGridInterpolationIGN[] = {
1197 ¶mGeocentricTranslationFile, nullptr};
1198
1199 static const ParamMapping paramLatitudeDifferenceFile = {
1200 EPSG_NAME_PARAMETER_LATITUDE_DIFFERENCE_FILE,
1201 EPSG_CODE_PARAMETER_LATITUDE_DIFFERENCE_FILE, nullptr,
1202 common::UnitOfMeasure::Type::NONE, nullptr};
1203
1204 static const ParamMapping paramLongitudeDifferenceFile = {
1205 EPSG_NAME_PARAMETER_LONGITUDE_DIFFERENCE_FILE,
1206 EPSG_CODE_PARAMETER_LONGITUDE_DIFFERENCE_FILE, nullptr,
1207 common::UnitOfMeasure::Type::NONE, nullptr};
1208
1209 static const ParamMapping *const paramsNADCON[] = {
1210 ¶mLatitudeDifferenceFile, ¶mLongitudeDifferenceFile, nullptr};
1211
1212 static const ParamMapping paramVerticalOffsetFile = {
1213 EPSG_NAME_PARAMETER_VERTICAL_OFFSET_FILE,
1214 EPSG_CODE_PARAMETER_VERTICAL_OFFSET_FILE, nullptr,
1215 common::UnitOfMeasure::Type::NONE, nullptr};
1216
1217 static const ParamMapping *const paramsVERTCON[] = {¶mVerticalOffsetFile,
1218 nullptr};
1219
1220 static const ParamMapping paramSouthPoleLatGRIB = {
1221 PROJ_WKT2_NAME_PARAMETER_SOUTH_POLE_LATITUDE_GRIB_CONVENTION, 0, nullptr,
1222 common::UnitOfMeasure::Type::ANGULAR, nullptr};
1223
1224 static const ParamMapping paramSouthPoleLonGRIB = {
1225 PROJ_WKT2_NAME_PARAMETER_SOUTH_POLE_LONGITUDE_GRIB_CONVENTION, 0, nullptr,
1226 common::UnitOfMeasure::Type::ANGULAR, nullptr};
1227
1228 static const ParamMapping paramAxisRotationGRIB = {
1229 PROJ_WKT2_NAME_PARAMETER_AXIS_ROTATION_GRIB_CONVENTION, 0, nullptr,
1230 common::UnitOfMeasure::Type::ANGULAR, nullptr};
1231
1232 static const ParamMapping *const paramsPoleRotationGRIBConvention[] = {
1233 ¶mSouthPoleLatGRIB, ¶mSouthPoleLonGRIB, ¶mAxisRotationGRIB,
1234 nullptr};
1235
1236 static const MethodMapping otherMethodMappings[] = {
1237 {EPSG_NAME_METHOD_CHANGE_VERTICAL_UNIT,
1238 EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT, nullptr, nullptr, nullptr,
1239 paramsChangeVerticalUnit},
1240 {EPSG_NAME_METHOD_HEIGHT_DEPTH_REVERSAL,
1241 EPSG_CODE_METHOD_HEIGHT_DEPTH_REVERSAL, nullptr, nullptr, nullptr,
1242 paramsChangeVerticalUnit},
1243 {EPSG_NAME_METHOD_AXIS_ORDER_REVERSAL_2D,
1244 EPSG_CODE_METHOD_AXIS_ORDER_REVERSAL_2D, nullptr, nullptr, nullptr,
1245 nullptr},
1246 {EPSG_NAME_METHOD_AXIS_ORDER_REVERSAL_3D,
1247 EPSG_CODE_METHOD_AXIS_ORDER_REVERSAL_3D, nullptr, nullptr, nullptr,
1248 nullptr},
1249 {EPSG_NAME_METHOD_GEOGRAPHIC_GEOCENTRIC,
1250 EPSG_CODE_METHOD_GEOGRAPHIC_GEOCENTRIC, nullptr, nullptr, nullptr,
1251 nullptr},
1252 {EPSG_NAME_METHOD_LONGITUDE_ROTATION, EPSG_CODE_METHOD_LONGITUDE_ROTATION,
1253 nullptr, nullptr, nullptr, paramsLongitudeRotation},
1254 {EPSG_NAME_METHOD_AFFINE_PARAMETRIC_TRANSFORMATION,
1255 EPSG_CODE_METHOD_AFFINE_PARAMETRIC_TRANSFORMATION, nullptr, nullptr,
1256 nullptr, paramsAffineParametricTransformation},
1257
1258 {PROJ_WKT2_NAME_METHOD_POLE_ROTATION_GRIB_CONVENTION, 0, nullptr, nullptr,
1259 nullptr, paramsPoleRotationGRIBConvention},
1260
1261 {EPSG_NAME_METHOD_GEOCENTRIC_TRANSLATION_GEOCENTRIC,
1262 EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_GEOCENTRIC, nullptr, nullptr,
1263 nullptr, paramsHelmert3},
1264 {EPSG_NAME_METHOD_GEOCENTRIC_TRANSLATION_GEOGRAPHIC_2D,
1265 EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_GEOGRAPHIC_2D, nullptr, nullptr,
1266 nullptr, paramsHelmert3},
1267 {EPSG_NAME_METHOD_GEOCENTRIC_TRANSLATION_GEOGRAPHIC_3D,
1268 EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_GEOGRAPHIC_3D, nullptr, nullptr,
1269 nullptr, paramsHelmert3},
1270
1271 {EPSG_NAME_METHOD_COORDINATE_FRAME_GEOCENTRIC,
1272 EPSG_CODE_METHOD_COORDINATE_FRAME_GEOCENTRIC, nullptr, nullptr, nullptr,
1273 paramsHelmert7},
1274 {EPSG_NAME_METHOD_COORDINATE_FRAME_GEOGRAPHIC_2D,
1275 EPSG_CODE_METHOD_COORDINATE_FRAME_GEOGRAPHIC_2D, nullptr, nullptr, nullptr,
1276 paramsHelmert7},
1277 {EPSG_NAME_METHOD_COORDINATE_FRAME_GEOGRAPHIC_3D,
1278 EPSG_CODE_METHOD_COORDINATE_FRAME_GEOGRAPHIC_3D, nullptr, nullptr, nullptr,
1279 paramsHelmert7},
1280
1281 {EPSG_NAME_METHOD_POSITION_VECTOR_GEOCENTRIC,
1282 EPSG_CODE_METHOD_POSITION_VECTOR_GEOCENTRIC, nullptr, nullptr, nullptr,
1283 paramsHelmert7},
1284 {EPSG_NAME_METHOD_POSITION_VECTOR_GEOGRAPHIC_2D,
1285 EPSG_CODE_METHOD_POSITION_VECTOR_GEOGRAPHIC_2D, nullptr, nullptr, nullptr,
1286 paramsHelmert7},
1287 {EPSG_NAME_METHOD_POSITION_VECTOR_GEOGRAPHIC_3D,
1288 EPSG_CODE_METHOD_POSITION_VECTOR_GEOGRAPHIC_3D, nullptr, nullptr, nullptr,
1289 paramsHelmert7},
1290
1291 {EPSG_NAME_METHOD_TIME_DEPENDENT_COORDINATE_FRAME_GEOCENTRIC,
1292 EPSG_CODE_METHOD_TIME_DEPENDENT_COORDINATE_FRAME_GEOCENTRIC, nullptr,
1293 nullptr, nullptr, paramsHelmert15},
1294 {EPSG_NAME_METHOD_TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_2D,
1295 EPSG_CODE_METHOD_TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_2D, nullptr,
1296 nullptr, nullptr, paramsHelmert15},
1297 {EPSG_NAME_METHOD_TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_3D,
1298 EPSG_CODE_METHOD_TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_3D, nullptr,
1299 nullptr, nullptr, paramsHelmert15},
1300
1301 {EPSG_NAME_METHOD_TIME_DEPENDENT_POSITION_VECTOR_GEOCENTRIC,
1302 EPSG_CODE_METHOD_TIME_DEPENDENT_POSITION_VECTOR_GEOCENTRIC, nullptr,
1303 nullptr, nullptr, paramsHelmert15},
1304 {EPSG_NAME_METHOD_TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_2D,
1305 EPSG_CODE_METHOD_TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_2D, nullptr,
1306 nullptr, nullptr, paramsHelmert15},
1307 {EPSG_NAME_METHOD_TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_3D,
1308 EPSG_CODE_METHOD_TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_3D, nullptr,
1309 nullptr, nullptr, paramsHelmert15},
1310
1311 {EPSG_NAME_METHOD_MOLODENSKY_BADEKAS_CF_GEOCENTRIC,
1312 EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_CF_GEOCENTRIC, nullptr, nullptr,
1313 nullptr, paramsMolodenskyBadekas},
1314 {EPSG_NAME_METHOD_MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_2D,
1315 EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_2D, nullptr, nullptr,
1316 nullptr, paramsMolodenskyBadekas},
1317 {EPSG_NAME_METHOD_MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_3D,
1318 EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_3D, nullptr, nullptr,
1319 nullptr, paramsMolodenskyBadekas},
1320
1321 {EPSG_NAME_METHOD_MOLODENSKY_BADEKAS_PV_GEOCENTRIC,
1322 EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_PV_GEOCENTRIC, nullptr, nullptr,
1323 nullptr, paramsMolodenskyBadekas},
1324 {EPSG_NAME_METHOD_MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_2D,
1325 EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_2D, nullptr, nullptr,
1326 nullptr, paramsMolodenskyBadekas},
1327 {EPSG_NAME_METHOD_MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_3D,
1328 EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_3D, nullptr, nullptr,
1329 nullptr, paramsMolodenskyBadekas},
1330
1331 {EPSG_NAME_METHOD_MOLODENSKY, EPSG_CODE_METHOD_MOLODENSKY, nullptr, nullptr,
1332 nullptr, paramsMolodensky},
1333
1334 {EPSG_NAME_METHOD_ABRIDGED_MOLODENSKY, EPSG_CODE_METHOD_ABRIDGED_MOLODENSKY,
1335 nullptr, nullptr, nullptr, paramsMolodensky},
1336
1337 {EPSG_NAME_METHOD_GEOGRAPHIC2D_OFFSETS,
1338 EPSG_CODE_METHOD_GEOGRAPHIC2D_OFFSETS, nullptr, nullptr, nullptr,
1339 paramsGeographic2DOffsets},
1340
1341 {EPSG_NAME_METHOD_GEOGRAPHIC2D_WITH_HEIGHT_OFFSETS,
1342 EPSG_CODE_METHOD_GEOGRAPHIC2D_WITH_HEIGHT_OFFSETS, nullptr, nullptr,
1343 nullptr, paramsGeographic2DWithHeightOffsets},
1344
1345 {EPSG_NAME_METHOD_GEOGRAPHIC3D_OFFSETS,
1346 EPSG_CODE_METHOD_GEOGRAPHIC3D_OFFSETS, nullptr, nullptr, nullptr,
1347 paramsGeographic3DOffsets},
1348
1349 {EPSG_NAME_METHOD_VERTICAL_OFFSET, EPSG_CODE_METHOD_VERTICAL_OFFSET,
1350 nullptr, nullptr, nullptr, paramsVerticalOffsets},
1351
1352 {EPSG_NAME_METHOD_NTV2, EPSG_CODE_METHOD_NTV2, nullptr, nullptr, nullptr,
1353 paramsNTV2},
1354
1355 {EPSG_NAME_METHOD_NTV1, EPSG_CODE_METHOD_NTV1, nullptr, nullptr, nullptr,
1356 paramsNTV2},
1357
1358 {EPSG_NAME_METHOD_GEOCENTRIC_TRANSLATION_BY_GRID_INTERPOLATION_IGN,
1359 EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_BY_GRID_INTERPOLATION_IGN, nullptr,
1360 nullptr, nullptr, paramsGeocentricTranslationGridInterpolationIGN},
1361
1362 {EPSG_NAME_METHOD_NADCON, EPSG_CODE_METHOD_NADCON, nullptr, nullptr,
1363 nullptr, paramsNADCON},
1364
1365 {EPSG_NAME_METHOD_VERTCON, EPSG_CODE_METHOD_VERTCON, nullptr, nullptr,
1366 nullptr, paramsVERTCON},
1367 {EPSG_NAME_METHOD_VERTCON_OLDNAME, EPSG_CODE_METHOD_VERTCON, nullptr,
1368 nullptr, nullptr, paramsVERTCON},
1369 };
1370
getOtherMethodMappings(size_t & nElts)1371 const MethodMapping *getOtherMethodMappings(size_t &nElts) {
1372 nElts = sizeof(otherMethodMappings) / sizeof(otherMethodMappings[0]);
1373 return otherMethodMappings;
1374 }
1375
1376 // ---------------------------------------------------------------------------
1377
getMapping(int epsg_code)1378 PROJ_NO_INLINE const MethodMapping *getMapping(int epsg_code) noexcept {
1379 for (const auto &mapping : projectionMethodMappings) {
1380 if (mapping.epsg_code == epsg_code) {
1381 return &mapping;
1382 }
1383 }
1384 return nullptr;
1385 }
1386
1387 // ---------------------------------------------------------------------------
1388
getMapping(const OperationMethod * method)1389 const MethodMapping *getMapping(const OperationMethod *method) noexcept {
1390 const std::string &name(method->nameStr());
1391 const int epsg_code = method->getEPSGCode();
1392 for (const auto &mapping : projectionMethodMappings) {
1393 if ((epsg_code != 0 && mapping.epsg_code == epsg_code) ||
1394 metadata::Identifier::isEquivalentName(mapping.wkt2_name,
1395 name.c_str())) {
1396 return &mapping;
1397 }
1398 }
1399 return nullptr;
1400 }
1401
1402 // ---------------------------------------------------------------------------
1403
getMappingFromWKT1(const std::string & wkt1_name)1404 const MethodMapping *getMappingFromWKT1(const std::string &wkt1_name) noexcept {
1405 // Unusual for a WKT1 projection name, but mentioned in OGC 12-063r5 C.4.2
1406 if (ci_starts_with(wkt1_name, "UTM zone")) {
1407 return getMapping(EPSG_CODE_METHOD_TRANSVERSE_MERCATOR);
1408 }
1409
1410 for (const auto &mapping : projectionMethodMappings) {
1411 if (mapping.wkt1_name && metadata::Identifier::isEquivalentName(
1412 mapping.wkt1_name, wkt1_name.c_str())) {
1413 return &mapping;
1414 }
1415 }
1416 return nullptr;
1417 }
1418 // ---------------------------------------------------------------------------
1419
getMapping(const char * wkt2_name)1420 const MethodMapping *getMapping(const char *wkt2_name) noexcept {
1421 for (const auto &mapping : projectionMethodMappings) {
1422 if (metadata::Identifier::isEquivalentName(mapping.wkt2_name,
1423 wkt2_name)) {
1424 return &mapping;
1425 }
1426 }
1427 for (const auto &mapping : otherMethodMappings) {
1428 if (metadata::Identifier::isEquivalentName(mapping.wkt2_name,
1429 wkt2_name)) {
1430 return &mapping;
1431 }
1432 }
1433 return nullptr;
1434 }
1435
1436 // ---------------------------------------------------------------------------
1437
1438 std::vector<const MethodMapping *>
getMappingsFromPROJName(const std::string & projName)1439 getMappingsFromPROJName(const std::string &projName) {
1440 std::vector<const MethodMapping *> res;
1441 for (const auto &mapping : projectionMethodMappings) {
1442 if (mapping.proj_name_main && projName == mapping.proj_name_main) {
1443 res.push_back(&mapping);
1444 }
1445 }
1446 return res;
1447 }
1448
1449 // ---------------------------------------------------------------------------
1450
getMapping(const MethodMapping * mapping,const OperationParameterNNPtr & param)1451 const ParamMapping *getMapping(const MethodMapping *mapping,
1452 const OperationParameterNNPtr ¶m) {
1453 if (mapping->params == nullptr) {
1454 return nullptr;
1455 }
1456
1457 // First try with id
1458 const int epsg_code = param->getEPSGCode();
1459 if (epsg_code) {
1460 for (int i = 0; mapping->params[i] != nullptr; ++i) {
1461 const auto *paramMapping = mapping->params[i];
1462 if (paramMapping->epsg_code == epsg_code) {
1463 return paramMapping;
1464 }
1465 }
1466 }
1467
1468 // then equivalent name
1469 const std::string &name = param->nameStr();
1470 for (int i = 0; mapping->params[i] != nullptr; ++i) {
1471 const auto *paramMapping = mapping->params[i];
1472 if (metadata::Identifier::isEquivalentName(paramMapping->wkt2_name,
1473 name.c_str())) {
1474 return paramMapping;
1475 }
1476 }
1477
1478 // and finally different name, but equivalent parameter
1479 for (int i = 0; mapping->params[i] != nullptr; ++i) {
1480 const auto *paramMapping = mapping->params[i];
1481 if (areEquivalentParameters(paramMapping->wkt2_name, name)) {
1482 return paramMapping;
1483 }
1484 }
1485
1486 return nullptr;
1487 }
1488
1489 // ---------------------------------------------------------------------------
1490
getMappingFromWKT1(const MethodMapping * mapping,const std::string & wkt1_name)1491 const ParamMapping *getMappingFromWKT1(const MethodMapping *mapping,
1492 const std::string &wkt1_name) {
1493 for (int i = 0; mapping->params[i] != nullptr; ++i) {
1494 const auto *paramMapping = mapping->params[i];
1495 if (paramMapping->wkt1_name &&
1496 (metadata::Identifier::isEquivalentName(paramMapping->wkt1_name,
1497 wkt1_name.c_str()) ||
1498 areEquivalentParameters(paramMapping->wkt1_name, wkt1_name))) {
1499 return paramMapping;
1500 }
1501 }
1502 return nullptr;
1503 }
1504
1505 //! @endcond
1506
1507 // ---------------------------------------------------------------------------
1508
1509 } // namespace operation
1510 NS_PROJ_END
1511