Coverage Report

Created: 2026-04-11 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PROJ/include/proj/io.hpp
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
#ifndef IO_HH_INCLUDED
30
#define IO_HH_INCLUDED
31
32
#include <list>
33
#include <memory>
34
#include <set>
35
#include <string>
36
#include <utility>
37
#include <vector>
38
39
#include "proj.h"
40
41
#include "util.hpp"
42
43
NS_PROJ_START
44
45
class CPLJSonStreamingWriter;
46
47
namespace common {
48
class UnitOfMeasure;
49
using UnitOfMeasurePtr = std::shared_ptr<UnitOfMeasure>;
50
using UnitOfMeasureNNPtr = util::nn<UnitOfMeasurePtr>;
51
52
class IdentifiedObject;
53
using IdentifiedObjectPtr = std::shared_ptr<IdentifiedObject>;
54
using IdentifiedObjectNNPtr = util::nn<IdentifiedObjectPtr>;
55
} // namespace common
56
57
namespace cs {
58
class CoordinateSystem;
59
using CoordinateSystemPtr = std::shared_ptr<CoordinateSystem>;
60
using CoordinateSystemNNPtr = util::nn<CoordinateSystemPtr>;
61
} // namespace cs
62
63
namespace metadata {
64
class Extent;
65
using ExtentPtr = std::shared_ptr<Extent>;
66
using ExtentNNPtr = util::nn<ExtentPtr>;
67
} // namespace metadata
68
69
namespace datum {
70
class Datum;
71
using DatumPtr = std::shared_ptr<Datum>;
72
using DatumNNPtr = util::nn<DatumPtr>;
73
74
class DatumEnsemble;
75
using DatumEnsemblePtr = std::shared_ptr<DatumEnsemble>;
76
using DatumEnsembleNNPtr = util::nn<DatumEnsemblePtr>;
77
78
class Ellipsoid;
79
using EllipsoidPtr = std::shared_ptr<Ellipsoid>;
80
using EllipsoidNNPtr = util::nn<EllipsoidPtr>;
81
82
class PrimeMeridian;
83
using PrimeMeridianPtr = std::shared_ptr<PrimeMeridian>;
84
using PrimeMeridianNNPtr = util::nn<PrimeMeridianPtr>;
85
86
class GeodeticReferenceFrame;
87
using GeodeticReferenceFramePtr = std::shared_ptr<GeodeticReferenceFrame>;
88
using GeodeticReferenceFrameNNPtr = util::nn<GeodeticReferenceFramePtr>;
89
90
class VerticalReferenceFrame;
91
using VerticalReferenceFramePtr = std::shared_ptr<VerticalReferenceFrame>;
92
using VerticalReferenceFrameNNPtr = util::nn<VerticalReferenceFramePtr>;
93
94
class EngineeringDatum;
95
using EngineeringDatumPtr = std::shared_ptr<EngineeringDatum>;
96
using EngineeringDatumNNPtr = util::nn<EngineeringDatumPtr>;
97
} // namespace datum
98
99
namespace crs {
100
class CRS;
101
using CRSPtr = std::shared_ptr<CRS>;
102
using CRSNNPtr = util::nn<CRSPtr>;
103
104
class GeodeticCRS;
105
using GeodeticCRSPtr = std::shared_ptr<GeodeticCRS>;
106
using GeodeticCRSNNPtr = util::nn<GeodeticCRSPtr>;
107
108
class GeographicCRS;
109
using GeographicCRSPtr = std::shared_ptr<GeographicCRS>;
110
using GeographicCRSNNPtr = util::nn<GeographicCRSPtr>;
111
112
class VerticalCRS;
113
using VerticalCRSPtr = std::shared_ptr<VerticalCRS>;
114
using VerticalCRSNNPtr = util::nn<VerticalCRSPtr>;
115
116
class ProjectedCRS;
117
using ProjectedCRSPtr = std::shared_ptr<ProjectedCRS>;
118
using ProjectedCRSNNPtr = util::nn<ProjectedCRSPtr>;
119
120
class DerivedProjectedCRS;
121
using DerivedProjectedCRSPtr = std::shared_ptr<DerivedProjectedCRS>;
122
using DerivedProjectedCRSNNPtr = util::nn<DerivedProjectedCRSPtr>;
123
124
class CompoundCRS;
125
using CompoundCRSPtr = std::shared_ptr<CompoundCRS>;
126
using CompoundCRSNNPtr = util::nn<CompoundCRSPtr>;
127
128
class EngineeringCRS;
129
using EngineeringCRSPtr = std::shared_ptr<EngineeringCRS>;
130
using EngineeringCRSNNPtr = util::nn<EngineeringCRSPtr>;
131
} // namespace crs
132
133
namespace coordinates {
134
class CoordinateMetadata;
135
/** Shared pointer of CoordinateMetadata */
136
using CoordinateMetadataPtr = std::shared_ptr<CoordinateMetadata>;
137
/** Non-null shared pointer of CoordinateMetadata */
138
using CoordinateMetadataNNPtr = util::nn<CoordinateMetadataPtr>;
139
} // namespace coordinates
140
141
namespace operation {
142
class Conversion;
143
using ConversionPtr = std::shared_ptr<Conversion>;
144
using ConversionNNPtr = util::nn<ConversionPtr>;
145
146
class CoordinateOperation;
147
using CoordinateOperationPtr = std::shared_ptr<CoordinateOperation>;
148
using CoordinateOperationNNPtr = util::nn<CoordinateOperationPtr>;
149
150
class PointMotionOperation;
151
using PointMotionOperationPtr = std::shared_ptr<PointMotionOperation>;
152
using PointMotionOperationNNPtr = util::nn<PointMotionOperationPtr>;
153
} // namespace operation
154
155
/** osgeo.proj.io namespace.
156
 *
157
 * \brief I/O classes
158
 */
159
namespace io {
160
161
class DatabaseContext;
162
/** Shared pointer of DatabaseContext. */
163
using DatabaseContextPtr = std::shared_ptr<DatabaseContext>;
164
/** Non-null shared pointer of DatabaseContext. */
165
using DatabaseContextNNPtr = util::nn<DatabaseContextPtr>;
166
167
// ---------------------------------------------------------------------------
168
169
class WKTNode;
170
/** Unique pointer of WKTNode. */
171
using WKTNodePtr = std::unique_ptr<WKTNode>;
172
/** Non-null unique pointer of WKTNode. */
173
using WKTNodeNNPtr = util::nn<WKTNodePtr>;
174
175
// ---------------------------------------------------------------------------
176
177
class WKTFormatter;
178
/** WKTFormatter unique pointer. */
179
using WKTFormatterPtr = std::unique_ptr<WKTFormatter>;
180
/** Non-null WKTFormatter unique pointer. */
181
using WKTFormatterNNPtr = util::nn<WKTFormatterPtr>;
182
183
/** \brief Formatter to WKT strings.
184
 *
185
 * An instance of this class can only be used by a single
186
 * thread at a time.
187
 */
188
class PROJ_GCC_DLL WKTFormatter {
189
  public:
190
    /** WKT variant. */
191
    enum class PROJ_MSVC_DLL Convention {
192
        /** Full WKT2 string, conforming to ISO 19162:2015(E) / OGC 12-063r5
193
         * (\ref WKT2_2015) with all possible nodes and new keyword names.
194
         */
195
        WKT2,
196
        WKT2_2015 = WKT2,
197
198
        /** Same as WKT2 with the following exceptions:
199
         * <ul>
200
         *      <li>UNIT keyword used.</li>
201
         *      <li>ID node only on top element.</li>
202
         *      <li>No ORDER element in AXIS element.</li>
203
         *      <li>PRIMEM node omitted if it is Greenwich.</li>
204
         *      <li>ELLIPSOID.UNIT node omitted if it is
205
         * UnitOfMeasure::METRE.</li>
206
         *      <li>PARAMETER.UNIT / PRIMEM.UNIT omitted if same as AXIS.</li>
207
         *      <li>AXIS.UNIT omitted and replaced by a common GEODCRS.UNIT if
208
         * they are all the same on all axis.</li>
209
         * </ul>
210
         */
211
        WKT2_SIMPLIFIED,
212
        WKT2_2015_SIMPLIFIED = WKT2_SIMPLIFIED,
213
214
        /** Full WKT2 string, conforming to ISO 19162:2019 / OGC 18-010, with
215
         * (\ref WKT2_2019) all possible nodes and new keyword names.
216
         * Non-normative list of differences:
217
         * <ul>
218
         *      <li>WKT2_2019 uses GEOGCRS / BASEGEOGCRS keywords for
219
         * GeographicCRS.</li>
220
         * </ul>
221
         */
222
        WKT2_2019,
223
224
        /** Deprecated alias for WKT2_2019 */
225
        WKT2_2018 = WKT2_2019,
226
227
        /** WKT2_2019 with the simplification rule of WKT2_SIMPLIFIED */
228
        WKT2_2019_SIMPLIFIED,
229
230
        /** Deprecated alias for WKT2_2019_SIMPLIFIED */
231
        WKT2_2018_SIMPLIFIED = WKT2_2019_SIMPLIFIED,
232
233
        /** WKT1 as traditionally output by GDAL, deriving from OGC 01-009.
234
            A notable departure from WKT1_GDAL with respect to OGC 01-009 is
235
            that in WKT1_GDAL, the unit of the PRIMEM value is always degrees.
236
           */
237
        WKT1_GDAL,
238
239
        /** WKT1 as traditionally output by ESRI software,
240
         * deriving from OGC 99-049. */
241
        WKT1_ESRI,
242
    };
243
244
    PROJ_DLL static WKTFormatterNNPtr
245
    create(Convention convention = Convention::WKT2,
246
           DatabaseContextPtr dbContext = nullptr);
247
    PROJ_DLL static WKTFormatterNNPtr create(const WKTFormatterNNPtr &other);
248
    //! @cond Doxygen_Suppress
249
    PROJ_DLL ~WKTFormatter();
250
    //! @endcond
251
252
    PROJ_DLL WKTFormatter &setMultiLine(bool multiLine) noexcept;
253
    PROJ_DLL WKTFormatter &setIndentationWidth(int width) noexcept;
254
255
    /** Rule for output AXIS nodes */
256
    enum class OutputAxisRule {
257
        /** Always include AXIS nodes */
258
        YES,
259
        /** Never include AXIS nodes */
260
        NO,
261
        /** Includes them only on PROJCS node if it uses Easting/Northing
262
         *ordering. Typically used for WKT1_GDAL */
263
        WKT1_GDAL_EPSG_STYLE,
264
    };
265
266
    PROJ_DLL WKTFormatter &setOutputAxis(OutputAxisRule outputAxis) noexcept;
267
    PROJ_DLL WKTFormatter &setStrict(bool strict) noexcept;
268
    PROJ_DLL bool isStrict() const noexcept;
269
270
    PROJ_DLL WKTFormatter &
271
    setAllowEllipsoidalHeightAsVerticalCRS(bool allow) noexcept;
272
    PROJ_DLL bool isAllowedEllipsoidalHeightAsVerticalCRS() const noexcept;
273
274
    PROJ_DLL WKTFormatter &setAllowLINUNITNode(bool allow) noexcept;
275
    PROJ_DLL bool isAllowedLINUNITNode() const noexcept;
276
277
    PROJ_DLL const std::string &toString() const;
278
279
    PROJ_PRIVATE :
280
        //! @cond Doxygen_Suppress
281
        PROJ_DLL WKTFormatter &
282
        setOutputId(bool outputIdIn);
283
284
    PROJ_INTERNAL void enter();
285
    PROJ_INTERNAL void leave();
286
287
    PROJ_INTERNAL void startNode(const std::string &keyword, bool hasId);
288
    PROJ_INTERNAL void endNode();
289
290
    PROJ_INTERNAL bool isAtTopLevel() const;
291
292
    PROJ_DLL WKTFormatter &simulCurNodeHasId();
293
294
    PROJ_INTERNAL void addQuotedString(const char *str);
295
    PROJ_INTERNAL void addQuotedString(const std::string &str);
296
    PROJ_INTERNAL void add(const std::string &str);
297
    PROJ_INTERNAL void add(int number);
298
    PROJ_INTERNAL void add(size_t number) = delete;
299
    PROJ_INTERNAL void add(double number, int precision = 15);
300
301
    PROJ_INTERNAL void pushOutputUnit(bool outputUnitIn);
302
    PROJ_INTERNAL void popOutputUnit();
303
    PROJ_INTERNAL bool outputUnit() const;
304
305
    PROJ_INTERNAL void pushOutputId(bool outputIdIn);
306
    PROJ_INTERNAL void popOutputId();
307
    PROJ_INTERNAL bool outputId() const;
308
309
    PROJ_INTERNAL void pushHasId(bool hasId);
310
    PROJ_INTERNAL void popHasId();
311
312
    PROJ_INTERNAL void pushDisableUsage();
313
    PROJ_INTERNAL void popDisableUsage();
314
    PROJ_INTERNAL bool outputUsage() const;
315
316
    PROJ_INTERNAL void
317
    pushAxisLinearUnit(const common::UnitOfMeasureNNPtr &unit);
318
    PROJ_INTERNAL void popAxisLinearUnit();
319
    PROJ_INTERNAL const common::UnitOfMeasureNNPtr &axisLinearUnit() const;
320
321
    PROJ_INTERNAL void
322
    pushAxisAngularUnit(const common::UnitOfMeasureNNPtr &unit);
323
    PROJ_INTERNAL void popAxisAngularUnit();
324
    PROJ_INTERNAL const common::UnitOfMeasureNNPtr &axisAngularUnit() const;
325
326
    PROJ_INTERNAL void setAbridgedTransformation(bool abriged);
327
    PROJ_INTERNAL bool abridgedTransformation() const;
328
329
    PROJ_INTERNAL void setUseDerivingConversion(bool useDerivingConversionIn);
330
    PROJ_INTERNAL bool useDerivingConversion() const;
331
332
    PROJ_INTERNAL void setTOWGS84Parameters(const std::vector<double> &params);
333
    PROJ_INTERNAL const std::vector<double> &getTOWGS84Parameters() const;
334
335
    PROJ_INTERNAL void setVDatumExtension(const std::string &filename);
336
    PROJ_INTERNAL const std::string &getVDatumExtension() const;
337
338
    PROJ_INTERNAL void setHDatumExtension(const std::string &filename);
339
    PROJ_INTERNAL const std::string &getHDatumExtension() const;
340
341
    PROJ_INTERNAL void
342
    setGeogCRSOfCompoundCRS(const crs::GeographicCRSPtr &crs);
343
    PROJ_INTERNAL const crs::GeographicCRSPtr &getGeogCRSOfCompoundCRS() const;
344
345
    PROJ_INTERNAL static std::string morphNameToESRI(const std::string &name);
346
347
#ifdef unused
348
    PROJ_INTERNAL void startInversion();
349
    PROJ_INTERNAL void stopInversion();
350
    PROJ_INTERNAL bool isInverted() const;
351
#endif
352
353
    PROJ_INTERNAL OutputAxisRule outputAxis() const;
354
    PROJ_INTERNAL bool outputAxisOrder() const;
355
    PROJ_INTERNAL bool primeMeridianOmittedIfGreenwich() const;
356
    PROJ_INTERNAL bool ellipsoidUnitOmittedIfMetre() const;
357
    PROJ_INTERNAL bool forceUNITKeyword() const;
358
    PROJ_INTERNAL bool primeMeridianOrParameterUnitOmittedIfSameAsAxis() const;
359
    PROJ_INTERNAL bool primeMeridianInDegree() const;
360
    PROJ_INTERNAL bool outputCSUnitOnlyOnceIfSame() const;
361
    PROJ_INTERNAL bool idOnTopLevelOnly() const;
362
    PROJ_INTERNAL bool topLevelHasId() const;
363
364
    /** WKT version. */
365
    enum class Version {
366
        /** WKT1 */
367
        WKT1,
368
        /** WKT2 / ISO 19162 */
369
        WKT2
370
    };
371
372
    PROJ_INTERNAL Version version() const;
373
    PROJ_INTERNAL bool use2019Keywords() const;
374
    PROJ_INTERNAL bool useESRIDialect() const;
375
376
    PROJ_INTERNAL const DatabaseContextPtr &databaseContext() const;
377
378
    PROJ_INTERNAL void ingestWKTNode(const WKTNodeNNPtr &node);
379
380
    //! @endcond
381
382
  protected:
383
    //! @cond Doxygen_Suppress
384
    PROJ_INTERNAL explicit WKTFormatter(Convention convention);
385
    WKTFormatter(const WKTFormatter &other) = delete;
386
387
    INLINED_MAKE_UNIQUE
388
    //! @endcond
389
390
  private:
391
    PROJ_OPAQUE_PRIVATE_DATA
392
};
393
394
// ---------------------------------------------------------------------------
395
396
class PROJStringFormatter;
397
/** PROJStringFormatter unique pointer. */
398
using PROJStringFormatterPtr = std::unique_ptr<PROJStringFormatter>;
399
/** Non-null PROJStringFormatter unique pointer. */
400
using PROJStringFormatterNNPtr = util::nn<PROJStringFormatterPtr>;
401
402
/** \brief Formatter to PROJ strings.
403
 *
404
 * An instance of this class can only be used by a single
405
 * thread at a time.
406
 */
407
class PROJ_GCC_DLL PROJStringFormatter {
408
  public:
409
    /** PROJ variant. */
410
    enum class PROJ_MSVC_DLL Convention {
411
        /** PROJ v5 (or later versions) string. */
412
        PROJ_5,
413
414
        /** PROJ v4 string as output by GDAL exportToProj4() */
415
        PROJ_4
416
    };
417
418
    PROJ_DLL static PROJStringFormatterNNPtr
419
    create(Convention conventionIn = Convention::PROJ_5,
420
           DatabaseContextPtr dbContext = nullptr);
421
    //! @cond Doxygen_Suppress
422
    PROJ_DLL ~PROJStringFormatter();
423
    //! @endcond
424
425
    PROJ_DLL PROJStringFormatter &setMultiLine(bool multiLine) noexcept;
426
    PROJ_DLL PROJStringFormatter &setIndentationWidth(int width) noexcept;
427
    PROJ_DLL PROJStringFormatter &setMaxLineLength(int maxLineLength) noexcept;
428
429
    PROJ_DLL void setUseApproxTMerc(bool flag);
430
431
    PROJ_DLL const std::string &toString() const;
432
433
    PROJ_PRIVATE :
434
        //! @cond Doxygen_Suppress
435
436
        PROJ_DLL void
437
        setCRSExport(bool b);
438
    PROJ_INTERNAL bool getCRSExport() const;
439
    PROJ_DLL void startInversion();
440
    PROJ_DLL void stopInversion();
441
    PROJ_INTERNAL bool isInverted() const;
442
    PROJ_INTERNAL bool getUseApproxTMerc() const;
443
    PROJ_INTERNAL void setCoordinateOperationOptimizations(bool enable);
444
445
    PROJ_DLL void
446
    ingestPROJString(const std::string &str); // throw ParsingException
447
448
    PROJ_DLL void addStep(const char *step);
449
    PROJ_DLL void addStep(const std::string &step);
450
    PROJ_DLL void setCurrentStepInverted(bool inverted);
451
    PROJ_DLL void addParam(const std::string &paramName);
452
    PROJ_DLL void addParam(const char *paramName, double val);
453
    PROJ_DLL void addParam(const std::string &paramName, double val);
454
    PROJ_DLL void addParam(const char *paramName, int val);
455
    PROJ_DLL void addParam(const std::string &paramName, int val);
456
    PROJ_DLL void addParam(const char *paramName, const char *val);
457
    PROJ_DLL void addParam(const char *paramName, const std::string &val);
458
    PROJ_DLL void addParam(const std::string &paramName, const char *val);
459
    PROJ_DLL void addParam(const std::string &paramName,
460
                           const std::string &val);
461
    PROJ_DLL void addParam(const char *paramName,
462
                           const std::vector<double> &vals);
463
464
    PROJ_INTERNAL bool hasParam(const char *paramName) const;
465
466
    PROJ_INTERNAL void addNoDefs(bool b);
467
    PROJ_INTERNAL bool getAddNoDefs() const;
468
469
    PROJ_INTERNAL std::set<std::string> getUsedGridNames() const;
470
471
    PROJ_INTERNAL bool requiresPerCoordinateInputTime() const;
472
473
    PROJ_INTERNAL void setTOWGS84Parameters(const std::vector<double> &params);
474
    PROJ_INTERNAL const std::vector<double> &getTOWGS84Parameters() const;
475
476
    PROJ_INTERNAL void setVDatumExtension(const std::string &filename,
477
                                          const std::string &geoidCRSValue);
478
    PROJ_INTERNAL const std::string &getVDatumExtension() const;
479
    PROJ_INTERNAL const std::string &getGeoidCRSValue() const;
480
481
    PROJ_INTERNAL void setHDatumExtension(const std::string &filename);
482
    PROJ_INTERNAL const std::string &getHDatumExtension() const;
483
484
    PROJ_INTERNAL void
485
    setGeogCRSOfCompoundCRS(const crs::GeographicCRSPtr &crs);
486
    PROJ_INTERNAL const crs::GeographicCRSPtr &getGeogCRSOfCompoundCRS() const;
487
488
    PROJ_INTERNAL void setOmitProjLongLatIfPossible(bool omit);
489
    PROJ_INTERNAL bool omitProjLongLatIfPossible() const;
490
491
    PROJ_INTERNAL void pushOmitZUnitConversion();
492
    PROJ_INTERNAL void popOmitZUnitConversion();
493
    PROJ_INTERNAL bool omitZUnitConversion() const;
494
495
    PROJ_INTERNAL void pushOmitHorizontalConversionInVertTransformation();
496
    PROJ_INTERNAL void popOmitHorizontalConversionInVertTransformation();
497
    PROJ_INTERNAL bool omitHorizontalConversionInVertTransformation() const;
498
499
    PROJ_INTERNAL void setLegacyCRSToCRSContext(bool legacyContext);
500
    PROJ_INTERNAL bool getLegacyCRSToCRSContext() const;
501
502
    PROJ_INTERNAL PROJStringFormatter &setNormalizeOutput();
503
504
    PROJ_INTERNAL const DatabaseContextPtr &databaseContext() const;
505
506
    PROJ_INTERNAL Convention convention() const;
507
508
    PROJ_INTERNAL size_t getStepCount() const;
509
510
    //! @endcond
511
512
  protected:
513
    //! @cond Doxygen_Suppress
514
    PROJ_INTERNAL explicit PROJStringFormatter(
515
        Convention conventionIn, const DatabaseContextPtr &dbContext);
516
    PROJStringFormatter(const PROJStringFormatter &other) = delete;
517
518
    INLINED_MAKE_UNIQUE
519
    //! @endcond
520
521
  private:
522
    PROJ_OPAQUE_PRIVATE_DATA
523
};
524
525
// ---------------------------------------------------------------------------
526
527
class JSONFormatter;
528
/** JSONFormatter unique pointer. */
529
using JSONFormatterPtr = std::unique_ptr<JSONFormatter>;
530
/** Non-null JSONFormatter unique pointer. */
531
using JSONFormatterNNPtr = util::nn<JSONFormatterPtr>;
532
533
/** \brief Formatter to JSON strings.
534
 *
535
 * An instance of this class can only be used by a single
536
 * thread at a time.
537
 */
538
class PROJ_GCC_DLL JSONFormatter {
539
  public:
540
    PROJ_DLL static JSONFormatterNNPtr
541
    create(DatabaseContextPtr dbContext = nullptr);
542
    //! @cond Doxygen_Suppress
543
    PROJ_DLL ~JSONFormatter();
544
    //! @endcond
545
546
    PROJ_DLL JSONFormatter &setMultiLine(bool multiLine) noexcept;
547
    PROJ_DLL JSONFormatter &setIndentationWidth(int width) noexcept;
548
    PROJ_DLL JSONFormatter &setSchema(const std::string &schema) noexcept;
549
550
    PROJ_DLL const std::string &toString() const;
551
552
    PROJ_PRIVATE :
553
554
        //! @cond Doxygen_Suppress
555
        PROJ_INTERNAL CPLJSonStreamingWriter *
556
        writer() const;
557
558
    PROJ_INTERNAL const DatabaseContextPtr &databaseContext() const;
559
560
    struct ObjectContext {
561
        JSONFormatter &m_formatter;
562
563
        ObjectContext(const ObjectContext &) = delete;
564
        ObjectContext(ObjectContext &&) = default;
565
566
        explicit ObjectContext(JSONFormatter &formatter, const char *objectType,
567
                               bool hasId);
568
        ~ObjectContext();
569
    };
570
    PROJ_INTERNAL inline ObjectContext MakeObjectContext(const char *objectType,
571
0
                                                         bool hasId) {
572
0
        return ObjectContext(*this, objectType, hasId);
573
0
    }
574
575
    PROJ_INTERNAL void setAllowIDInImmediateChild();
576
577
    PROJ_INTERNAL void setOmitTypeInImmediateChild();
578
579
    PROJ_INTERNAL void setAbridgedTransformation(bool abriged);
580
    PROJ_INTERNAL bool abridgedTransformation() const;
581
582
    PROJ_INTERNAL void setAbridgedTransformationWriteSourceCRS(bool writeCRS);
583
    PROJ_INTERNAL bool abridgedTransformationWriteSourceCRS() const;
584
585
    // cppcheck-suppress functionStatic
586
    PROJ_INTERNAL bool outputId() const;
587
588
    PROJ_INTERNAL bool
589
    outputUsage(bool calledBeforeObjectContext = false) const;
590
591
    PROJ_INTERNAL static const char *PROJJSON_v0_7;
592
593
    //! @endcond
594
595
  protected:
596
    //! @cond Doxygen_Suppress
597
    PROJ_INTERNAL explicit JSONFormatter();
598
    JSONFormatter(const JSONFormatter &other) = delete;
599
600
    INLINED_MAKE_UNIQUE
601
    //! @endcond
602
603
  private:
604
    PROJ_OPAQUE_PRIVATE_DATA
605
};
606
607
// ---------------------------------------------------------------------------
608
609
/** \brief Interface for an object that can be exported to JSON. */
610
class PROJ_GCC_DLL IJSONExportable {
611
  public:
612
    //! @cond Doxygen_Suppress
613
    PROJ_DLL virtual ~IJSONExportable();
614
    //! @endcond
615
616
    /** Builds a JSON representation. May throw a FormattingException */
617
    PROJ_DLL std::string
618
    exportToJSON(JSONFormatter *formatter) const; // throw(FormattingException)
619
620
    PROJ_PRIVATE :
621
622
        //! @cond Doxygen_Suppress
623
        PROJ_INTERNAL virtual void
624
        _exportToJSON(
625
            JSONFormatter *formatter) const = 0; // throw(FormattingException)
626
                                                 //! @endcond
627
};
628
629
// ---------------------------------------------------------------------------
630
631
/** \brief Exception possibly thrown by IWKTExportable::exportToWKT() or
632
 * IPROJStringExportable::exportToPROJString(). */
633
class PROJ_GCC_DLL FormattingException : public util::Exception {
634
  public:
635
    //! @cond Doxygen_Suppress
636
    PROJ_INTERNAL explicit FormattingException(const char *message);
637
    PROJ_INTERNAL explicit FormattingException(const std::string &message);
638
    PROJ_DLL FormattingException(const FormattingException &other);
639
    PROJ_DLL virtual ~FormattingException() override;
640
641
    PROJ_INTERNAL static void Throw(const char *msg) PROJ_NO_RETURN;
642
    PROJ_INTERNAL static void Throw(const std::string &msg) PROJ_NO_RETURN;
643
    //! @endcond
644
};
645
646
// ---------------------------------------------------------------------------
647
648
/** \brief Exception possibly thrown by WKTNode::createFrom() or
649
 * WKTParser::createFromWKT(). */
650
class PROJ_GCC_DLL ParsingException : public util::Exception {
651
  public:
652
    //! @cond Doxygen_Suppress
653
    PROJ_INTERNAL explicit ParsingException(const char *message);
654
    PROJ_INTERNAL explicit ParsingException(const std::string &message);
655
    PROJ_DLL ParsingException(const ParsingException &other);
656
    PROJ_DLL virtual ~ParsingException() override;
657
    //! @endcond
658
};
659
660
// ---------------------------------------------------------------------------
661
662
/** \brief Interface for an object that can be exported to WKT. */
663
class PROJ_GCC_DLL IWKTExportable {
664
  public:
665
    //! @cond Doxygen_Suppress
666
    PROJ_DLL virtual ~IWKTExportable();
667
    //! @endcond
668
669
    /** Builds a WKT representation. May throw a FormattingException */
670
    PROJ_DLL std::string
671
    exportToWKT(WKTFormatter *formatter) const; // throw(FormattingException)
672
673
    PROJ_PRIVATE :
674
675
        //! @cond Doxygen_Suppress
676
        PROJ_INTERNAL virtual void
677
        _exportToWKT(
678
            WKTFormatter *formatter) const = 0; // throw(FormattingException)
679
                                                //! @endcond
680
};
681
682
// ---------------------------------------------------------------------------
683
684
class IPROJStringExportable;
685
/** Shared pointer of IPROJStringExportable. */
686
using IPROJStringExportablePtr = std::shared_ptr<IPROJStringExportable>;
687
/** Non-null shared pointer of IPROJStringExportable. */
688
using IPROJStringExportableNNPtr = util::nn<IPROJStringExportablePtr>;
689
690
/** \brief Interface for an object that can be exported to a PROJ string. */
691
class PROJ_GCC_DLL IPROJStringExportable {
692
  public:
693
    //! @cond Doxygen_Suppress
694
    PROJ_DLL virtual ~IPROJStringExportable();
695
    //! @endcond
696
697
    /** \brief Builds a PROJ string representation.
698
     *
699
     * <ul>
700
     * <li>For PROJStringFormatter::Convention::PROJ_5 (the default),
701
     * <ul>
702
     * <li>For a crs::CRS, returns the same as
703
     * PROJStringFormatter::Convention::PROJ_4. It should be noted that the
704
     * export of a CRS as a PROJ string may cause loss of many important aspects
705
     * of a CRS definition. Consequently it is discouraged to use it for
706
     * interoperability in newer projects. The choice of a WKT representation
707
     * will be a better option.</li>
708
     * <li>For operation::CoordinateOperation, returns a PROJ
709
     * pipeline.</li>
710
     * </ul>
711
     *
712
     * <li>For PROJStringFormatter::Convention::PROJ_4, format a string
713
     * compatible with the OGRSpatialReference::exportToProj4() of GDAL
714
     * &lt;=2.3. It is only compatible of a few CRS objects. The PROJ string
715
     * will also contain a +type=crs parameter to disambiguate the nature of
716
     * the string from a CoordinateOperation.
717
     * <ul>
718
     * <li>For a crs::GeographicCRS, returns a proj=longlat string, with
719
     * ellipsoid / datum / prime meridian information, ignoring axis order
720
     * and unit information.</li>
721
     * <li>For a geocentric crs::GeodeticCRS, returns the transformation from
722
     * geographic coordinates into geocentric coordinates.</li>
723
     * <li>For a crs::ProjectedCRS, returns the projection method, ignoring
724
     * axis order.</li>
725
     * <li>For a crs::BoundCRS, returns the PROJ string of its source/base CRS,
726
     * amended with towgs84 / nadgrids parameter when the deriving conversion
727
     * can be expressed in that way.</li>
728
     * </ul>
729
     * </li>
730
     *
731
     * </ul>
732
     *
733
     * @param formatter PROJ string formatter.
734
     * @return a PROJ string.
735
     * @throw FormattingException if cannot be exported as a PROJ string */
736
    PROJ_DLL std::string exportToPROJString(
737
        PROJStringFormatter *formatter) const; // throw(FormattingException)
738
739
    PROJ_PRIVATE :
740
741
        //! @cond Doxygen_Suppress
742
        PROJ_INTERNAL virtual void
743
        _exportToPROJString(PROJStringFormatter *formatter)
744
            const = 0; // throw(FormattingException)
745
                       //! @endcond
746
};
747
748
// ---------------------------------------------------------------------------
749
750
/** \brief Node in the tree-splitted WKT representation.
751
 */
752
class PROJ_GCC_DLL WKTNode {
753
  public:
754
    PROJ_DLL explicit WKTNode(const std::string &valueIn);
755
    //! @cond Doxygen_Suppress
756
    PROJ_DLL ~WKTNode();
757
    //! @endcond
758
759
    PROJ_DLL const std::string &value() const;
760
    PROJ_DLL const std::vector<WKTNodeNNPtr> &children() const;
761
762
    PROJ_DLL void addChild(WKTNodeNNPtr &&child);
763
    PROJ_DLL const WKTNodePtr &lookForChild(const std::string &childName,
764
                                            int occurrence = 0) const noexcept;
765
    PROJ_DLL int
766
    countChildrenOfName(const std::string &childName) const noexcept;
767
768
    PROJ_DLL std::string toString() const;
769
770
    PROJ_DLL static WKTNodeNNPtr createFrom(const std::string &wkt,
771
                                            size_t indexStart = 0);
772
773
  protected:
774
    PROJ_INTERNAL static WKTNodeNNPtr
775
    createFrom(const std::string &wkt, size_t indexStart, int recLevel,
776
               size_t &indexEnd); // throw(ParsingException)
777
778
  private:
779
    friend class WKTParser;
780
    PROJ_OPAQUE_PRIVATE_DATA
781
};
782
783
// ---------------------------------------------------------------------------
784
785
PROJ_DLL util::BaseObjectNNPtr
786
createFromUserInput(const std::string &text,
787
                    const DatabaseContextPtr &dbContext,
788
                    bool usePROJ4InitRules = false);
789
790
PROJ_DLL util::BaseObjectNNPtr createFromUserInput(const std::string &text,
791
                                                   PJ_CONTEXT *ctx);
792
793
// ---------------------------------------------------------------------------
794
795
/** \brief Parse a WKT string into the appropriate subclass of util::BaseObject.
796
 */
797
class PROJ_GCC_DLL WKTParser {
798
  public:
799
    PROJ_DLL WKTParser();
800
    //! @cond Doxygen_Suppress
801
    PROJ_DLL ~WKTParser();
802
    //! @endcond
803
804
    PROJ_DLL WKTParser &
805
    attachDatabaseContext(const DatabaseContextPtr &dbContext);
806
807
    PROJ_DLL WKTParser &setStrict(bool strict);
808
    PROJ_DLL std::list<std::string> warningList() const;
809
    PROJ_DLL std::list<std::string> grammarErrorList() const;
810
811
    PROJ_DLL WKTParser &setUnsetIdentifiersIfIncompatibleDef(bool unset);
812
813
    PROJ_DLL util::BaseObjectNNPtr
814
    createFromWKT(const std::string &wkt); // throw(ParsingException)
815
816
    /** Guessed WKT "dialect" */
817
    enum class PROJ_MSVC_DLL WKTGuessedDialect {
818
        /** \ref WKT2_2019 */
819
        WKT2_2019,
820
        /** Deprecated alias for WKT2_2019 */
821
        WKT2_2018 = WKT2_2019,
822
        /** \ref WKT2_2015 */
823
        WKT2_2015,
824
        /** \ref WKT1 */
825
        WKT1_GDAL,
826
        /** ESRI variant of WKT1 */
827
        WKT1_ESRI,
828
        /** Not WKT / unrecognized */
829
        NOT_WKT
830
    };
831
832
    // cppcheck-suppress functionStatic
833
    PROJ_DLL WKTGuessedDialect guessDialect(const std::string &wkt) noexcept;
834
835
  private:
836
    PROJ_OPAQUE_PRIVATE_DATA
837
};
838
839
// ---------------------------------------------------------------------------
840
841
/** \brief Parse a PROJ string into the appropriate subclass of
842
 * util::BaseObject.
843
 */
844
class PROJ_GCC_DLL PROJStringParser {
845
  public:
846
    PROJ_DLL PROJStringParser();
847
    //! @cond Doxygen_Suppress
848
    PROJ_DLL ~PROJStringParser();
849
    //! @endcond
850
851
    PROJ_DLL PROJStringParser &
852
    attachDatabaseContext(const DatabaseContextPtr &dbContext);
853
854
    PROJ_DLL PROJStringParser &setUsePROJ4InitRules(bool enable);
855
856
    PROJ_DLL std::vector<std::string> warningList() const;
857
858
    PROJ_DLL util::BaseObjectNNPtr createFromPROJString(
859
        const std::string &projString); // throw(ParsingException)
860
861
    PROJ_PRIVATE :
862
        //! @cond Doxygen_Suppress
863
        PROJStringParser &
864
        attachContext(PJ_CONTEXT *ctx);
865
    //! @endcond
866
  private:
867
    PROJ_OPAQUE_PRIVATE_DATA
868
};
869
870
// ---------------------------------------------------------------------------
871
872
/** \brief Database context.
873
 *
874
 * A database context should be used only by one thread at a time.
875
 */
876
class PROJ_GCC_DLL DatabaseContext {
877
  public:
878
    //! @cond Doxygen_Suppress
879
    PROJ_DLL ~DatabaseContext();
880
    //! @endcond
881
882
    PROJ_DLL static DatabaseContextNNPtr
883
    create(const std::string &databasePath = std::string(),
884
           const std::vector<std::string> &auxiliaryDatabasePaths =
885
               std::vector<std::string>(),
886
           PJ_CONTEXT *ctx = nullptr);
887
888
    PROJ_DLL const std::string &getPath() const;
889
890
    PROJ_DLL const char *getMetadata(const char *key) const;
891
892
    PROJ_DLL std::set<std::string> getAuthorities() const;
893
894
    PROJ_DLL std::vector<std::string> getDatabaseStructure() const;
895
896
    PROJ_DLL void startInsertStatementsSession();
897
898
    PROJ_DLL std::string
899
    suggestsCodeFor(const common::IdentifiedObjectNNPtr &object,
900
                    const std::string &authName, bool numericCode);
901
902
    PROJ_DLL std::vector<std::string> getInsertStatementsFor(
903
        const common::IdentifiedObjectNNPtr &object,
904
        const std::string &authName, const std::string &code, bool numericCode,
905
        const std::vector<std::string> &allowedAuthorities = {"EPSG", "PROJ"});
906
907
    PROJ_DLL void stopInsertStatementsSession();
908
909
    PROJ_PRIVATE :
910
        //! @cond Doxygen_Suppress
911
        PROJ_DLL void *
912
        getSqliteHandle() const;
913
914
    PROJ_DLL static DatabaseContextNNPtr create(void *sqlite_handle);
915
916
    PROJ_INTERNAL bool lookForGridAlternative(const std::string &officialName,
917
                                              std::string &projFilename,
918
                                              std::string &projFormat,
919
                                              bool &inverse) const;
920
921
    PROJ_DLL bool lookForGridInfo(const std::string &projFilename,
922
                                  bool considerKnownGridsAsAvailable,
923
                                  std::string &fullFilename,
924
                                  std::string &packageName, std::string &url,
925
                                  bool &directDownload, bool &openLicense,
926
                                  bool &gridAvailable) const;
927
928
    PROJ_DLL unsigned int getQueryCounter() const;
929
930
    PROJ_INTERNAL std::string
931
    getProjGridName(const std::string &oldProjGridName);
932
933
    PROJ_INTERNAL void invalidateGridInfo(const std::string &projFilename);
934
935
    PROJ_INTERNAL std::string getOldProjGridName(const std::string &gridName);
936
937
    PROJ_INTERNAL std::string
938
    getAliasFromOfficialName(const std::string &officialName,
939
                             const std::string &tableName,
940
                             const std::string &source) const;
941
942
    PROJ_INTERNAL std::list<std::string>
943
    getAliases(const std::string &authName, const std::string &code,
944
               const std::string &officialName, const std::string &tableName,
945
               const std::string &source) const;
946
947
    PROJ_INTERNAL bool isKnownName(const std::string &name,
948
                                   const std::string &tableName) const;
949
950
    PROJ_INTERNAL std::string getName(const std::string &tableName,
951
                                      const std::string &authName,
952
                                      const std::string &code) const;
953
954
    PROJ_INTERNAL std::string getTextDefinition(const std::string &tableName,
955
                                                const std::string &authName,
956
                                                const std::string &code) const;
957
958
    PROJ_INTERNAL std::vector<std::string>
959
    getAllowedAuthorities(const std::string &sourceAuthName,
960
                          const std::string &targetAuthName) const;
961
962
    PROJ_INTERNAL std::list<std::pair<std::string, std::string>>
963
    getNonDeprecated(const std::string &tableName, const std::string &authName,
964
                     const std::string &code) const;
965
966
    PROJ_INTERNAL static std::vector<operation::CoordinateOperationNNPtr>
967
    getTransformationsForGridName(const DatabaseContextNNPtr &databaseContext,
968
                                  const std::string &gridName);
969
970
    PROJ_INTERNAL bool
971
    getAuthorityAndVersion(const std::string &versionedAuthName,
972
                           std::string &authNameOut, std::string &versionOut);
973
974
    PROJ_INTERNAL bool getVersionedAuthority(const std::string &authName,
975
                                             const std::string &version,
976
                                             std::string &versionedAuthNameOut);
977
978
    PROJ_DLL std::vector<std::string>
979
    getVersionedAuthoritiesFromName(const std::string &authName);
980
981
    PROJ_FOR_TEST bool
982
    toWGS84AutocorrectWrongValues(double &tx, double &ty, double &tz,
983
                                  double &rx, double &ry, double &rz,
984
                                  double &scale_difference) const;
985
986
    //! @endcond
987
988
  protected:
989
    PROJ_INTERNAL DatabaseContext();
990
    INLINED_MAKE_SHARED
991
    PROJ_FRIEND(AuthorityFactory);
992
993
  private:
994
    PROJ_OPAQUE_PRIVATE_DATA
995
    DatabaseContext(const DatabaseContext &) = delete;
996
    DatabaseContext &operator=(const DatabaseContext &other) = delete;
997
};
998
999
// ---------------------------------------------------------------------------
1000
1001
class AuthorityFactory;
1002
/** Shared pointer of AuthorityFactory. */
1003
using AuthorityFactoryPtr = std::shared_ptr<AuthorityFactory>;
1004
/** Non-null shared pointer of AuthorityFactory. */
1005
using AuthorityFactoryNNPtr = util::nn<AuthorityFactoryPtr>;
1006
1007
/** \brief Builds object from an authority database.
1008
 *
1009
 * A AuthorityFactory should be used only by one thread at a time.
1010
 *
1011
 * \remark Implements [AuthorityFactory]
1012
 * (http://www.geoapi.org/3.0/javadoc/org.opengis.geoapi/org/opengis/referencing/AuthorityFactory.html)
1013
 * from \ref GeoAPI
1014
 */
1015
class PROJ_GCC_DLL AuthorityFactory {
1016
  public:
1017
    //! @cond Doxygen_Suppress
1018
    PROJ_DLL ~AuthorityFactory();
1019
    //! @endcond
1020
1021
    PROJ_DLL util::BaseObjectNNPtr createObject(const std::string &code) const;
1022
1023
    PROJ_DLL common::UnitOfMeasureNNPtr
1024
    createUnitOfMeasure(const std::string &code) const;
1025
1026
    PROJ_DLL metadata::ExtentNNPtr createExtent(const std::string &code) const;
1027
1028
    PROJ_DLL datum::PrimeMeridianNNPtr
1029
    createPrimeMeridian(const std::string &code) const;
1030
1031
    PROJ_DLL std::string identifyBodyFromSemiMajorAxis(double a,
1032
                                                       double tolerance) const;
1033
1034
    PROJ_DLL datum::EllipsoidNNPtr
1035
    createEllipsoid(const std::string &code) const;
1036
1037
    PROJ_DLL datum::DatumNNPtr createDatum(const std::string &code) const;
1038
1039
    PROJ_DLL datum::DatumEnsembleNNPtr
1040
    createDatumEnsemble(const std::string &code,
1041
                        const std::string &type = std::string()) const;
1042
1043
    PROJ_DLL datum::GeodeticReferenceFrameNNPtr
1044
    createGeodeticDatum(const std::string &code) const;
1045
1046
    PROJ_DLL datum::VerticalReferenceFrameNNPtr
1047
    createVerticalDatum(const std::string &code) const;
1048
1049
    PROJ_DLL datum::EngineeringDatumNNPtr
1050
    createEngineeringDatum(const std::string &code) const;
1051
1052
    PROJ_DLL cs::CoordinateSystemNNPtr
1053
    createCoordinateSystem(const std::string &code) const;
1054
1055
    PROJ_DLL crs::GeodeticCRSNNPtr
1056
    createGeodeticCRS(const std::string &code) const;
1057
1058
    PROJ_DLL crs::GeographicCRSNNPtr
1059
    createGeographicCRS(const std::string &code) const;
1060
1061
    PROJ_DLL crs::VerticalCRSNNPtr
1062
    createVerticalCRS(const std::string &code) const;
1063
1064
    PROJ_DLL crs::EngineeringCRSNNPtr
1065
    createEngineeringCRS(const std::string &code) const;
1066
1067
    PROJ_DLL operation::ConversionNNPtr
1068
    createConversion(const std::string &code) const;
1069
1070
    PROJ_DLL crs::ProjectedCRSNNPtr
1071
    createProjectedCRS(const std::string &code) const;
1072
1073
    PROJ_DLL crs::DerivedProjectedCRSNNPtr
1074
    createDerivedProjectedCRS(const std::string &code) const;
1075
1076
    PROJ_DLL crs::CompoundCRSNNPtr
1077
    createCompoundCRS(const std::string &code) const;
1078
1079
    PROJ_DLL crs::CRSNNPtr
1080
    createCoordinateReferenceSystem(const std::string &code) const;
1081
1082
    PROJ_DLL coordinates::CoordinateMetadataNNPtr
1083
    createCoordinateMetadata(const std::string &code) const;
1084
1085
    PROJ_DLL operation::CoordinateOperationNNPtr
1086
    createCoordinateOperation(const std::string &code,
1087
                              bool usePROJAlternativeGridNames) const;
1088
1089
    PROJ_DLL std::vector<operation::CoordinateOperationNNPtr>
1090
    createFromCoordinateReferenceSystemCodes(
1091
        const std::string &sourceCRSCode,
1092
        const std::string &targetCRSCode) const;
1093
1094
    PROJ_DLL std::list<std::string>
1095
    getGeoidModels(const std::string &code) const;
1096
1097
    PROJ_DLL const std::string &getAuthority() PROJ_PURE_DECL;
1098
1099
    /** Object type. */
1100
    enum class ObjectType {
1101
        /** Object of type datum::PrimeMeridian */
1102
        PRIME_MERIDIAN,
1103
        /** Object of type datum::Ellipsoid */
1104
        ELLIPSOID,
1105
        /** Object of type datum::Datum (and derived classes) */
1106
        DATUM,
1107
        /** Object of type datum::GeodeticReferenceFrame (and derived
1108
           classes) */
1109
        GEODETIC_REFERENCE_FRAME,
1110
        /** Object of type datum::VerticalReferenceFrame (and derived
1111
           classes) */
1112
        VERTICAL_REFERENCE_FRAME,
1113
        /** Object of type datum::EngineeringDatum */
1114
        ENGINEERING_DATUM,
1115
        /** Object of type crs::CRS (and derived classes) */
1116
        CRS,
1117
        /** Object of type crs::GeodeticCRS (and derived classes) */
1118
        GEODETIC_CRS,
1119
        /** GEODETIC_CRS of type geocentric */
1120
        GEOCENTRIC_CRS,
1121
        /** Object of type crs::GeographicCRS (and derived classes) */
1122
        GEOGRAPHIC_CRS,
1123
        /** GEOGRAPHIC_CRS of type Geographic 2D */
1124
        GEOGRAPHIC_2D_CRS,
1125
        /** GEOGRAPHIC_CRS of type Geographic 3D */
1126
        GEOGRAPHIC_3D_CRS,
1127
        /** Object of type crs::ProjectedCRS (and derived classes) */
1128
        PROJECTED_CRS,
1129
        /** Object of type crs::VerticalCRS (and derived classes) */
1130
        VERTICAL_CRS,
1131
        /** Object of type crs::CompoundCRS (and derived classes) */
1132
        ENGINEERING_CRS,
1133
        /** Object of type crs::EngineeringCRS */
1134
        COMPOUND_CRS,
1135
        /** Object of type crs::DerivedProjectedCRS */
1136
        DERIVED_PROJECTED_CRS,
1137
        /** Object of type operation::CoordinateOperation (and derived
1138
           classes) */
1139
        COORDINATE_OPERATION,
1140
        /** Object of type operation::Conversion (and derived classes) */
1141
        CONVERSION,
1142
        /** Object of type operation::Transformation (and derived classes)
1143
         */
1144
        TRANSFORMATION,
1145
        /** Object of type operation::ConcatenatedOperation (and derived
1146
           classes) */
1147
        CONCATENATED_OPERATION,
1148
        /** Object of type datum::DynamicGeodeticReferenceFrame */
1149
        DYNAMIC_GEODETIC_REFERENCE_FRAME,
1150
        /** Object of type datum::DynamicVerticalReferenceFrame */
1151
        DYNAMIC_VERTICAL_REFERENCE_FRAME,
1152
        /** Object of type datum::DatumEnsemble */
1153
        DATUM_ENSEMBLE,
1154
    };
1155
1156
    PROJ_DLL std::set<std::string>
1157
    getAuthorityCodes(const ObjectType &type,
1158
                      bool allowDeprecated = true) const;
1159
1160
    PROJ_DLL std::string getDescriptionText(const std::string &code) const;
1161
1162
    // non-standard
1163
1164
    /** CRS information */
1165
    struct CRSInfo {
1166
        /** Authority name */
1167
        std::string authName;
1168
        /** Code */
1169
        std::string code;
1170
        /** Name */
1171
        std::string name;
1172
        /** Type */
1173
        ObjectType type;
1174
        /** Whether the object is deprecated */
1175
        bool deprecated;
1176
        /** Whereas the west_lon_degree, south_lat_degree, east_lon_degree and
1177
         * north_lat_degree fields are valid. */
1178
        bool bbox_valid;
1179
        /** Western-most longitude of the area of use, in degrees. */
1180
        double west_lon_degree;
1181
        /** Southern-most latitude of the area of use, in degrees. */
1182
        double south_lat_degree;
1183
        /** Eastern-most longitude of the area of use, in degrees. */
1184
        double east_lon_degree;
1185
        /** Northern-most latitude of the area of use, in degrees. */
1186
        double north_lat_degree;
1187
        /** Name of the area of use. */
1188
        std::string areaName;
1189
        /** Name of the projection method for a projected CRS. Might be empty
1190
         * even for projected CRS in some cases. */
1191
        std::string projectionMethodName;
1192
        /** Name of the celestial body of the CRS (e.g. "Earth") */
1193
        std::string celestialBodyName;
1194
1195
        //! @cond Doxygen_Suppress
1196
        CRSInfo();
1197
        //! @endcond
1198
    };
1199
1200
    PROJ_DLL std::list<CRSInfo> getCRSInfoList() const;
1201
1202
    /** Unit information */
1203
    struct UnitInfo {
1204
        /** Authority name */
1205
        std::string authName;
1206
        /** Code */
1207
        std::string code;
1208
        /** Name */
1209
        std::string name;
1210
        /** Category: one of "linear", "linear_per_time", "angular",
1211
         * "angular_per_time", "scale", "scale_per_time" or "time" */
1212
        std::string category;
1213
        /** Conversion factor to the SI unit.
1214
         * It might be 0 in some cases to indicate no known conversion factor.
1215
         */
1216
        double convFactor;
1217
        /** PROJ short name (may be empty) */
1218
        std::string projShortName;
1219
        /** Whether the object is deprecated */
1220
        bool deprecated;
1221
1222
        //! @cond Doxygen_Suppress
1223
        UnitInfo();
1224
        //! @endcond
1225
    };
1226
1227
    PROJ_DLL std::list<UnitInfo> getUnitList() const;
1228
1229
    /** Celestial Body information */
1230
    struct CelestialBodyInfo {
1231
        /** Authority name */
1232
        std::string authName;
1233
        /** Name */
1234
        std::string name;
1235
        //! @cond Doxygen_Suppress
1236
        CelestialBodyInfo();
1237
        //! @endcond
1238
    };
1239
1240
    PROJ_DLL std::list<CelestialBodyInfo> getCelestialBodyList() const;
1241
1242
    PROJ_DLL static AuthorityFactoryNNPtr
1243
    create(const DatabaseContextNNPtr &context,
1244
           const std::string &authorityName);
1245
1246
    PROJ_DLL const DatabaseContextNNPtr &databaseContext() const;
1247
1248
    PROJ_DLL std::vector<operation::CoordinateOperationNNPtr>
1249
    createFromCoordinateReferenceSystemCodes(
1250
        const std::string &sourceCRSAuthName, const std::string &sourceCRSCode,
1251
        const std::string &targetCRSAuthName, const std::string &targetCRSCode,
1252
        bool usePROJAlternativeGridNames, bool discardIfMissingGrid,
1253
        bool considerKnownGridsAsAvailable, bool discardSuperseded,
1254
        bool tryReverseOrder = false,
1255
        bool reportOnlyIntersectingTransformations = false,
1256
        const metadata::ExtentPtr &intersectingExtent1 = nullptr,
1257
        const metadata::ExtentPtr &intersectingExtent2 = nullptr) const;
1258
1259
    PROJ_DLL std::vector<operation::CoordinateOperationNNPtr>
1260
    createFromCRSCodesWithIntermediates(
1261
        const std::string &sourceCRSAuthName, const std::string &sourceCRSCode,
1262
        const std::string &targetCRSAuthName, const std::string &targetCRSCode,
1263
        bool usePROJAlternativeGridNames, bool discardIfMissingGrid,
1264
        bool considerKnownGridsAsAvailable, bool discardSuperseded,
1265
        const std::vector<std::pair<std::string, std::string>>
1266
            &intermediateCRSAuthCodes,
1267
        ObjectType allowedIntermediateObjectType = ObjectType::CRS,
1268
        const std::vector<std::string> &allowedAuthorities =
1269
            std::vector<std::string>(),
1270
        const metadata::ExtentPtr &intersectingExtent1 = nullptr,
1271
        const metadata::ExtentPtr &intersectingExtent2 = nullptr,
1272
        bool skipIntermediateExtentIntersection = false) const;
1273
1274
    PROJ_DLL std::string getOfficialNameFromAlias(
1275
        const std::string &aliasedName, const std::string &tableName,
1276
        const std::string &source, bool tryEquivalentNameSpelling,
1277
        std::string &outTableName, std::string &outAuthName,
1278
        std::string &outCode) const;
1279
1280
    PROJ_DLL std::list<common::IdentifiedObjectNNPtr>
1281
    createObjectsFromName(const std::string &name,
1282
                          const std::vector<ObjectType> &allowedObjectTypes =
1283
                              std::vector<ObjectType>(),
1284
                          bool approximateMatch = true,
1285
                          size_t limitResultCount = 0) const;
1286
1287
    PROJ_DLL std::list<std::pair<std::string, std::string>>
1288
    listAreaOfUseFromName(const std::string &name, bool approximateMatch) const;
1289
1290
    PROJ_PRIVATE :
1291
        //! @cond Doxygen_Suppress
1292
1293
        PROJ_INTERNAL std::list<datum::EllipsoidNNPtr>
1294
        createEllipsoidFromExisting(
1295
            const datum::EllipsoidNNPtr &ellipsoid) const;
1296
1297
    PROJ_INTERNAL std::list<crs::GeodeticCRSNNPtr>
1298
    createGeodeticCRSFromDatum(const std::string &datum_auth_name,
1299
                               const std::string &datum_code,
1300
                               const std::string &geodetic_crs_type) const;
1301
1302
    PROJ_INTERNAL std::list<crs::GeodeticCRSNNPtr>
1303
    createGeodeticCRSFromDatum(const datum::GeodeticReferenceFrameNNPtr &datum,
1304
                               const std::string &preferredAuthName,
1305
                               const std::string &geodetic_crs_type) const;
1306
1307
    PROJ_INTERNAL std::list<crs::VerticalCRSNNPtr>
1308
    createVerticalCRSFromDatum(const std::string &datum_auth_name,
1309
                               const std::string &datum_code) const;
1310
1311
    PROJ_INTERNAL std::list<crs::GeodeticCRSNNPtr>
1312
    createGeodeticCRSFromEllipsoid(const std::string &ellipsoid_auth_name,
1313
                                   const std::string &ellipsoid_code,
1314
                                   const std::string &geodetic_crs_type) const;
1315
1316
    PROJ_INTERNAL std::list<crs::ProjectedCRSNNPtr>
1317
    createProjectedCRSFromExisting(const crs::ProjectedCRSNNPtr &crs) const;
1318
1319
    PROJ_INTERNAL std::list<crs::CompoundCRSNNPtr>
1320
    createCompoundCRSFromExisting(const crs::CompoundCRSNNPtr &crs) const;
1321
1322
    PROJ_INTERNAL crs::CRSNNPtr
1323
    createCoordinateReferenceSystem(const std::string &code,
1324
                                    bool allowCompound) const;
1325
1326
    PROJ_INTERNAL std::vector<operation::CoordinateOperationNNPtr>
1327
    getTransformationsForGeoid(const std::string &geoidName,
1328
                               bool usePROJAlternativeGridNames) const;
1329
1330
    PROJ_INTERNAL std::vector<operation::CoordinateOperationNNPtr>
1331
    createBetweenGeodeticCRSWithDatumBasedIntermediates(
1332
        const crs::CRSNNPtr &sourceCRS, const std::string &sourceCRSAuthName,
1333
        const std::string &sourceCRSCode, const crs::CRSNNPtr &targetCRS,
1334
        const std::string &targetCRSAuthName, const std::string &targetCRSCode,
1335
        bool usePROJAlternativeGridNames, bool discardIfMissingGrid,
1336
        bool considerKnownGridsAsAvailable, bool discardSuperseded,
1337
        const std::vector<std::string> &allowedAuthorities,
1338
        const metadata::ExtentPtr &intersectingExtent1,
1339
        const metadata::ExtentPtr &intersectingExtent2,
1340
        bool skipIntermediateExtentIntersection = false) const;
1341
1342
    typedef std::pair<common::IdentifiedObjectNNPtr, std::string>
1343
        PairObjectName;
1344
    PROJ_INTERNAL std::list<PairObjectName>
1345
    createObjectsFromNameEx(const std::string &name,
1346
                            const std::vector<ObjectType> &allowedObjectTypes =
1347
                                std::vector<ObjectType>(),
1348
                            bool approximateMatch = true,
1349
                            size_t limitResultCount = 0,
1350
                            bool useAliases = true) const;
1351
1352
    PROJ_FOR_TEST std::vector<operation::PointMotionOperationNNPtr>
1353
    getPointMotionOperationsFor(const crs::GeodeticCRSNNPtr &crs,
1354
                                bool usePROJAlternativeGridNames) const;
1355
1356
    //! @endcond
1357
1358
  protected:
1359
    PROJ_INTERNAL AuthorityFactory(const DatabaseContextNNPtr &context,
1360
                                   const std::string &authorityName);
1361
1362
    PROJ_INTERNAL crs::GeodeticCRSNNPtr
1363
    createGeodeticCRS(const std::string &code, bool geographicOnly) const;
1364
1365
    PROJ_INTERNAL operation::CoordinateOperationNNPtr
1366
    createCoordinateOperation(const std::string &code, bool allowConcatenated,
1367
                              bool usePROJAlternativeGridNames,
1368
                              const std::string &type) const;
1369
1370
    INLINED_MAKE_SHARED
1371
1372
  private:
1373
    PROJ_OPAQUE_PRIVATE_DATA
1374
1375
    PROJ_INTERNAL void
1376
    createGeodeticDatumOrEnsemble(const std::string &code,
1377
                                  datum::GeodeticReferenceFramePtr &outDatum,
1378
                                  datum::DatumEnsemblePtr &outDatumEnsemble,
1379
                                  bool turnEnsembleAsDatum) const;
1380
1381
    PROJ_INTERNAL void
1382
    createVerticalDatumOrEnsemble(const std::string &code,
1383
                                  datum::VerticalReferenceFramePtr &outDatum,
1384
                                  datum::DatumEnsemblePtr &outDatumEnsemble,
1385
                                  bool turnEnsembleAsDatum) const;
1386
};
1387
1388
// ---------------------------------------------------------------------------
1389
1390
/** \brief Exception thrown when a factory can't create an instance of the
1391
 * requested object.
1392
 */
1393
class PROJ_GCC_DLL FactoryException : public util::Exception {
1394
  public:
1395
    //! @cond Doxygen_Suppress
1396
    PROJ_DLL explicit FactoryException(const char *message);
1397
    PROJ_DLL explicit FactoryException(const std::string &message);
1398
    PROJ_DLL
1399
    FactoryException(const FactoryException &other);
1400
    PROJ_DLL ~FactoryException() override;
1401
    //! @endcond
1402
};
1403
1404
// ---------------------------------------------------------------------------
1405
1406
/** \brief Exception thrown when an authority factory can't find the requested
1407
 * authority code.
1408
 */
1409
class PROJ_GCC_DLL NoSuchAuthorityCodeException : public FactoryException {
1410
  public:
1411
    //! @cond Doxygen_Suppress
1412
    PROJ_DLL explicit NoSuchAuthorityCodeException(const std::string &message,
1413
                                                   const std::string &authority,
1414
                                                   const std::string &code);
1415
    PROJ_DLL
1416
    NoSuchAuthorityCodeException(const NoSuchAuthorityCodeException &other);
1417
    PROJ_DLL ~NoSuchAuthorityCodeException() override;
1418
    //! @endcond
1419
1420
    PROJ_DLL const std::string &getAuthority() const;
1421
    PROJ_DLL const std::string &getAuthorityCode() const;
1422
1423
  private:
1424
    PROJ_OPAQUE_PRIVATE_DATA
1425
};
1426
1427
} // namespace io
1428
1429
NS_PROJ_END
1430
1431
#endif // IO_HH_INCLUDED