Coverage Report

Created: 2025-06-22 06:59

/src/gdal/ogr/ogr_spatialref.h
Line
Count
Source (jump to first uncovered line)
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
     * @since GDAL 2.3
730
     */
731
    static inline OGRSpatialReferenceH ToHandle(OGRSpatialReference *poSRS)
732
0
    {
733
0
        return reinterpret_cast<OGRSpatialReferenceH>(poSRS);
734
0
    }
735
736
    /** Convert a OGRSpatialReferenceH to a OGRSpatialReference*.
737
     * @since GDAL 2.3
738
     */
739
    static inline OGRSpatialReference *FromHandle(OGRSpatialReferenceH hSRS)
740
2.37k
    {
741
2.37k
        return reinterpret_cast<OGRSpatialReference *>(hSRS);
742
2.37k
    }
OGRSpatialReference::FromHandle(OGRSpatialReferenceHS*)
Line
Count
Source
740
2.37k
    {
741
2.37k
        return reinterpret_cast<OGRSpatialReference *>(hSRS);
742
2.37k
    }
Unexecuted instantiation: OGRSpatialReference::FromHandle(void*)
743
};
744
745
/*! @cond Doxygen_Suppress */
746
struct CPL_DLL OGRSpatialReferenceReleaser
747
{
748
    void operator()(OGRSpatialReference *poSRS) const
749
0
    {
750
0
        if (poSRS)
751
0
            poSRS->Release();
752
0
    }
753
};
754
755
/*! @endcond */
756
757
/************************************************************************/
758
/*                     OGRCoordinateTransformation                      */
759
/*                                                                      */
760
/*      This is really just used as a base class for a private          */
761
/*      implementation.                                                 */
762
/************************************************************************/
763
764
/**
765
 * Interface for transforming between coordinate systems.
766
 *
767
 * Currently, the only implementation within OGR is OGRProjCT, which
768
 * requires the PROJ library.
769
 *
770
 * Also, see OGRCreateCoordinateTransformation() for creating transformations.
771
 */
772
773
class CPL_DLL OGRCoordinateTransformation
774
{
775
  public:
776
    virtual ~OGRCoordinateTransformation();
777
778
    static void DestroyCT(OGRCoordinateTransformation *poCT);
779
780
    // From CT_CoordinateTransformation
781
782
    /** Fetch internal source coordinate system. */
783
    virtual const OGRSpatialReference *GetSourceCS() const = 0;
784
785
    /** Fetch internal target coordinate system. */
786
    virtual const OGRSpatialReference *GetTargetCS() const = 0;
787
788
    /** Whether the transformer will emit CPLError */
789
    virtual bool GetEmitErrors() const
790
0
    {
791
0
        return false;
792
0
    }
793
794
    /** Set if the transformer must emit CPLError */
795
    virtual void SetEmitErrors(bool /*bEmitErrors*/)
796
0
    {
797
0
    }
798
799
    // From CT_MathTransform
800
801
    /**
802
     * Transform points from source to destination space.
803
     *
804
     * This method is the same as the C function OCTTransformEx().
805
     *
806
     * @param nCount number of points to transform (`size_t` type since 3.9,
807
     *               `int` in previous versions).
808
     * @param x array of nCount X vertices, modified in place. Should not be
809
     * NULL.
810
     * @param y array of nCount Y vertices, modified in place. Should not be
811
     * NULL.
812
     * @param z array of nCount Z vertices, modified in place. Might be NULL.
813
     * @param pabSuccess array of per-point flags set to TRUE if that point
814
     * transforms, or FALSE if it does not. Might be NULL.
815
     *
816
     * @return TRUE on success, or FALSE if some or all points fail to
817
     * transform. When FALSE is returned the pabSuccess[] array indicates which
818
     * points succeeded or failed to transform. When TRUE is returned, all
819
     * values in pabSuccess[] are set to true.
820
     */
821
    int Transform(size_t nCount, double *x, double *y, double *z = nullptr,
822
                  int *pabSuccess = nullptr);
823
824
    /**
825
     * Transform points from source to destination space.
826
     *
827
     * This method is the same as the C function OCTTransform4D().
828
     *
829
     * @param nCount number of points to transform (`size_t` type since 3.9,
830
     *               `int` in previous versions).
831
     * @param x array of nCount X vertices, modified in place. Should not be
832
     * NULL.
833
     * @param y array of nCount Y vertices, modified in place. Should not be
834
     * NULL.
835
     * @param z array of nCount Z vertices, modified in place. Might be NULL.
836
     * @param t array of nCount time values, modified in place. Might be NULL.
837
     * @param pabSuccess array of per-point flags set to TRUE if that point
838
     * transforms, or FALSE if it does not. Might be NULL.
839
     *
840
     * @return TRUE on success, or FALSE if some or all points fail to
841
     * transform. When FALSE is returned the pabSuccess[] array indicates which
842
     * points succeeded or failed to transform. When TRUE is returned, all
843
     * values in pabSuccess[] are set to true.
844
     * Caution: prior to GDAL 3.11, TRUE could be returned if a
845
     * transformation could be found but not all points may
846
     * have necessarily succeed to transform.
847
     */
848
    virtual int Transform(size_t nCount, double *x, double *y, double *z,
849
                          double *t, int *pabSuccess) = 0;
850
851
    /**
852
     * Transform points from source to destination space.
853
     *
854
     * This method is the same as the C function OCTTransform4DWithErrorCodes().
855
     *
856
     * @param nCount number of points to transform (`size_t` type since 3.9,
857
     *               `int` in previous versions).
858
     * @param x array of nCount X vertices, modified in place. Should not be
859
     * NULL.
860
     * @param y array of nCount Y vertices, modified in place. Should not be
861
     * NULL.
862
     * @param z array of nCount Z vertices, modified in place. Might be NULL.
863
     * @param t array of nCount time values, modified in place. Might be NULL.
864
     * @param panErrorCodes Output array of nCount value that will be set to 0
865
     * for success, or a non-zero value for failure. Refer to PROJ 8 public
866
     * error codes. Might be NULL
867
     * @return TRUE on success, or FALSE if some or all points fail to
868
     * transform. When FALSE is returned the panErrorCodes[] array indicates
869
     * which points succeeded or failed to transform. When TRUE is returned, all
870
     * values in panErrorCodes[] are set to zero.
871
     * Caution: prior to GDAL 3.11, TRUE could be returned if a
872
     * transformation could be found but not all points may
873
     * have necessarily succeed to transform.
874
     * @since GDAL 3.3, and PROJ 8 to be able to use PROJ public error codes
875
     */
876
    virtual int TransformWithErrorCodes(size_t nCount, double *x, double *y,
877
                                        double *z, double *t,
878
                                        int *panErrorCodes);
879
880
    /** \brief Transform boundary.
881
     *
882
     * This method is the same as the C function OCTTransformBounds().
883
     *
884
     * Transform boundary densifying the edges to account for nonlinear
885
     * transformations along these edges and extracting the outermost bounds.
886
     *
887
     * If the destination CRS is geographic, the first axis is longitude,
888
     * and xmax < xmin then the bounds crossed the antimeridian.
889
     * In this scenario there are two polygons, one on each side of the
890
     * antimeridian. The first polygon should be constructed with (xmin, ymin,
891
     * 180, ymax) and the second with (-180, ymin, xmax, ymax).
892
     *
893
     * If the destination CRS is geographic, the first axis is latitude,
894
     * and ymax < ymin then the bounds crossed the antimeridian.
895
     * In this scenario there are two polygons, one on each side of the
896
     * antimeridian. The first polygon should be constructed with (ymin, xmin,
897
     * ymax, 180) and the second with (ymin, -180, ymax, xmax).
898
     *
899
     * @param xmin Minimum bounding coordinate of the first axis in source CRS.
900
     * @param ymin Minimum bounding coordinate of the second axis in source CRS.
901
     * @param xmax Maximum bounding coordinate of the first axis in source CRS.
902
     * @param ymax Maximum bounding coordinate of the second axis in source CRS.
903
     * @param out_xmin Minimum bounding coordinate of the first axis in target
904
     * CRS
905
     * @param out_ymin Minimum bounding coordinate of the second axis in target
906
     * CRS.
907
     * @param out_xmax Maximum bounding coordinate of the first axis in target
908
     * CRS.
909
     * @param out_ymax Maximum bounding coordinate of the second axis in target
910
     * CRS.
911
     * @param densify_pts Recommended to use 21. This is the number of points
912
     *     to use to densify the bounding polygon in the transformation.
913
     * @return TRUE if successful. FALSE if failures encountered.
914
     * @since 3.4
915
     */
916
    virtual int TransformBounds(const double xmin, const double ymin,
917
                                const double xmax, const double ymax,
918
                                double *out_xmin, double *out_ymin,
919
                                double *out_xmax, double *out_ymax,
920
                                const int densify_pts)
921
0
    {
922
0
        (void)xmin;
923
0
        (void)xmax;
924
0
        (void)ymin;
925
0
        (void)ymax;
926
0
        (void)densify_pts;
927
0
        *out_xmin = HUGE_VAL;
928
0
        *out_ymin = HUGE_VAL;
929
0
        *out_xmax = HUGE_VAL;
930
0
        *out_ymax = HUGE_VAL;
931
0
        CPLError(CE_Failure, CPLE_AppDefined,
932
0
                 "TransformBounds not implemented.");
933
0
        return false;
934
0
    }
935
936
    /** Convert a OGRCoordinateTransformation* to a
937
     * OGRCoordinateTransformationH.
938
     * @since GDAL 2.3
939
     */
940
    static inline OGRCoordinateTransformationH
941
    ToHandle(OGRCoordinateTransformation *poCT)
942
0
    {
943
0
        return reinterpret_cast<OGRCoordinateTransformationH>(poCT);
944
0
    }
945
946
    /** Convert a OGRCoordinateTransformationH to a
947
     * OGRCoordinateTransformation*.
948
     * @since GDAL 2.3
949
     */
950
    static inline OGRCoordinateTransformation *
951
    FromHandle(OGRCoordinateTransformationH hCT)
952
0
    {
953
0
        return reinterpret_cast<OGRCoordinateTransformation *>(hCT);
954
0
    }
Unexecuted instantiation: OGRCoordinateTransformation::FromHandle(OGRCoordinateTransformationHS*)
Unexecuted instantiation: OGRCoordinateTransformation::FromHandle(void*)
955
956
    /** Clone
957
     * @since GDAL 3.1
958
     */
959
    virtual OGRCoordinateTransformation *Clone() const = 0;
960
961
    /** Return a coordinate transformation that performs the inverse
962
     * transformation of the current one.
963
     *
964
     * In some cases, this is not possible, and this method might return
965
     * nullptr, or fail to perform the transformations.
966
     *
967
     * @return the new coordinate transformation, or nullptr in case of error.
968
     * @since GDAL 3.3
969
     */
970
    virtual OGRCoordinateTransformation *GetInverse() const = 0;
971
972
  protected:
973
    /*! @cond Doxygen_Suppress */
974
0
    OGRCoordinateTransformation() = default;
975
0
    OGRCoordinateTransformation(const OGRCoordinateTransformation &) = default;
976
    OGRCoordinateTransformation &
977
    operator=(const OGRCoordinateTransformation &) = default;
978
    OGRCoordinateTransformation(OGRCoordinateTransformation &&) = default;
979
    OGRCoordinateTransformation &
980
    operator=(OGRCoordinateTransformation &&) = default;
981
    /*! @endcond */
982
};
983
984
OGRCoordinateTransformation CPL_DLL *
985
OGRCreateCoordinateTransformation(const OGRSpatialReference *poSource,
986
                                  const OGRSpatialReference *poTarget);
987
988
/**
989
 * Context for coordinate transformation.
990
 *
991
 * @since GDAL 3.0
992
 */
993
994
struct CPL_DLL OGRCoordinateTransformationOptions
995
{
996
    /*! @cond Doxygen_Suppress */
997
  private:
998
    friend class OGRProjCT;
999
    struct Private;
1000
    std::unique_ptr<Private> d;
1001
    /*! @endcond */
1002
1003
  public:
1004
    OGRCoordinateTransformationOptions();
1005
    OGRCoordinateTransformationOptions(
1006
        const OGRCoordinateTransformationOptions &);
1007
    OGRCoordinateTransformationOptions &
1008
    operator=(const OGRCoordinateTransformationOptions &);
1009
    ~OGRCoordinateTransformationOptions();
1010
1011
    bool SetAreaOfInterest(double dfWestLongitudeDeg, double dfSouthLatitudeDeg,
1012
                           double dfEastLongitudeDeg,
1013
                           double dfNorthLatitudeDeg);
1014
    bool SetDesiredAccuracy(double dfAccuracy);
1015
    bool SetBallparkAllowed(bool bAllowBallpark);
1016
    bool SetOnlyBest(bool bOnlyBest);
1017
1018
    bool SetCoordinateOperation(const char *pszCT, bool bReverseCT);
1019
    /*! @cond Doxygen_Suppress */
1020
    void SetSourceCenterLong(double dfCenterLong);
1021
    void SetTargetCenterLong(double dfCenterLong);
1022
    /*! @endcond */
1023
};
1024
1025
OGRCoordinateTransformation CPL_DLL *OGRCreateCoordinateTransformation(
1026
    const OGRSpatialReference *poSource, const OGRSpatialReference *poTarget,
1027
    const OGRCoordinateTransformationOptions &options);
1028
1029
#endif /* ndef OGR_SPATIALREF_H_INCLUDED */