Coverage Report

Created: 2026-04-10 07:04

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