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