Coverage Report

Created: 2025-11-16 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/ogr/ogr_spatialref.h
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  OpenGIS Simple Features Reference Implementation
4
 * Purpose:  Classes for manipulating spatial reference systems in a
5
 *           platform non-specific manner.
6
 * Author:   Frank Warmerdam, warmerdam@pobox.com
7
 *
8
 ******************************************************************************
9
 * Copyright (c) 1999,  Les Technologies SoftMap Inc.
10
 * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
11
 *
12
 * SPDX-License-Identifier: MIT
13
 ****************************************************************************/
14
15
#ifndef OGR_SPATIALREF_H_INCLUDED
16
#define OGR_SPATIALREF_H_INCLUDED
17
18
#include "cpl_string.h"
19
#include "ogr_srs_api.h"
20
21
#include <cstddef>
22
#include <map>
23
#include <memory>
24
#include <vector>
25
26
/**
27
 * \file ogr_spatialref.h
28
 *
29
 * Coordinate systems services.
30
 */
31
32
/************************************************************************/
33
/*                             OGR_SRSNode                              */
34
/************************************************************************/
35
36
/**
37
 * Objects of this class are used to represent value nodes in the parsed
38
 * representation of the WKT SRS format.  For instance UNIT["METER",1]
39
 * would be rendered into three OGR_SRSNodes.  The root node would have a
40
 * value of UNIT, and two children, the first with a value of METER, and the
41
 * second with a value of 1.
42
 *
43
 * Normally application code just interacts with the OGRSpatialReference
44
 * object, which uses the OGR_SRSNode to implement its data structure;
45
 * however, this class is user accessible for detailed access to components
46
 * of an SRS definition.
47
 */
48
49
class CPL_DLL OGR_SRSNode
50
{
51
  public:
52
    /** Listener that is notified of modification to nodes. */
53
    struct Listener
54
    {
55
        virtual ~Listener();
56
        /** Method triggered when a node is modified. */
57
        virtual void notifyChange(OGR_SRSNode *) = 0;
58
    };
59
60
    explicit OGR_SRSNode(const char * = nullptr);
61
    ~OGR_SRSNode();
62
63
    /** Register a (single) listener. */
64
    void RegisterListener(const std::shared_ptr<Listener> &listener);
65
66
    /** Return whether this is a leaf node.
67
     * @return TRUE or FALSE
68
     */
69
    int IsLeafNode() const
70
0
    {
71
0
        return nChildren == 0;
72
0
    }
73
74
    int GetChildCount() const
75
0
    {
76
0
        return nChildren;
77
0
    }
78
79
    OGR_SRSNode *GetChild(int);
80
    const OGR_SRSNode *GetChild(int) const;
81
82
    OGR_SRSNode *GetNode(const char *);
83
    const OGR_SRSNode *GetNode(const char *) const;
84
85
    void InsertChild(OGR_SRSNode *, int);
86
    void AddChild(OGR_SRSNode *);
87
    int FindChild(const char *) const;
88
    void DestroyChild(int);
89
    void ClearChildren();
90
    void StripNodes(const char *);
91
92
    const char *GetValue() const
93
0
    {
94
0
        return pszValue;
95
0
    }
96
97
    void SetValue(const char *);
98
99
    void MakeValueSafe();
100
101
    OGR_SRSNode *Clone() const;
102
103
    OGRErr importFromWkt(char **)
104
        /*! @cond Doxygen_Suppress */
105
        CPL_WARN_DEPRECATED("Use importFromWkt(const char**)")
106
        /*! @endcond */
107
        ;
108
    OGRErr importFromWkt(const char **);
109
    OGRErr exportToWkt(char **) const;
110
    OGRErr exportToPrettyWkt(char **, int = 1) const;
111
112
  private:
113
    char *pszValue;
114
115
    OGR_SRSNode **papoChildNodes;
116
    OGR_SRSNode *poParent;
117
118
    int nChildren;
119
120
    int NeedsQuoting() const;
121
    OGRErr importFromWkt(const char **, int nRecLevel, int *pnNodes);
122
123
    std::weak_ptr<Listener> m_listener{};
124
    void notifyChange();
125
126
    CPL_DISALLOW_COPY_ASSIGN(OGR_SRSNode)
127
};
128
129
/************************************************************************/
130
/*                         OGRSpatialReference                          */
131
/************************************************************************/
132
133
/**
134
 * This class represents an OpenGIS Spatial Reference System, and contains
135
 * methods for converting between this object organization and well known
136
 * text (WKT) format.  This object is reference counted as one instance of
137
 * the object is normally shared between many OGRGeometry objects.
138
 *
139
 * Normally application code can fetch needed parameter values for this
140
 * SRS using GetAttrValue(), but in special cases the underlying parse tree
141
 * (or OGR_SRSNode objects) can be accessed more directly.
142
 *
143
 * See <a href="https://gdal.org/tutorials/osr_api_tut.html">the tutorial
144
 * </a> for more information on how to use this class.
145
 *
146
 * Consult also the <a href="https://gdal.org/tutorials/wktproblems.html">
147
 * OGC WKT Coordinate System Issues</a> page for implementation details of
148
 * WKT in OGR.
149
 */
150
151
class CPL_DLL OGRSpatialReference
152
{
153
    struct Private;
154
    std::unique_ptr<Private> d;
155
156
    void GetNormInfo() const;
157
158
    // No longer used with PROJ >= 8.1.0
159
    OGRErr importFromURNPart(const char *pszAuthority, const char *pszCode,
160
                             const char *pszURN);
161
162
    static CPLString lookupInDict(const char *pszDictFile, const char *pszCode);
163
164
    OGRErr GetWKT2ProjectionMethod(const char **ppszMethodName,
165
                                   const char **ppszMethodAuthName = nullptr,
166
                                   const char **ppszMethodCode = nullptr) const;
167
168
  public:
169
    explicit OGRSpatialReference(const char * = nullptr);
170
    OGRSpatialReference(const OGRSpatialReference &);
171
    OGRSpatialReference(OGRSpatialReference &&);
172
173
    virtual ~OGRSpatialReference();
174
175
    static void DestroySpatialReference(OGRSpatialReference *poSRS);
176
177
    OGRSpatialReference &operator=(const OGRSpatialReference &);
178
    OGRSpatialReference &operator=(OGRSpatialReference &&);
179
180
    OGRSpatialReference &AssignAndSetThreadSafe(const OGRSpatialReference &);
181
182
    int Reference();
183
    int Dereference();
184
    int GetReferenceCount() const;
185
    void Release();
186
187
    const char *GetName() const;
188
189
    OGRSpatialReference *Clone() const;
190
    OGRSpatialReference *CloneGeogCS() const;
191
192
    void dumpReadable();
193
    OGRErr exportToWkt(char **) const;
194
    OGRErr exportToWkt(char **ppszWKT, const char *const *papszOptions) const;
195
    std::string exportToWkt(const char *const *papszOptions = nullptr) const;
196
    OGRErr exportToPrettyWkt(char **, int = FALSE) const;
197
    // cppcheck-suppress functionStatic
198
    OGRErr exportToPROJJSON(char **, const char *const *papszOptions) const;
199
    OGRErr exportToProj4(char **) const;
200
    OGRErr exportToPCI(char **, char **, double **) const;
201
    OGRErr exportToUSGS(long *, long *, double **, long *) const;
202
    OGRErr exportToXML(char **, const char * = nullptr) const;
203
    OGRErr exportToPanorama(long *, long *, long *, long *, double *) const;
204
    OGRErr exportVertCSToPanorama(int *) const;
205
    OGRErr exportToERM(char *pszProj, char *pszDatum, char *pszUnits);
206
    OGRErr exportToMICoordSys(char **) const;
207
    OGRErr exportToCF1(char **ppszGridMappingName, char ***ppapszKeyValues,
208
                       char **ppszUnits, CSLConstList papszOptions) const;
209
210
    OGRErr importFromWkt(char **)
211
        /*! @cond Doxygen_Suppress */
212
        CPL_WARN_DEPRECATED(
213
            "Use importFromWkt(const char**) or importFromWkt(const char*)")
214
        /*! @endcond */
215
        ;
216
217
    OGRErr importFromWkt(const char **);
218
    /*! @cond Doxygen_Suppress */
219
    OGRErr importFromWkt(const char *pszInput, CSLConstList papszOptions);
220
    OGRErr importFromWkt(const char **ppszInput, CSLConstList papszOptions);
221
    /*! @endcond */
222
    OGRErr importFromWkt(const char *);
223
    OGRErr importFromProj4(const char *);
224
    OGRErr importFromEPSG(int);
225
    OGRErr importFromEPSGA(int);
226
    OGRErr importFromESRI(char **);
227
    OGRErr importFromPCI(const char *, const char * = nullptr,
228
                         const double * = nullptr);
229
230
#define USGS_ANGLE_DECIMALDEGREES 0 /**< Angle is in decimal degrees. */
231
#define USGS_ANGLE_PACKEDDMS                                                   \
232
    TRUE                     /**< Angle is in packed degree minute second. */
233
#define USGS_ANGLE_RADIANS 2 /**< Angle is in radians. */
234
    OGRErr importFromUSGS(long iProjSys, long iZone, double *padfPrjParams,
235
                          long iDatum,
236
                          int nUSGSAngleFormat = USGS_ANGLE_PACKEDDMS);
237
    OGRErr importFromPanorama(long, long, long, double *, bool bNorth = true);
238
    OGRErr importVertCSFromPanorama(int);
239
    OGRErr importFromOzi(const char *const *papszLines);
240
    OGRErr importFromWMSAUTO(const char *pszAutoDef);
241
    OGRErr importFromXML(const char *);
242
    OGRErr importFromDict(const char *pszDict, const char *pszCode);
243
    OGRErr importFromURN(const char *);
244
    OGRErr importFromCRSURL(const char *);
245
    OGRErr importFromERM(const char *pszProj, const char *pszDatum,
246
                         const char *pszUnits);
247
    OGRErr importFromUrl(const char *);
248
    OGRErr importFromMICoordSys(const char *);
249
    OGRErr importFromCF1(CSLConstList papszKeyValues, const char *pszUnits);
250
251
    OGRErr morphToESRI();
252
    OGRErr morphFromESRI();
253
254
    OGRSpatialReference *
255
    convertToOtherProjection(const char *pszTargetProjection,
256
                             const char *const *papszOptions = nullptr) const;
257
258
    OGRErr Validate() const;
259
    OGRErr StripVertical();
260
261
    bool StripTOWGS84IfKnownDatumAndAllowed();
262
    bool StripTOWGS84IfKnownDatum();
263
264
    int EPSGTreatsAsLatLong() const;
265
    int EPSGTreatsAsNorthingEasting() const;
266
    int GetAxesCount() const;
267
    const char *GetAxis(const char *pszTargetKey, int iAxis,
268
                        OGRAxisOrientation *peOrientation,
269
                        double *pdfConvFactor = nullptr) const;
270
    OGRErr SetAxes(const char *pszTargetKey, const char *pszXAxisName,
271
                   OGRAxisOrientation eXAxisOrientation,
272
                   const char *pszYAxisName,
273
                   OGRAxisOrientation eYAxisOrientation);
274
275
    OSRAxisMappingStrategy GetAxisMappingStrategy() const;
276
    void SetAxisMappingStrategy(OSRAxisMappingStrategy);
277
    const std::vector<int> &GetDataAxisToSRSAxisMapping() const;
278
    OGRErr SetDataAxisToSRSAxisMapping(const std::vector<int> &mapping);
279
280
    // Machinery for accessing parse nodes
281
282
    //! Return root node
283
    OGR_SRSNode *GetRoot();
284
    //! Return root node
285
    const OGR_SRSNode *GetRoot() const;
286
    void SetRoot(OGR_SRSNode *);
287
288
    OGR_SRSNode *GetAttrNode(const char *);
289
    const OGR_SRSNode *GetAttrNode(const char *) const;
290
    const char *GetAttrValue(const char *, int = 0) const;
291
292
    OGRErr SetNode(const char *, const char *);
293
    // cppcheck-suppress functionStatic
294
    OGRErr SetNode(const char *, double);
295
296
    OGRErr
297
    SetLinearUnitsAndUpdateParameters(const char *pszName, double dfInMeters,
298
                                      const char *pszUnitAuthority = nullptr,
299
                                      const char *pszUnitCode = nullptr);
300
    OGRErr SetLinearUnits(const char *pszName, double dfInMeters);
301
    OGRErr SetTargetLinearUnits(const char *pszTargetKey, const char *pszName,
302
                                double dfInMeters,
303
                                const char *pszUnitAuthority = nullptr,
304
                                const char *pszUnitCode = nullptr);
305
306
    double GetLinearUnits(char **) const
307
        /*! @cond Doxygen_Suppress */
308
        CPL_WARN_DEPRECATED("Use GetLinearUnits(const char**) instead")
309
        /*! @endcond */
310
        ;
311
    double GetLinearUnits(const char ** = nullptr) const;
312
313
    /*! @cond Doxygen_Suppress */
314
    double GetLinearUnits(std::nullptr_t) const
315
0
    {
316
0
        return GetLinearUnits(static_cast<const char **>(nullptr));
317
0
    }
318
319
    /*! @endcond */
320
321
    double GetTargetLinearUnits(const char *pszTargetKey,
322
                                char **ppszRetName) const
323
        /*! @cond Doxygen_Suppress */
324
        CPL_WARN_DEPRECATED(
325
            "Use GetTargetLinearUnits(const char*, const char**)")
326
        /*! @endcond */
327
        ;
328
    double GetTargetLinearUnits(const char *pszTargetKey,
329
                                const char **ppszRetName = nullptr) const;
330
331
    /*! @cond Doxygen_Suppress */
332
    double GetTargetLinearUnits(const char *pszTargetKey, std::nullptr_t) const
333
0
    {
334
0
        return GetTargetLinearUnits(pszTargetKey,
335
0
                                    static_cast<const char **>(nullptr));
336
0
    }
337
338
    /*! @endcond */
339
340
    OGRErr SetAngularUnits(const char *pszName, double dfInRadians);
341
    double GetAngularUnits(char **) const
342
        /*! @cond Doxygen_Suppress */
343
        CPL_WARN_DEPRECATED("Use GetAngularUnits(const char**) instead")
344
        /*! @endcond */
345
        ;
346
    double GetAngularUnits(const char ** = nullptr) const;
347
348
    /*! @cond Doxygen_Suppress */
349
    double GetAngularUnits(std::nullptr_t) const
350
0
    {
351
0
        return GetAngularUnits(static_cast<const char **>(nullptr));
352
0
    }
353
354
    /*! @endcond */
355
356
    double GetPrimeMeridian(char **) const
357
        /*! @cond Doxygen_Suppress */
358
        CPL_WARN_DEPRECATED("Use GetPrimeMeridian(const char**) instead")
359
        /*! @endcond */
360
        ;
361
    double GetPrimeMeridian(const char ** = nullptr) const;
362
363
    /*! @cond Doxygen_Suppress */
364
    double GetPrimeMeridian(std::nullptr_t) const
365
0
    {
366
0
        return GetPrimeMeridian(static_cast<const char **>(nullptr));
367
0
    }
368
369
    /*! @endcond */
370
371
    bool IsEmpty() const;
372
    int IsGeographic() const;
373
    int IsDerivedGeographic() const;
374
    int IsProjected() const;
375
    int IsDerivedProjected() const;
376
    int IsGeocentric() const;
377
    bool IsDynamic() const;
378
379
    // cppcheck-suppress functionStatic
380
    bool HasPointMotionOperation() const;
381
382
    int IsLocal() const;
383
    int IsVertical() const;
384
    int IsCompound() const;
385
    int IsSameGeogCS(const OGRSpatialReference *) const;
386
    int IsSameGeogCS(const OGRSpatialReference *,
387
                     const char *const *papszOptions) const;
388
    int IsSameVertCS(const OGRSpatialReference *) const;
389
    int IsSame(const OGRSpatialReference *) const;
390
    int IsSame(const OGRSpatialReference *,
391
               const char *const *papszOptions) const;
392
393
    const char *GetCelestialBodyName() const;
394
395
    void Clear();
396
    OGRErr SetLocalCS(const char *);
397
    OGRErr SetProjCS(const char *);
398
    OGRErr SetProjection(const char *);
399
    OGRErr SetGeocCS(const char *pszGeocName);
400
    OGRErr SetGeogCS(const char *pszGeogName, const char *pszDatumName,
401
                     const char *pszEllipsoidName, double dfSemiMajor,
402
                     double dfInvFlattening, const char *pszPMName = nullptr,
403
                     double dfPMOffset = 0.0, const char *pszUnits = nullptr,
404
                     double dfConvertToRadians = 0.0);
405
    OGRErr SetWellKnownGeogCS(const char *);
406
    OGRErr CopyGeogCSFrom(const OGRSpatialReference *poSrcSRS);
407
    OGRErr SetVertCS(const char *pszVertCSName, const char *pszVertDatumName,
408
                     int nVertDatumClass = 2005);
409
    OGRErr SetCompoundCS(const char *pszName,
410
                         const OGRSpatialReference *poHorizSRS,
411
                         const OGRSpatialReference *poVertSRS);
412
413
    void SetCoordinateEpoch(double dfCoordinateEpoch);
414
    double GetCoordinateEpoch() const;
415
416
    // cppcheck-suppress functionStatic
417
    OGRErr PromoteTo3D(const char *pszName);
418
    // cppcheck-suppress functionStatic
419
    OGRErr DemoteTo2D(const char *pszName);
420
421
    OGRErr SetFromUserInput(const char *);
422
423
    static const char *const SET_FROM_USER_INPUT_LIMITATIONS[];
424
    static CSLConstList SET_FROM_USER_INPUT_LIMITATIONS_get();
425
426
    OGRErr SetFromUserInput(const char *, CSLConstList papszOptions);
427
428
    OGRErr SetTOWGS84(double, double, double, double = 0.0, double = 0.0,
429
                      double = 0.0, double = 0.0);
430
    OGRErr GetTOWGS84(double *padfCoef, int nCoeff = 7) const;
431
    OGRErr AddGuessedTOWGS84();
432
433
    double GetSemiMajor(OGRErr * = nullptr) const;
434
    double GetSemiMinor(OGRErr * = nullptr) const;
435
    double GetInvFlattening(OGRErr * = nullptr) const;
436
    double GetEccentricity() const;
437
    double GetSquaredEccentricity() const;
438
439
    OGRErr SetAuthority(const char *pszTargetKey, const char *pszAuthority,
440
                        int nCode);
441
442
    OGRErr AutoIdentifyEPSG();
443
    OGRSpatialReferenceH *FindMatches(char **papszOptions, int *pnEntries,
444
                                      int **ppanMatchConfidence) const;
445
    OGRSpatialReference *
446
    FindBestMatch(int nMinimumMatchConfidence = 90,
447
                  const char *pszPreferredAuthority = "EPSG",
448
                  CSLConstList papszOptions = nullptr) const;
449
450
    int GetEPSGGeogCS() const;
451
452
    const char *GetAuthorityCode(const char *pszTargetKey) const;
453
    const char *GetAuthorityName(const char *pszTargetKey) const;
454
    char *GetOGCURN() const;
455
456
    bool GetAreaOfUse(double *pdfWestLongitudeDeg, double *pdfSouthLatitudeDeg,
457
                      double *pdfEastLongitudeDeg, double *pdfNorthLatitudeDeg,
458
                      const char **ppszAreaName) const;
459
460
    const char *GetExtension(const char *pszTargetKey, const char *pszName,
461
                             const char *pszDefault = nullptr) const;
462
    OGRErr SetExtension(const char *pszTargetKey, const char *pszName,
463
                        const char *pszValue);
464
465
    int FindProjParm(const char *pszParameter,
466
                     const OGR_SRSNode *poPROJCS = nullptr) const;
467
    OGRErr SetProjParm(const char *, double);
468
    double GetProjParm(const char *, double = 0.0, OGRErr * = nullptr) const;
469
470
    OGRErr SetNormProjParm(const char *, double);
471
    double GetNormProjParm(const char *, double = 0.0,
472
                           OGRErr * = nullptr) const;
473
474
    static int IsAngularParameter(const char *);
475
    static int IsLongitudeParameter(const char *);
476
    static int IsLinearParameter(const char *);
477
478
    /** Albers Conic Equal Area */
479
    OGRErr SetACEA(double dfStdP1, double dfStdP2, double dfCenterLat,
480
                   double dfCenterLong, double dfFalseEasting,
481
                   double dfFalseNorthing);
482
483
    /** Azimuthal Equidistant */
484
    OGRErr SetAE(double dfCenterLat, double dfCenterLong, double dfFalseEasting,
485
                 double dfFalseNorthing);
486
487
    /** Bonne */
488
    OGRErr SetBonne(double dfStdP1, double dfCentralMeridian,
489
                    double dfFalseEasting, double dfFalseNorthing);
490
491
    /** Cylindrical Equal Area */
492
    OGRErr SetCEA(double dfStdP1, double dfCentralMeridian,
493
                  double dfFalseEasting, double dfFalseNorthing);
494
495
    /** Cassini-Soldner */
496
    OGRErr SetCS(double dfCenterLat, double dfCenterLong, double dfFalseEasting,
497
                 double dfFalseNorthing);
498
499
    /** Equidistant Conic */
500
    OGRErr SetEC(double dfStdP1, double dfStdP2, double dfCenterLat,
501
                 double dfCenterLong, double dfFalseEasting,
502
                 double dfFalseNorthing);
503
504
    /** Eckert I */
505
    OGRErr SetEckert(int nVariation, double dfCentralMeridian,
506
                     double dfFalseEasting, double dfFalseNorthing);
507
508
    /** Eckert IV */
509
    OGRErr SetEckertIV(double dfCentralMeridian, double dfFalseEasting,
510
                       double dfFalseNorthing);
511
512
    /** Eckert VI */
513
    OGRErr SetEckertVI(double dfCentralMeridian, double dfFalseEasting,
514
                       double dfFalseNorthing);
515
516
    /** Equirectangular */
517
    OGRErr SetEquirectangular(double dfCenterLat, double dfCenterLong,
518
                              double dfFalseEasting, double dfFalseNorthing);
519
    /** Equirectangular generalized form : */
520
    OGRErr SetEquirectangular2(double dfCenterLat, double dfCenterLong,
521
                               double dfPseudoStdParallel1,
522
                               double dfFalseEasting, double dfFalseNorthing);
523
524
    /** Geostationary Satellite */
525
    OGRErr SetGEOS(double dfCentralMeridian, double dfSatelliteHeight,
526
                   double dfFalseEasting, double dfFalseNorthing);
527
528
    /** Goode Homolosine */
529
    OGRErr SetGH(double dfCentralMeridian, double dfFalseEasting,
530
                 double dfFalseNorthing);
531
532
    /** Interrupted Goode Homolosine */
533
    OGRErr SetIGH();
534
535
    /** Gall Stereographic */
536
    OGRErr SetGS(double dfCentralMeridian, double dfFalseEasting,
537
                 double dfFalseNorthing);
538
539
    /** Gauss Schreiber Transverse Mercator */
540
    OGRErr SetGaussSchreiberTMercator(double dfCenterLat, double dfCenterLong,
541
                                      double dfScale, double dfFalseEasting,
542
                                      double dfFalseNorthing);
543
544
    /** Gnomonic */
545
    OGRErr SetGnomonic(double dfCenterLat, double dfCenterLong,
546
                       double dfFalseEasting, double dfFalseNorthing);
547
548
    /** Hotine Oblique Mercator */
549
    OGRErr SetHOM(double dfCenterLat, double dfCenterLong, double dfAzimuth,
550
                  double dfRectToSkew, double dfScale, double dfFalseEasting,
551
                  double dfFalseNorthing);
552
553
    /**  Hotine Oblique Mercator 2 points */
554
    OGRErr SetHOM2PNO(double dfCenterLat, double dfLat1, double dfLong1,
555
                      double dfLat2, double dfLong2, double dfScale,
556
                      double dfFalseEasting, double dfFalseNorthing);
557
558
    /** Hotine Oblique Mercator Azimuth Center / Variant B */
559
    OGRErr SetHOMAC(double dfCenterLat, double dfCenterLong, double dfAzimuth,
560
                    double dfRectToSkew, double dfScale, double dfFalseEasting,
561
                    double dfFalseNorthing);
562
563
    /** Laborde Oblique Mercator */
564
    OGRErr SetLOM(double dfCenterLat, double dfCenterLong, double dfAzimuth,
565
                  double dfScale, double dfFalseEasting,
566
                  double dfFalseNorthing);
567
568
    /** International Map of the World Polyconic */
569
    OGRErr SetIWMPolyconic(double dfLat1, double dfLat2, double dfCenterLong,
570
                           double dfFalseEasting, double dfFalseNorthing);
571
572
    /** Krovak Oblique Conic Conformal */
573
    OGRErr SetKrovak(double dfCenterLat, double dfCenterLong, double dfAzimuth,
574
                     double dfPseudoStdParallelLat, double dfScale,
575
                     double dfFalseEasting, double dfFalseNorthing);
576
577
    /** Lambert Azimuthal Equal-Area */
578
    OGRErr SetLAEA(double dfCenterLat, double dfCenterLong,
579
                   double dfFalseEasting, double dfFalseNorthing);
580
581
    /** Lambert Conformal Conic */
582
    OGRErr SetLCC(double dfStdP1, double dfStdP2, double dfCenterLat,
583
                  double dfCenterLong, double dfFalseEasting,
584
                  double dfFalseNorthing);
585
586
    /** Lambert Conformal Conic 1SP */
587
    OGRErr SetLCC1SP(double dfCenterLat, double dfCenterLong, double dfScale,
588
                     double dfFalseEasting, double dfFalseNorthing);
589
590
    /** Lambert Conformal Conic (Belgium) */
591
    OGRErr SetLCCB(double dfStdP1, double dfStdP2, double dfCenterLat,
592
                   double dfCenterLong, double dfFalseEasting,
593
                   double dfFalseNorthing);
594
595
    /** Miller Cylindrical */
596
    OGRErr SetMC(double dfCenterLat, double dfCenterLong, double dfFalseEasting,
597
                 double dfFalseNorthing);
598
599
    /** Mercator 1SP */
600
    OGRErr SetMercator(double dfCenterLat, double dfCenterLong, double dfScale,
601
                       double dfFalseEasting, double dfFalseNorthing);
602
603
    /** Mercator 2SP */
604
    OGRErr SetMercator2SP(double dfStdP1, double dfCenterLat,
605
                          double dfCenterLong, double dfFalseEasting,
606
                          double dfFalseNorthing);
607
608
    /** Mollweide */
609
    OGRErr SetMollweide(double dfCentralMeridian, double dfFalseEasting,
610
                        double dfFalseNorthing);
611
612
    /** New Zealand Map Grid */
613
    OGRErr SetNZMG(double dfCenterLat, double dfCenterLong,
614
                   double dfFalseEasting, double dfFalseNorthing);
615
616
    /** Oblique Stereographic */
617
    OGRErr SetOS(double dfOriginLat, double dfCMeridian, double dfScale,
618
                 double dfFalseEasting, double dfFalseNorthing);
619
620
    /** Orthographic */
621
    OGRErr SetOrthographic(double dfCenterLat, double dfCenterLong,
622
                           double dfFalseEasting, double dfFalseNorthing);
623
624
    /** Polyconic */
625
    OGRErr SetPolyconic(double dfCenterLat, double dfCenterLong,
626
                        double dfFalseEasting, double dfFalseNorthing);
627
628
    /** Polar Stereographic */
629
    OGRErr SetPS(double dfCenterLat, double dfCenterLong, double dfScale,
630
                 double dfFalseEasting, double dfFalseNorthing);
631
632
    /** Robinson */
633
    OGRErr SetRobinson(double dfCenterLong, double dfFalseEasting,
634
                       double dfFalseNorthing);
635
636
    /** Sinusoidal */
637
    OGRErr SetSinusoidal(double dfCenterLong, double dfFalseEasting,
638
                         double dfFalseNorthing);
639
640
    /** Stereographic */
641
    OGRErr SetStereographic(double dfCenterLat, double dfCenterLong,
642
                            double dfScale, double dfFalseEasting,
643
                            double dfFalseNorthing);
644
645
    /** Swiss Oblique Cylindrical */
646
    OGRErr SetSOC(double dfLatitudeOfOrigin, double dfCentralMeridian,
647
                  double dfFalseEasting, double dfFalseNorthing);
648
649
    /** Transverse Mercator */
650
    OGRErr SetTM(double dfCenterLat, double dfCenterLong, double dfScale,
651
                 double dfFalseEasting, double dfFalseNorthing);
652
653
    /** Transverse Mercator variants. */
654
    OGRErr SetTMVariant(const char *pszVariantName, double dfCenterLat,
655
                        double dfCenterLong, double dfScale,
656
                        double dfFalseEasting, double dfFalseNorthing);
657
658
    /** Tunesia Mining Grid  */
659
    OGRErr SetTMG(double dfCenterLat, double dfCenterLong,
660
                  double dfFalseEasting, double dfFalseNorthing);
661
662
    /** Transverse Mercator (South Oriented) */
663
    OGRErr SetTMSO(double dfCenterLat, double dfCenterLong, double dfScale,
664
                   double dfFalseEasting, double dfFalseNorthing);
665
666
    /** Two Point Equidistant */
667
    OGRErr SetTPED(double dfLat1, double dfLong1, double dfLat2, double dfLong2,
668
                   double dfFalseEasting, double dfFalseNorthing);
669
670
    /** VanDerGrinten */
671
    OGRErr SetVDG(double dfCenterLong, double dfFalseEasting,
672
                  double dfFalseNorthing);
673
674
    /** Universal Transverse Mercator */
675
    OGRErr SetUTM(int nZone, int bNorth = TRUE);
676
    int GetUTMZone(int *pbNorth = nullptr) const;
677
678
    /** Wagner I \-- VII */
679
    OGRErr SetWagner(int nVariation, double dfCenterLat, double dfFalseEasting,
680
                     double dfFalseNorthing);
681
682
    /** Quadrilateralized Spherical Cube */
683
    OGRErr SetQSC(double dfCenterLat, double dfCenterLong);
684
685
    /** Spherical, Cross-track, Height */
686
    OGRErr SetSCH(double dfPegLat, double dfPegLong, double dfPegHeading,
687
                  double dfPegHgt);
688
689
    /** Vertical Perspective / Near-sided Perspective */
690
    OGRErr
691
    SetVerticalPerspective(double dfTopoOriginLat, double dfTopoOriginLon,
692
                           double dfTopoOriginHeight, double dfViewPointHeight,
693
                           double dfFalseEasting, double dfFalseNorthing);
694
695
    /** Pole rotation (GRIB convention) */
696
    OGRErr SetDerivedGeogCRSWithPoleRotationGRIBConvention(
697
        const char *pszCRSName, double dfSouthPoleLat, double dfSouthPoleLon,
698
        double dfAxisRotation);
699
700
    /** Pole rotation (netCDF CF convention) */
701
    OGRErr SetDerivedGeogCRSWithPoleRotationNetCDFCFConvention(
702
        const char *pszCRSName, double dfGridNorthPoleLat,
703
        double dfGridNorthPoleLon, double dfNorthPoleGridLon);
704
705
    /** State Plane */
706
    OGRErr SetStatePlane(int nZone, int bNAD83 = TRUE,
707
                         const char *pszOverrideUnitName = nullptr,
708
                         double dfOverrideUnit = 0.0);
709
710
    /** ImportFromESRIStatePlaneWKT */
711
    OGRErr ImportFromESRIStatePlaneWKT(int nCode, const char *pszDatumName,
712
                                       const char *pszUnitsName, int nPCSCode,
713
                                       const char *pszCRSName = nullptr);
714
715
    /** ImportFromESRIWisconsinWKT */
716
    OGRErr ImportFromESRIWisconsinWKT(const char *pszPrjName,
717
                                      double dfCentralMeridian,
718
                                      double dfLatOfOrigin,
719
                                      const char *pszUnitsName,
720
                                      const char *pszCRSName = nullptr);
721
722
    /*! @cond Doxygen_Suppress */
723
    void UpdateCoordinateSystemFromGeogCRS();
724
    /*! @endcond */
725
726
    static OGRSpatialReference *GetWGS84SRS();
727
728
    /** Convert a OGRSpatialReference* to a OGRSpatialReferenceH.
729
     */
730
    static inline OGRSpatialReferenceH ToHandle(OGRSpatialReference *poSRS)
731
0
    {
732
0
        return reinterpret_cast<OGRSpatialReferenceH>(poSRS);
733
0
    }
734
735
    /** Convert a OGRSpatialReferenceH to a OGRSpatialReference*.
736
     */
737
    static inline OGRSpatialReference *FromHandle(OGRSpatialReferenceH hSRS)
738
2.20k
    {
739
2.20k
        return reinterpret_cast<OGRSpatialReference *>(hSRS);
740
2.20k
    }
OGRSpatialReference::FromHandle(OGRSpatialReferenceHS*)
Line
Count
Source
738
2.20k
    {
739
2.20k
        return reinterpret_cast<OGRSpatialReference *>(hSRS);
740
2.20k
    }
Unexecuted instantiation: OGRSpatialReference::FromHandle(void*)
741
};
742
743
/*! @cond Doxygen_Suppress */
744
struct CPL_DLL OGRSpatialReferenceReleaser
745
{
746
    void operator()(OGRSpatialReference *poSRS) const
747
0
    {
748
0
        if (poSRS)
749
0
            poSRS->Release();
750
0
    }
751
};
752
753
/*! @endcond */
754
755
/************************************************************************/
756
/*                     OGRCoordinateTransformation                      */
757
/*                                                                      */
758
/*      This is really just used as a base class for a private          */
759
/*      implementation.                                                 */
760
/************************************************************************/
761
762
/**
763
 * Interface for transforming between coordinate systems.
764
 *
765
 * Currently, the only implementation within OGR is OGRProjCT, which
766
 * requires the PROJ library.
767
 *
768
 * Also, see OGRCreateCoordinateTransformation() for creating transformations.
769
 */
770
771
class CPL_DLL OGRCoordinateTransformation
772
{
773
  public:
774
    virtual ~OGRCoordinateTransformation();
775
776
    static void DestroyCT(OGRCoordinateTransformation *poCT);
777
778
    // From CT_CoordinateTransformation
779
780
    /** Fetch internal source coordinate system. */
781
    virtual const OGRSpatialReference *GetSourceCS() const = 0;
782
783
    /** Fetch internal target coordinate system. */
784
    virtual const OGRSpatialReference *GetTargetCS() const = 0;
785
786
    /** Whether the transformer will emit CPLError */
787
    virtual bool GetEmitErrors() const
788
0
    {
789
0
        return false;
790
0
    }
791
792
    /** Set if the transformer must emit CPLError */
793
    virtual void SetEmitErrors(bool /*bEmitErrors*/)
794
0
    {
795
0
    }
796
797
    // From CT_MathTransform
798
799
    /**
800
     * Transform points from source to destination space.
801
     *
802
     * This method is the same as the C function OCTTransformEx().
803
     *
804
     * @param nCount number of points to transform (`size_t` type since 3.9,
805
     *               `int` in previous versions).
806
     * @param x array of nCount X vertices, modified in place. Should not be
807
     * NULL.
808
     * @param y array of nCount Y vertices, modified in place. Should not be
809
     * NULL.
810
     * @param z array of nCount Z vertices, modified in place. Might be NULL.
811
     * @param pabSuccess array of per-point flags set to TRUE if that point
812
     * transforms, or FALSE if it does not. Might be NULL.
813
     *
814
     * @return TRUE on success, or FALSE if some or all points fail to
815
     * transform. When FALSE is returned the pabSuccess[] array indicates which
816
     * points succeeded or failed to transform. When TRUE is returned, all
817
     * values in pabSuccess[] are set to true.
818
     */
819
    int Transform(size_t nCount, double *x, double *y, double *z = nullptr,
820
                  int *pabSuccess = nullptr);
821
822
    /**
823
     * Transform points from source to destination space.
824
     *
825
     * This method is the same as the C function OCTTransform4D().
826
     *
827
     * @param nCount number of points to transform (`size_t` type since 3.9,
828
     *               `int` in previous versions).
829
     * @param x array of nCount X vertices, modified in place. Should not be
830
     * NULL.
831
     * @param y array of nCount Y vertices, modified in place. Should not be
832
     * NULL.
833
     * @param z array of nCount Z vertices, modified in place. Might be NULL.
834
     * @param t array of nCount time values, modified in place. Might be NULL.
835
     * @param pabSuccess array of per-point flags set to TRUE if that point
836
     * transforms, or FALSE if it does not. Might be NULL.
837
     *
838
     * @return TRUE on success, or FALSE if some or all points fail to
839
     * transform. When FALSE is returned the pabSuccess[] array indicates which
840
     * points succeeded or failed to transform. When TRUE is returned, all
841
     * values in pabSuccess[] are set to true.
842
     * Caution: prior to GDAL 3.11, TRUE could be returned if a
843
     * transformation could be found but not all points may
844
     * have necessarily succeed to transform.
845
     */
846
    virtual int Transform(size_t nCount, double *x, double *y, double *z,
847
                          double *t, int *pabSuccess) = 0;
848
849
    /**
850
     * Transform points from source to destination space.
851
     *
852
     * This method is the same as the C function OCTTransform4DWithErrorCodes().
853
     *
854
     * @param nCount number of points to transform (`size_t` type since 3.9,
855
     *               `int` in previous versions).
856
     * @param x array of nCount X vertices, modified in place. Should not be
857
     * NULL.
858
     * @param y array of nCount Y vertices, modified in place. Should not be
859
     * NULL.
860
     * @param z array of nCount Z vertices, modified in place. Might be NULL.
861
     * @param t array of nCount time values, modified in place. Might be NULL.
862
     * @param panErrorCodes Output array of nCount value that will be set to 0
863
     * for success, or a non-zero value for failure. Refer to PROJ 8 public
864
     * error codes. Might be NULL
865
     * @return TRUE on success, or FALSE if some or all points fail to
866
     * transform. When FALSE is returned the panErrorCodes[] array indicates
867
     * which points succeeded or failed to transform. When TRUE is returned, all
868
     * values in panErrorCodes[] are set to zero.
869
     * Caution: prior to GDAL 3.11, TRUE could be returned if a
870
     * transformation could be found but not all points may
871
     * have necessarily succeed to transform.
872
     * @since GDAL 3.3, and PROJ 8 to be able to use PROJ public error codes
873
     */
874
    virtual int TransformWithErrorCodes(size_t nCount, double *x, double *y,
875
                                        double *z, double *t,
876
                                        int *panErrorCodes);
877
878
    /** \brief Transform boundary.
879
     *
880
     * This method is the same as the C function OCTTransformBounds().
881
     *
882
     * Transform boundary densifying the edges to account for nonlinear
883
     * transformations along these edges and extracting the outermost bounds.
884
     *
885
     * If the destination CRS is geographic, the first axis is longitude,
886
     * and xmax < xmin then the bounds crossed the antimeridian.
887
     * In this scenario there are two polygons, one on each side of the
888
     * antimeridian. The first polygon should be constructed with (xmin, ymin,
889
     * 180, ymax) and the second with (-180, ymin, xmax, ymax).
890
     *
891
     * If the destination CRS is geographic, the first axis is latitude,
892
     * and ymax < ymin then the bounds crossed the antimeridian.
893
     * In this scenario there are two polygons, one on each side of the
894
     * antimeridian. The first polygon should be constructed with (ymin, xmin,
895
     * ymax, 180) and the second with (ymin, -180, ymax, xmax).
896
     *
897
     * @param xmin Minimum bounding coordinate of the first axis in source CRS.
898
     * @param ymin Minimum bounding coordinate of the second axis in source CRS.
899
     * @param xmax Maximum bounding coordinate of the first axis in source CRS.
900
     * @param ymax Maximum bounding coordinate of the second axis in source CRS.
901
     * @param out_xmin Minimum bounding coordinate of the first axis in target
902
     * CRS
903
     * @param out_ymin Minimum bounding coordinate of the second axis in target
904
     * CRS.
905
     * @param out_xmax Maximum bounding coordinate of the first axis in target
906
     * CRS.
907
     * @param out_ymax Maximum bounding coordinate of the second axis in target
908
     * CRS.
909
     * @param densify_pts Recommended to use 21. This is the number of points
910
     *     to use to densify the bounding polygon in the transformation.
911
     * @return TRUE if successful. FALSE if failures encountered.
912
     * @since 3.4
913
     */
914
    virtual int TransformBounds(const double xmin, const double ymin,
915
                                const double xmax, const double ymax,
916
                                double *out_xmin, double *out_ymin,
917
                                double *out_xmax, double *out_ymax,
918
                                const int densify_pts)
919
0
    {
920
0
        (void)xmin;
921
0
        (void)xmax;
922
0
        (void)ymin;
923
0
        (void)ymax;
924
0
        (void)densify_pts;
925
0
        *out_xmin = HUGE_VAL;
926
0
        *out_ymin = HUGE_VAL;
927
0
        *out_xmax = HUGE_VAL;
928
0
        *out_ymax = HUGE_VAL;
929
0
        CPLError(CE_Failure, CPLE_AppDefined,
930
0
                 "TransformBounds not implemented.");
931
0
        return false;
932
0
    }
933
934
    /** Convert a OGRCoordinateTransformation* to a
935
     * OGRCoordinateTransformationH.
936
     */
937
    static inline OGRCoordinateTransformationH
938
    ToHandle(OGRCoordinateTransformation *poCT)
939
0
    {
940
0
        return reinterpret_cast<OGRCoordinateTransformationH>(poCT);
941
0
    }
942
943
    /** Convert a OGRCoordinateTransformationH to a
944
     * OGRCoordinateTransformation*.
945
     */
946
    static inline OGRCoordinateTransformation *
947
    FromHandle(OGRCoordinateTransformationH hCT)
948
0
    {
949
0
        return reinterpret_cast<OGRCoordinateTransformation *>(hCT);
950
0
    }
Unexecuted instantiation: OGRCoordinateTransformation::FromHandle(OGRCoordinateTransformationHS*)
Unexecuted instantiation: OGRCoordinateTransformation::FromHandle(void*)
951
952
    /** Clone
953
     * @since GDAL 3.1
954
     */
955
    virtual OGRCoordinateTransformation *Clone() const = 0;
956
957
    /** Return a coordinate transformation that performs the inverse
958
     * transformation of the current one.
959
     *
960
     * In some cases, this is not possible, and this method might return
961
     * nullptr, or fail to perform the transformations.
962
     *
963
     * @return the new coordinate transformation, or nullptr in case of error.
964
     * @since GDAL 3.3
965
     */
966
    virtual OGRCoordinateTransformation *GetInverse() const = 0;
967
968
  protected:
969
    /*! @cond Doxygen_Suppress */
970
0
    OGRCoordinateTransformation() = default;
971
0
    OGRCoordinateTransformation(const OGRCoordinateTransformation &) = default;
972
    OGRCoordinateTransformation &
973
    operator=(const OGRCoordinateTransformation &) = default;
974
    OGRCoordinateTransformation(OGRCoordinateTransformation &&) = default;
975
    OGRCoordinateTransformation &
976
    operator=(OGRCoordinateTransformation &&) = default;
977
    /*! @endcond */
978
};
979
980
OGRCoordinateTransformation CPL_DLL *
981
OGRCreateCoordinateTransformation(const OGRSpatialReference *poSource,
982
                                  const OGRSpatialReference *poTarget);
983
984
/**
985
 * Context for coordinate transformation.
986
 *
987
 * @since GDAL 3.0
988
 */
989
990
struct CPL_DLL OGRCoordinateTransformationOptions
991
{
992
    /*! @cond Doxygen_Suppress */
993
  private:
994
    friend class OGRProjCT;
995
    struct Private;
996
    std::unique_ptr<Private> d;
997
    /*! @endcond */
998
999
  public:
1000
    OGRCoordinateTransformationOptions();
1001
    OGRCoordinateTransformationOptions(
1002
        const OGRCoordinateTransformationOptions &);
1003
    OGRCoordinateTransformationOptions &
1004
    operator=(const OGRCoordinateTransformationOptions &);
1005
    ~OGRCoordinateTransformationOptions();
1006
1007
    bool SetAreaOfInterest(double dfWestLongitudeDeg, double dfSouthLatitudeDeg,
1008
                           double dfEastLongitudeDeg,
1009
                           double dfNorthLatitudeDeg);
1010
    bool SetDesiredAccuracy(double dfAccuracy);
1011
    bool SetBallparkAllowed(bool bAllowBallpark);
1012
    bool SetOnlyBest(bool bOnlyBest);
1013
1014
    bool SetCoordinateOperation(const char *pszCT, bool bReverseCT);
1015
    /*! @cond Doxygen_Suppress */
1016
    void SetSourceCenterLong(double dfCenterLong);
1017
    void SetTargetCenterLong(double dfCenterLong);
1018
    /*! @endcond */
1019
};
1020
1021
OGRCoordinateTransformation CPL_DLL *OGRCreateCoordinateTransformation(
1022
    const OGRSpatialReference *poSource, const OGRSpatialReference *poTarget,
1023
    const OGRCoordinateTransformationOptions &options);
1024
1025
#endif /* ndef OGR_SPATIALREF_H_INCLUDED */