Coverage Report

Created: 2025-06-13 06:29

/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
    void Clear();
394
    OGRErr SetLocalCS(const char *);
395
    OGRErr SetProjCS(const char *);
396
    OGRErr SetProjection(const char *);
397
    OGRErr SetGeocCS(const char *pszGeocName);
398
    OGRErr SetGeogCS(const char *pszGeogName, const char *pszDatumName,
399
                     const char *pszEllipsoidName, double dfSemiMajor,
400
                     double dfInvFlattening, const char *pszPMName = nullptr,
401
                     double dfPMOffset = 0.0, const char *pszUnits = nullptr,
402
                     double dfConvertToRadians = 0.0);
403
    OGRErr SetWellKnownGeogCS(const char *);
404
    OGRErr CopyGeogCSFrom(const OGRSpatialReference *poSrcSRS);
405
    OGRErr SetVertCS(const char *pszVertCSName, const char *pszVertDatumName,
406
                     int nVertDatumClass = 2005);
407
    OGRErr SetCompoundCS(const char *pszName,
408
                         const OGRSpatialReference *poHorizSRS,
409
                         const OGRSpatialReference *poVertSRS);
410
411
    void SetCoordinateEpoch(double dfCoordinateEpoch);
412
    double GetCoordinateEpoch() const;
413
414
    // cppcheck-suppress functionStatic
415
    OGRErr PromoteTo3D(const char *pszName);
416
    // cppcheck-suppress functionStatic
417
    OGRErr DemoteTo2D(const char *pszName);
418
419
    OGRErr SetFromUserInput(const char *);
420
421
    static const char *const SET_FROM_USER_INPUT_LIMITATIONS[];
422
    static CSLConstList SET_FROM_USER_INPUT_LIMITATIONS_get();
423
424
    OGRErr SetFromUserInput(const char *, CSLConstList papszOptions);
425
426
    OGRErr SetTOWGS84(double, double, double, double = 0.0, double = 0.0,
427
                      double = 0.0, double = 0.0);
428
    OGRErr GetTOWGS84(double *padfCoef, int nCoeff = 7) const;
429
    OGRErr AddGuessedTOWGS84();
430
431
    double GetSemiMajor(OGRErr * = nullptr) const;
432
    double GetSemiMinor(OGRErr * = nullptr) const;
433
    double GetInvFlattening(OGRErr * = nullptr) const;
434
    double GetEccentricity() const;
435
    double GetSquaredEccentricity() const;
436
437
    OGRErr SetAuthority(const char *pszTargetKey, const char *pszAuthority,
438
                        int nCode);
439
440
    OGRErr AutoIdentifyEPSG();
441
    OGRSpatialReferenceH *FindMatches(char **papszOptions, int *pnEntries,
442
                                      int **ppanMatchConfidence) const;
443
    OGRSpatialReference *
444
    FindBestMatch(int nMinimumMatchConfidence = 90,
445
                  const char *pszPreferredAuthority = "EPSG",
446
                  CSLConstList papszOptions = nullptr) const;
447
448
    int GetEPSGGeogCS() const;
449
450
    const char *GetAuthorityCode(const char *pszTargetKey) const;
451
    const char *GetAuthorityName(const char *pszTargetKey) const;
452
    char *GetOGCURN() const;
453
454
    bool GetAreaOfUse(double *pdfWestLongitudeDeg, double *pdfSouthLatitudeDeg,
455
                      double *pdfEastLongitudeDeg, double *pdfNorthLatitudeDeg,
456
                      const char **ppszAreaName) const;
457
458
    const char *GetExtension(const char *pszTargetKey, const char *pszName,
459
                             const char *pszDefault = nullptr) const;
460
    OGRErr SetExtension(const char *pszTargetKey, const char *pszName,
461
                        const char *pszValue);
462
463
    int FindProjParm(const char *pszParameter,
464
                     const OGR_SRSNode *poPROJCS = nullptr) const;
465
    OGRErr SetProjParm(const char *, double);
466
    double GetProjParm(const char *, double = 0.0, OGRErr * = nullptr) const;
467
468
    OGRErr SetNormProjParm(const char *, double);
469
    double GetNormProjParm(const char *, double = 0.0,
470
                           OGRErr * = nullptr) const;
471
472
    static int IsAngularParameter(const char *);
473
    static int IsLongitudeParameter(const char *);
474
    static int IsLinearParameter(const char *);
475
476
    /** Albers Conic Equal Area */
477
    OGRErr SetACEA(double dfStdP1, double dfStdP2, double dfCenterLat,
478
                   double dfCenterLong, double dfFalseEasting,
479
                   double dfFalseNorthing);
480
481
    /** Azimuthal Equidistant */
482
    OGRErr SetAE(double dfCenterLat, double dfCenterLong, double dfFalseEasting,
483
                 double dfFalseNorthing);
484
485
    /** Bonne */
486
    OGRErr SetBonne(double dfStdP1, double dfCentralMeridian,
487
                    double dfFalseEasting, double dfFalseNorthing);
488
489
    /** Cylindrical Equal Area */
490
    OGRErr SetCEA(double dfStdP1, double dfCentralMeridian,
491
                  double dfFalseEasting, double dfFalseNorthing);
492
493
    /** Cassini-Soldner */
494
    OGRErr SetCS(double dfCenterLat, double dfCenterLong, double dfFalseEasting,
495
                 double dfFalseNorthing);
496
497
    /** Equidistant Conic */
498
    OGRErr SetEC(double dfStdP1, double dfStdP2, double dfCenterLat,
499
                 double dfCenterLong, double dfFalseEasting,
500
                 double dfFalseNorthing);
501
502
    /** Eckert I */
503
    OGRErr SetEckert(int nVariation, double dfCentralMeridian,
504
                     double dfFalseEasting, double dfFalseNorthing);
505
506
    /** Eckert IV */
507
    OGRErr SetEckertIV(double dfCentralMeridian, double dfFalseEasting,
508
                       double dfFalseNorthing);
509
510
    /** Eckert VI */
511
    OGRErr SetEckertVI(double dfCentralMeridian, double dfFalseEasting,
512
                       double dfFalseNorthing);
513
514
    /** Equirectangular */
515
    OGRErr SetEquirectangular(double dfCenterLat, double dfCenterLong,
516
                              double dfFalseEasting, double dfFalseNorthing);
517
    /** Equirectangular generalized form : */
518
    OGRErr SetEquirectangular2(double dfCenterLat, double dfCenterLong,
519
                               double dfPseudoStdParallel1,
520
                               double dfFalseEasting, double dfFalseNorthing);
521
522
    /** Geostationary Satellite */
523
    OGRErr SetGEOS(double dfCentralMeridian, double dfSatelliteHeight,
524
                   double dfFalseEasting, double dfFalseNorthing);
525
526
    /** Goode Homolosine */
527
    OGRErr SetGH(double dfCentralMeridian, double dfFalseEasting,
528
                 double dfFalseNorthing);
529
530
    /** Interrupted Goode Homolosine */
531
    OGRErr SetIGH();
532
533
    /** Gall Stereographic */
534
    OGRErr SetGS(double dfCentralMeridian, double dfFalseEasting,
535
                 double dfFalseNorthing);
536
537
    /** Gauss Schreiber Transverse Mercator */
538
    OGRErr SetGaussSchreiberTMercator(double dfCenterLat, double dfCenterLong,
539
                                      double dfScale, double dfFalseEasting,
540
                                      double dfFalseNorthing);
541
542
    /** Gnomonic */
543
    OGRErr SetGnomonic(double dfCenterLat, double dfCenterLong,
544
                       double dfFalseEasting, double dfFalseNorthing);
545
546
    /** Hotine Oblique Mercator */
547
    OGRErr SetHOM(double dfCenterLat, double dfCenterLong, double dfAzimuth,
548
                  double dfRectToSkew, double dfScale, double dfFalseEasting,
549
                  double dfFalseNorthing);
550
551
    /**  Hotine Oblique Mercator 2 points */
552
    OGRErr SetHOM2PNO(double dfCenterLat, double dfLat1, double dfLong1,
553
                      double dfLat2, double dfLong2, double dfScale,
554
                      double dfFalseEasting, double dfFalseNorthing);
555
556
    /** Hotine Oblique Mercator Azimuth Center / Variant B */
557
    OGRErr SetHOMAC(double dfCenterLat, double dfCenterLong, double dfAzimuth,
558
                    double dfRectToSkew, double dfScale, double dfFalseEasting,
559
                    double dfFalseNorthing);
560
561
    /** Laborde Oblique Mercator */
562
    OGRErr SetLOM(double dfCenterLat, double dfCenterLong, double dfAzimuth,
563
                  double dfScale, double dfFalseEasting,
564
                  double dfFalseNorthing);
565
566
    /** International Map of the World Polyconic */
567
    OGRErr SetIWMPolyconic(double dfLat1, double dfLat2, double dfCenterLong,
568
                           double dfFalseEasting, double dfFalseNorthing);
569
570
    /** Krovak Oblique Conic Conformal */
571
    OGRErr SetKrovak(double dfCenterLat, double dfCenterLong, double dfAzimuth,
572
                     double dfPseudoStdParallelLat, double dfScale,
573
                     double dfFalseEasting, double dfFalseNorthing);
574
575
    /** Lambert Azimuthal Equal-Area */
576
    OGRErr SetLAEA(double dfCenterLat, double dfCenterLong,
577
                   double dfFalseEasting, double dfFalseNorthing);
578
579
    /** Lambert Conformal Conic */
580
    OGRErr SetLCC(double dfStdP1, double dfStdP2, double dfCenterLat,
581
                  double dfCenterLong, double dfFalseEasting,
582
                  double dfFalseNorthing);
583
584
    /** Lambert Conformal Conic 1SP */
585
    OGRErr SetLCC1SP(double dfCenterLat, double dfCenterLong, double dfScale,
586
                     double dfFalseEasting, double dfFalseNorthing);
587
588
    /** Lambert Conformal Conic (Belgium) */
589
    OGRErr SetLCCB(double dfStdP1, double dfStdP2, double dfCenterLat,
590
                   double dfCenterLong, double dfFalseEasting,
591
                   double dfFalseNorthing);
592
593
    /** Miller Cylindrical */
594
    OGRErr SetMC(double dfCenterLat, double dfCenterLong, double dfFalseEasting,
595
                 double dfFalseNorthing);
596
597
    /** Mercator 1SP */
598
    OGRErr SetMercator(double dfCenterLat, double dfCenterLong, double dfScale,
599
                       double dfFalseEasting, double dfFalseNorthing);
600
601
    /** Mercator 2SP */
602
    OGRErr SetMercator2SP(double dfStdP1, double dfCenterLat,
603
                          double dfCenterLong, double dfFalseEasting,
604
                          double dfFalseNorthing);
605
606
    /** Mollweide */
607
    OGRErr SetMollweide(double dfCentralMeridian, double dfFalseEasting,
608
                        double dfFalseNorthing);
609
610
    /** New Zealand Map Grid */
611
    OGRErr SetNZMG(double dfCenterLat, double dfCenterLong,
612
                   double dfFalseEasting, double dfFalseNorthing);
613
614
    /** Oblique Stereographic */
615
    OGRErr SetOS(double dfOriginLat, double dfCMeridian, double dfScale,
616
                 double dfFalseEasting, double dfFalseNorthing);
617
618
    /** Orthographic */
619
    OGRErr SetOrthographic(double dfCenterLat, double dfCenterLong,
620
                           double dfFalseEasting, double dfFalseNorthing);
621
622
    /** Polyconic */
623
    OGRErr SetPolyconic(double dfCenterLat, double dfCenterLong,
624
                        double dfFalseEasting, double dfFalseNorthing);
625
626
    /** Polar Stereographic */
627
    OGRErr SetPS(double dfCenterLat, double dfCenterLong, double dfScale,
628
                 double dfFalseEasting, double dfFalseNorthing);
629
630
    /** Robinson */
631
    OGRErr SetRobinson(double dfCenterLong, double dfFalseEasting,
632
                       double dfFalseNorthing);
633
634
    /** Sinusoidal */
635
    OGRErr SetSinusoidal(double dfCenterLong, double dfFalseEasting,
636
                         double dfFalseNorthing);
637
638
    /** Stereographic */
639
    OGRErr SetStereographic(double dfCenterLat, double dfCenterLong,
640
                            double dfScale, double dfFalseEasting,
641
                            double dfFalseNorthing);
642
643
    /** Swiss Oblique Cylindrical */
644
    OGRErr SetSOC(double dfLatitudeOfOrigin, double dfCentralMeridian,
645
                  double dfFalseEasting, double dfFalseNorthing);
646
647
    /** Transverse Mercator */
648
    OGRErr SetTM(double dfCenterLat, double dfCenterLong, double dfScale,
649
                 double dfFalseEasting, double dfFalseNorthing);
650
651
    /** Transverse Mercator variants. */
652
    OGRErr SetTMVariant(const char *pszVariantName, double dfCenterLat,
653
                        double dfCenterLong, double dfScale,
654
                        double dfFalseEasting, double dfFalseNorthing);
655
656
    /** Tunesia Mining Grid  */
657
    OGRErr SetTMG(double dfCenterLat, double dfCenterLong,
658
                  double dfFalseEasting, double dfFalseNorthing);
659
660
    /** Transverse Mercator (South Oriented) */
661
    OGRErr SetTMSO(double dfCenterLat, double dfCenterLong, double dfScale,
662
                   double dfFalseEasting, double dfFalseNorthing);
663
664
    /** Two Point Equidistant */
665
    OGRErr SetTPED(double dfLat1, double dfLong1, double dfLat2, double dfLong2,
666
                   double dfFalseEasting, double dfFalseNorthing);
667
668
    /** VanDerGrinten */
669
    OGRErr SetVDG(double dfCenterLong, double dfFalseEasting,
670
                  double dfFalseNorthing);
671
672
    /** Universal Transverse Mercator */
673
    OGRErr SetUTM(int nZone, int bNorth = TRUE);
674
    int GetUTMZone(int *pbNorth = nullptr) const;
675
676
    /** Wagner I \-- VII */
677
    OGRErr SetWagner(int nVariation, double dfCenterLat, double dfFalseEasting,
678
                     double dfFalseNorthing);
679
680
    /** Quadrilateralized Spherical Cube */
681
    OGRErr SetQSC(double dfCenterLat, double dfCenterLong);
682
683
    /** Spherical, Cross-track, Height */
684
    OGRErr SetSCH(double dfPegLat, double dfPegLong, double dfPegHeading,
685
                  double dfPegHgt);
686
687
    /** Vertical Perspective / Near-sided Perspective */
688
    OGRErr
689
    SetVerticalPerspective(double dfTopoOriginLat, double dfTopoOriginLon,
690
                           double dfTopoOriginHeight, double dfViewPointHeight,
691
                           double dfFalseEasting, double dfFalseNorthing);
692
693
    /** Pole rotation (GRIB convention) */
694
    OGRErr SetDerivedGeogCRSWithPoleRotationGRIBConvention(
695
        const char *pszCRSName, double dfSouthPoleLat, double dfSouthPoleLon,
696
        double dfAxisRotation);
697
698
    /** Pole rotation (netCDF CF convention) */
699
    OGRErr SetDerivedGeogCRSWithPoleRotationNetCDFCFConvention(
700
        const char *pszCRSName, double dfGridNorthPoleLat,
701
        double dfGridNorthPoleLon, double dfNorthPoleGridLon);
702
703
    /** State Plane */
704
    OGRErr SetStatePlane(int nZone, int bNAD83 = TRUE,
705
                         const char *pszOverrideUnitName = nullptr,
706
                         double dfOverrideUnit = 0.0);
707
708
    /** ImportFromESRIStatePlaneWKT */
709
    OGRErr ImportFromESRIStatePlaneWKT(int nCode, const char *pszDatumName,
710
                                       const char *pszUnitsName, int nPCSCode,
711
                                       const char *pszCRSName = nullptr);
712
713
    /** ImportFromESRIWisconsinWKT */
714
    OGRErr ImportFromESRIWisconsinWKT(const char *pszPrjName,
715
                                      double dfCentralMeridian,
716
                                      double dfLatOfOrigin,
717
                                      const char *pszUnitsName,
718
                                      const char *pszCRSName = nullptr);
719
720
    /*! @cond Doxygen_Suppress */
721
    void UpdateCoordinateSystemFromGeogCRS();
722
    /*! @endcond */
723
724
    static OGRSpatialReference *GetWGS84SRS();
725
726
    /** Convert a OGRSpatialReference* to a OGRSpatialReferenceH.
727
     * @since GDAL 2.3
728
     */
729
    static inline OGRSpatialReferenceH ToHandle(OGRSpatialReference *poSRS)
730
0
    {
731
0
        return reinterpret_cast<OGRSpatialReferenceH>(poSRS);
732
0
    }
733
734
    /** Convert a OGRSpatialReferenceH to a OGRSpatialReference*.
735
     * @since GDAL 2.3
736
     */
737
    static inline OGRSpatialReference *FromHandle(OGRSpatialReferenceH hSRS)
738
3.13k
    {
739
3.13k
        return reinterpret_cast<OGRSpatialReference *>(hSRS);
740
3.13k
    }
OGRSpatialReference::FromHandle(OGRSpatialReferenceHS*)
Line
Count
Source
738
3.13k
    {
739
3.13k
        return reinterpret_cast<OGRSpatialReference *>(hSRS);
740
3.13k
    }
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
     * @since GDAL 2.3
937
     */
938
    static inline OGRCoordinateTransformationH
939
    ToHandle(OGRCoordinateTransformation *poCT)
940
0
    {
941
0
        return reinterpret_cast<OGRCoordinateTransformationH>(poCT);
942
0
    }
943
944
    /** Convert a OGRCoordinateTransformationH to a
945
     * OGRCoordinateTransformation*.
946
     * @since GDAL 2.3
947
     */
948
    static inline OGRCoordinateTransformation *
949
    FromHandle(OGRCoordinateTransformationH hCT)
950
0
    {
951
0
        return reinterpret_cast<OGRCoordinateTransformation *>(hCT);
952
0
    }
Unexecuted instantiation: OGRCoordinateTransformation::FromHandle(OGRCoordinateTransformationHS*)
Unexecuted instantiation: OGRCoordinateTransformation::FromHandle(void*)
953
954
    /** Clone
955
     * @since GDAL 3.1
956
     */
957
    virtual OGRCoordinateTransformation *Clone() const = 0;
958
959
    /** Return a coordinate transformation that performs the inverse
960
     * transformation of the current one.
961
     *
962
     * In some cases, this is not possible, and this method might return
963
     * nullptr, or fail to perform the transformations.
964
     *
965
     * @return the new coordinate transformation, or nullptr in case of error.
966
     * @since GDAL 3.3
967
     */
968
    virtual OGRCoordinateTransformation *GetInverse() const = 0;
969
970
  protected:
971
    /*! @cond Doxygen_Suppress */
972
0
    OGRCoordinateTransformation() = default;
973
0
    OGRCoordinateTransformation(const OGRCoordinateTransformation &) = default;
974
    OGRCoordinateTransformation &
975
    operator=(const OGRCoordinateTransformation &) = default;
976
    OGRCoordinateTransformation(OGRCoordinateTransformation &&) = default;
977
    OGRCoordinateTransformation &
978
    operator=(OGRCoordinateTransformation &&) = default;
979
    /*! @endcond */
980
};
981
982
OGRCoordinateTransformation CPL_DLL *
983
OGRCreateCoordinateTransformation(const OGRSpatialReference *poSource,
984
                                  const OGRSpatialReference *poTarget);
985
986
/**
987
 * Context for coordinate transformation.
988
 *
989
 * @since GDAL 3.0
990
 */
991
992
struct CPL_DLL OGRCoordinateTransformationOptions
993
{
994
    /*! @cond Doxygen_Suppress */
995
  private:
996
    friend class OGRProjCT;
997
    struct Private;
998
    std::unique_ptr<Private> d;
999
    /*! @endcond */
1000
1001
  public:
1002
    OGRCoordinateTransformationOptions();
1003
    OGRCoordinateTransformationOptions(
1004
        const OGRCoordinateTransformationOptions &);
1005
    OGRCoordinateTransformationOptions &
1006
    operator=(const OGRCoordinateTransformationOptions &);
1007
    ~OGRCoordinateTransformationOptions();
1008
1009
    bool SetAreaOfInterest(double dfWestLongitudeDeg, double dfSouthLatitudeDeg,
1010
                           double dfEastLongitudeDeg,
1011
                           double dfNorthLatitudeDeg);
1012
    bool SetDesiredAccuracy(double dfAccuracy);
1013
    bool SetBallparkAllowed(bool bAllowBallpark);
1014
    bool SetOnlyBest(bool bOnlyBest);
1015
1016
    bool SetCoordinateOperation(const char *pszCT, bool bReverseCT);
1017
    /*! @cond Doxygen_Suppress */
1018
    void SetSourceCenterLong(double dfCenterLong);
1019
    void SetTargetCenterLong(double dfCenterLong);
1020
    /*! @endcond */
1021
};
1022
1023
OGRCoordinateTransformation CPL_DLL *OGRCreateCoordinateTransformation(
1024
    const OGRSpatialReference *poSource, const OGRSpatialReference *poTarget,
1025
    const OGRCoordinateTransformationOptions &options);
1026
1027
#endif /* ndef OGR_SPATIALREF_H_INCLUDED */