Coverage Report

Created: 2026-07-25 06:50

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