Line data Source code
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 281917 : 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 : {
71 : return nChildren == 0;
72 : }
73 :
74 482039 : int GetChildCount() const
75 : {
76 482039 : return nChildren;
77 : }
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 685426 : const char *GetValue() const
93 : {
94 685426 : return pszValue;
95 : }
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 6053 : double GetLinearUnits(std::nullptr_t) const
326 : {
327 6053 : return GetLinearUnits(static_cast<const char **>(nullptr));
328 : }
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 : {
345 : return GetTargetLinearUnits(pszTargetKey,
346 : static_cast<const char **>(nullptr));
347 : }
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 2346 : double GetAngularUnits(std::nullptr_t) const
361 : {
362 2346 : return GetAngularUnits(static_cast<const char **>(nullptr));
363 : }
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 1251 : double GetPrimeMeridian(std::nullptr_t) const
376 : {
377 1251 : return GetPrimeMeridian(static_cast<const char **>(nullptr));
378 : }
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 CopyGeogCSFrom(const OGRSpatialReference *poSrcSRS,
419 : bool bInnerMostGeogCRS);
420 : OGRErr SetVertCS(const char *pszVertCSName, const char *pszVertDatumName,
421 : int nVertDatumClass = 2005);
422 : OGRErr SetCompoundCS(const char *pszName,
423 : const OGRSpatialReference *poHorizSRS,
424 : const OGRSpatialReference *poVertSRS);
425 :
426 : void SetCoordinateEpoch(double dfCoordinateEpoch);
427 : double GetCoordinateEpoch() const;
428 :
429 : // cppcheck-suppress functionStatic
430 : OGRErr PromoteTo3D(const char *pszName);
431 : // cppcheck-suppress functionStatic
432 : OGRErr DemoteTo2D(const char *pszName);
433 :
434 : OGRErr SetFromUserInput(const char *);
435 :
436 : static const char *const SET_FROM_USER_INPUT_LIMITATIONS[];
437 : static CSLConstList SET_FROM_USER_INPUT_LIMITATIONS_get();
438 :
439 : OGRErr SetFromUserInput(const char *, CSLConstList papszOptions);
440 :
441 : OGRErr SetTOWGS84(double, double, double, double = 0.0, double = 0.0,
442 : double = 0.0, double = 0.0);
443 : OGRErr GetTOWGS84(double *padfCoef, int nCoeff = 7) const;
444 : OGRErr AddGuessedTOWGS84();
445 :
446 : double GetSemiMajor(OGRErr * = nullptr) const;
447 : double GetSemiMinor(OGRErr * = nullptr) const;
448 : double GetInvFlattening(OGRErr * = nullptr) const;
449 : double GetEccentricity() const;
450 : double GetSquaredEccentricity() const;
451 :
452 : OGRErr SetAuthority(const char *pszTargetKey, const char *pszAuthority,
453 : int nCode);
454 :
455 : OGRErr AutoIdentifyEPSG();
456 : OGRSpatialReferenceH *FindMatches(CSLConstList papszOptions, int *pnEntries,
457 : int **ppanMatchConfidence) const;
458 : OGRSpatialReference *
459 : FindBestMatch(int nMinimumMatchConfidence = 90,
460 : const char *pszPreferredAuthority = "EPSG",
461 : CSLConstList papszOptions = nullptr) const;
462 :
463 : int GetEPSGGeogCS() const;
464 :
465 : const char *GetAuthorityCode(const char *pszTargetKey = nullptr) const;
466 : const char *GetAuthorityName(const char *pszTargetKey = nullptr) const;
467 : char *GetOGCURN() const;
468 :
469 : bool GetAreaOfUse(double *pdfWestLongitudeDeg, double *pdfSouthLatitudeDeg,
470 : double *pdfEastLongitudeDeg, double *pdfNorthLatitudeDeg,
471 : const char **ppszAreaName) const;
472 :
473 : const char *GetExtension(const char *pszTargetKey, const char *pszName,
474 : const char *pszDefault = nullptr) const;
475 : OGRErr SetExtension(const char *pszTargetKey, const char *pszName,
476 : const char *pszValue);
477 :
478 : int FindProjParm(const char *pszParameter,
479 : const OGR_SRSNode *poPROJCS = nullptr) const;
480 : OGRErr SetProjParm(const char *, double);
481 : double GetProjParm(const char *, double = 0.0, OGRErr * = nullptr) const;
482 :
483 : OGRErr SetNormProjParm(const char *, double);
484 : double GetNormProjParm(const char *, double = 0.0,
485 : OGRErr * = nullptr) const;
486 :
487 : static int IsAngularParameter(const char *);
488 : static int IsLongitudeParameter(const char *);
489 : static int IsLinearParameter(const char *);
490 :
491 : /** Albers Conic Equal Area */
492 : OGRErr SetACEA(double dfStdP1, double dfStdP2, double dfCenterLat,
493 : double dfCenterLong, double dfFalseEasting,
494 : double dfFalseNorthing);
495 :
496 : /** Azimuthal Equidistant */
497 : OGRErr SetAE(double dfCenterLat, double dfCenterLong, double dfFalseEasting,
498 : double dfFalseNorthing);
499 :
500 : /** Bonne */
501 : OGRErr SetBonne(double dfStdP1, double dfCentralMeridian,
502 : double dfFalseEasting, double dfFalseNorthing);
503 :
504 : /** Cylindrical Equal Area */
505 : OGRErr SetCEA(double dfStdP1, double dfCentralMeridian,
506 : double dfFalseEasting, double dfFalseNorthing);
507 :
508 : /** Cassini-Soldner */
509 : OGRErr SetCS(double dfCenterLat, double dfCenterLong, double dfFalseEasting,
510 : double dfFalseNorthing);
511 :
512 : /** Equidistant Conic */
513 : OGRErr SetEC(double dfStdP1, double dfStdP2, double dfCenterLat,
514 : double dfCenterLong, double dfFalseEasting,
515 : double dfFalseNorthing);
516 :
517 : /** Eckert I */
518 : OGRErr SetEckert(int nVariation, double dfCentralMeridian,
519 : double dfFalseEasting, double dfFalseNorthing);
520 :
521 : /** Eckert IV */
522 : OGRErr SetEckertIV(double dfCentralMeridian, double dfFalseEasting,
523 : double dfFalseNorthing);
524 :
525 : /** Eckert VI */
526 : OGRErr SetEckertVI(double dfCentralMeridian, double dfFalseEasting,
527 : double dfFalseNorthing);
528 :
529 : /** Equirectangular */
530 : OGRErr SetEquirectangular(double dfCenterLat, double dfCenterLong,
531 : double dfFalseEasting, double dfFalseNorthing);
532 : /** Equirectangular generalized form : */
533 : OGRErr SetEquirectangular2(double dfCenterLat, double dfCenterLong,
534 : double dfPseudoStdParallel1,
535 : double dfFalseEasting, double dfFalseNorthing);
536 :
537 : /** Geostationary Satellite */
538 : OGRErr SetGEOS(double dfCentralMeridian, double dfSatelliteHeight,
539 : double dfFalseEasting, double dfFalseNorthing);
540 :
541 : /** Goode Homolosine */
542 : OGRErr SetGH(double dfCentralMeridian, double dfFalseEasting,
543 : double dfFalseNorthing);
544 :
545 : /** Interrupted Goode Homolosine */
546 : OGRErr SetIGH();
547 :
548 : /** Gall Stereographic */
549 : OGRErr SetGS(double dfCentralMeridian, double dfFalseEasting,
550 : double dfFalseNorthing);
551 :
552 : /** Gauss Schreiber Transverse Mercator */
553 : OGRErr SetGaussSchreiberTMercator(double dfCenterLat, double dfCenterLong,
554 : double dfScale, double dfFalseEasting,
555 : double dfFalseNorthing);
556 :
557 : /** Gnomonic */
558 : OGRErr SetGnomonic(double dfCenterLat, double dfCenterLong,
559 : double dfFalseEasting, double dfFalseNorthing);
560 :
561 : /** Hotine Oblique Mercator */
562 : OGRErr SetHOM(double dfCenterLat, double dfCenterLong, double dfAzimuth,
563 : double dfRectToSkew, double dfScale, double dfFalseEasting,
564 : double dfFalseNorthing);
565 :
566 : /** Hotine Oblique Mercator 2 points */
567 : OGRErr SetHOM2PNO(double dfCenterLat, double dfLat1, double dfLong1,
568 : double dfLat2, double dfLong2, double dfScale,
569 : double dfFalseEasting, double dfFalseNorthing);
570 :
571 : /** Hotine Oblique Mercator Azimuth Center / Variant B */
572 : OGRErr SetHOMAC(double dfCenterLat, double dfCenterLong, double dfAzimuth,
573 : double dfRectToSkew, double dfScale, double dfFalseEasting,
574 : double dfFalseNorthing);
575 :
576 : /** Laborde Oblique Mercator */
577 : OGRErr SetLOM(double dfCenterLat, double dfCenterLong, double dfAzimuth,
578 : double dfScale, double dfFalseEasting,
579 : double dfFalseNorthing);
580 :
581 : /** International Map of the World Polyconic */
582 : OGRErr SetIWMPolyconic(double dfLat1, double dfLat2, double dfCenterLong,
583 : double dfFalseEasting, double dfFalseNorthing);
584 :
585 : /** Krovak Oblique Conic Conformal */
586 : OGRErr SetKrovak(double dfCenterLat, double dfCenterLong, double dfAzimuth,
587 : double dfPseudoStdParallelLat, double dfScale,
588 : double dfFalseEasting, double dfFalseNorthing);
589 :
590 : /** Lambert Azimuthal Equal-Area */
591 : OGRErr SetLAEA(double dfCenterLat, double dfCenterLong,
592 : double dfFalseEasting, double dfFalseNorthing);
593 :
594 : /** Lambert Conformal Conic */
595 : OGRErr SetLCC(double dfStdP1, double dfStdP2, double dfCenterLat,
596 : double dfCenterLong, double dfFalseEasting,
597 : double dfFalseNorthing);
598 :
599 : /** Lambert Conformal Conic 1SP */
600 : OGRErr SetLCC1SP(double dfCenterLat, double dfCenterLong, double dfScale,
601 : double dfFalseEasting, double dfFalseNorthing);
602 :
603 : /** Lambert Conformal Conic (Belgium) */
604 : OGRErr SetLCCB(double dfStdP1, double dfStdP2, double dfCenterLat,
605 : double dfCenterLong, double dfFalseEasting,
606 : double dfFalseNorthing);
607 :
608 : /** Miller Cylindrical */
609 : OGRErr SetMC(double dfCenterLat, double dfCenterLong, double dfFalseEasting,
610 : double dfFalseNorthing);
611 :
612 : /** Mercator 1SP */
613 : OGRErr SetMercator(double dfCenterLat, double dfCenterLong, double dfScale,
614 : double dfFalseEasting, double dfFalseNorthing);
615 :
616 : /** Mercator 2SP */
617 : OGRErr SetMercator2SP(double dfStdP1, double dfCenterLat,
618 : double dfCenterLong, double dfFalseEasting,
619 : double dfFalseNorthing);
620 :
621 : /** Mollweide */
622 : OGRErr SetMollweide(double dfCentralMeridian, double dfFalseEasting,
623 : double dfFalseNorthing);
624 :
625 : /** New Zealand Map Grid */
626 : OGRErr SetNZMG(double dfCenterLat, double dfCenterLong,
627 : double dfFalseEasting, double dfFalseNorthing);
628 :
629 : /** Oblique Stereographic */
630 : OGRErr SetOS(double dfOriginLat, double dfCMeridian, double dfScale,
631 : double dfFalseEasting, double dfFalseNorthing);
632 :
633 : /** Orthographic */
634 : OGRErr SetOrthographic(double dfCenterLat, double dfCenterLong,
635 : double dfFalseEasting, double dfFalseNorthing);
636 :
637 : /** Polyconic */
638 : OGRErr SetPolyconic(double dfCenterLat, double dfCenterLong,
639 : double dfFalseEasting, double dfFalseNorthing);
640 :
641 : /** Polar Stereographic */
642 : OGRErr SetPS(double dfCenterLat, double dfCenterLong, double dfScale,
643 : double dfFalseEasting, double dfFalseNorthing);
644 :
645 : /** Robinson */
646 : OGRErr SetRobinson(double dfCenterLong, double dfFalseEasting,
647 : double dfFalseNorthing);
648 :
649 : /** Sinusoidal */
650 : OGRErr SetSinusoidal(double dfCenterLong, double dfFalseEasting,
651 : double dfFalseNorthing);
652 :
653 : /** Stereographic */
654 : OGRErr SetStereographic(double dfCenterLat, double dfCenterLong,
655 : double dfScale, double dfFalseEasting,
656 : double dfFalseNorthing);
657 :
658 : /** Swiss Oblique Cylindrical */
659 : OGRErr SetSOC(double dfLatitudeOfOrigin, double dfCentralMeridian,
660 : double dfFalseEasting, double dfFalseNorthing);
661 :
662 : /** Transverse Mercator */
663 : OGRErr SetTM(double dfCenterLat, double dfCenterLong, double dfScale,
664 : double dfFalseEasting, double dfFalseNorthing);
665 :
666 : /** Transverse Mercator variants. */
667 : OGRErr SetTMVariant(const char *pszVariantName, double dfCenterLat,
668 : double dfCenterLong, double dfScale,
669 : double dfFalseEasting, double dfFalseNorthing);
670 :
671 : /** Tunesia Mining Grid */
672 : OGRErr SetTMG(double dfCenterLat, double dfCenterLong,
673 : double dfFalseEasting, double dfFalseNorthing);
674 :
675 : /** Transverse Mercator (South Oriented) */
676 : OGRErr SetTMSO(double dfCenterLat, double dfCenterLong, double dfScale,
677 : double dfFalseEasting, double dfFalseNorthing);
678 :
679 : /** Two Point Equidistant */
680 : OGRErr SetTPED(double dfLat1, double dfLong1, double dfLat2, double dfLong2,
681 : double dfFalseEasting, double dfFalseNorthing);
682 :
683 : /** VanDerGrinten */
684 : OGRErr SetVDG(double dfCenterLong, double dfFalseEasting,
685 : double dfFalseNorthing);
686 :
687 : /** Universal Transverse Mercator */
688 : OGRErr SetUTM(int nZone, int bNorth = TRUE);
689 : int GetUTMZone(int *pbNorth = nullptr) const;
690 :
691 : /** Wagner I \-- VII */
692 : OGRErr SetWagner(int nVariation, double dfCenterLat, double dfFalseEasting,
693 : double dfFalseNorthing);
694 :
695 : /** Quadrilateralized Spherical Cube */
696 : OGRErr SetQSC(double dfCenterLat, double dfCenterLong);
697 :
698 : /** Spherical, Cross-track, Height */
699 : OGRErr SetSCH(double dfPegLat, double dfPegLong, double dfPegHeading,
700 : double dfPegHgt);
701 :
702 : /** Vertical Perspective / Near-sided Perspective */
703 : OGRErr
704 : SetVerticalPerspective(double dfTopoOriginLat, double dfTopoOriginLon,
705 : double dfTopoOriginHeight, double dfViewPointHeight,
706 : double dfFalseEasting, double dfFalseNorthing);
707 :
708 : /** Pole rotation (GRIB convention) */
709 : OGRErr SetDerivedGeogCRSWithPoleRotationGRIBConvention(
710 : const char *pszCRSName, double dfSouthPoleLat, double dfSouthPoleLon,
711 : double dfAxisRotation);
712 :
713 : /** Pole rotation (netCDF CF convention) */
714 : OGRErr SetDerivedGeogCRSWithPoleRotationNetCDFCFConvention(
715 : const char *pszCRSName, double dfGridNorthPoleLat,
716 : double dfGridNorthPoleLon, double dfNorthPoleGridLon);
717 :
718 : /** State Plane */
719 : OGRErr SetStatePlane(int nZone, int bNAD83 = TRUE,
720 : const char *pszOverrideUnitName = nullptr,
721 : double dfOverrideUnit = 0.0);
722 :
723 : /** ImportFromESRIStatePlaneWKT */
724 : OGRErr ImportFromESRIStatePlaneWKT(int nCode, const char *pszDatumName,
725 : const char *pszUnitsName, int nPCSCode,
726 : const char *pszCRSName = nullptr);
727 :
728 : /** ImportFromESRIWisconsinWKT */
729 : OGRErr ImportFromESRIWisconsinWKT(const char *pszPrjName,
730 : double dfCentralMeridian,
731 : double dfLatOfOrigin,
732 : const char *pszUnitsName,
733 : const char *pszCRSName = nullptr);
734 :
735 : /*! @cond Doxygen_Suppress */
736 : void UpdateCoordinateSystemFromGeogCRS();
737 : /*! @endcond */
738 :
739 : static OGRSpatialReference *GetWGS84SRS();
740 :
741 : /** Convert a OGRSpatialReference* to a OGRSpatialReferenceH.
742 : */
743 34416 : static inline OGRSpatialReferenceH ToHandle(OGRSpatialReference *poSRS)
744 : {
745 34416 : return reinterpret_cast<OGRSpatialReferenceH>(poSRS);
746 : }
747 :
748 : /** Convert a OGRSpatialReferenceH to a OGRSpatialReference*.
749 : */
750 208715 : static inline OGRSpatialReference *FromHandle(OGRSpatialReferenceH hSRS)
751 : {
752 208715 : return reinterpret_cast<OGRSpatialReference *>(hSRS);
753 : }
754 : };
755 :
756 : /*! @cond Doxygen_Suppress */
757 :
758 : #include "ogr_refcountedptr.h"
759 :
760 : template <>
761 : struct OGRRefCountedPtr<OGRSpatialReference>
762 : : public OGRRefCountedPtrBase<OGRSpatialReference>
763 : {
764 : /** Constructs from a raw OGRSpatialReference instance.
765 : *
766 : * Be careful: a fresh OGRSpatialReference instance has a reference count
767 : * equal to one, so you generally want to set add_ref = false
768 : * So ``OGRSpatialReferenceRefCountedPtr srs(new OGRSpatialReference(), false)``
769 : * or less error prone ``auto srs = OGRSpatialReferenceRefCountedPtr::makeInstance()``
770 : */
771 21104 : inline explicit OGRRefCountedPtr(OGRSpatialReference *poSRS, bool add_ref)
772 21104 : : OGRRefCountedPtrBase<OGRSpatialReference>(poSRS, add_ref)
773 : {
774 21104 : }
775 :
776 : /** Constructs with a null OGRSpatialReference instance.
777 : */
778 152125 : inline OGRRefCountedPtr()
779 152125 : {
780 152125 : }
781 :
782 : /** Constructs with a null OGRSpatialReference instance.
783 : */
784 : // cppcheck-suppress noExplicitConstructor
785 127488 : inline /* implicit */ OGRRefCountedPtr(std::nullptr_t)
786 127488 : {
787 127488 : }
788 :
789 : /** Constructs with a new OGRSpatialReference instance initialized
790 : * with a WKT string (or in an empty state if pszWKT is nullptr).
791 : */
792 5802 : inline static OGRRefCountedPtr makeInstance(const char *pszWKT = nullptr)
793 : {
794 : // Initial ref_count of OGRSpatialReference is 1, so don't add a ref
795 5802 : return OGRRefCountedPtr(new OGRSpatialReference(pszWKT),
796 5802 : /* add_ref = */ false);
797 : }
798 :
799 : /** Constructs with a clone of an existing OGRSpatialReference instance.
800 : */
801 14256 : inline static OGRRefCountedPtr makeClone(const OGRSpatialReference *poSRS)
802 : {
803 5893 : return OGRRefCountedPtr(poSRS ? poSRS->Clone() : nullptr,
804 20149 : /* add_ref = */ false);
805 : }
806 :
807 : /** Constructs with a clone of an existing OGRSpatialReference instance.
808 : */
809 10 : inline static OGRRefCountedPtr makeClone(const OGRSpatialReference &oSRS)
810 : {
811 : return OGRRefCountedPtr(oSRS.Clone(),
812 10 : /* add_ref = */ false);
813 : }
814 :
815 : /** Reset the managed raw pointer.
816 : *
817 : * Release the current managed raw pointer.
818 : */
819 4 : inline void reset()
820 : {
821 4 : OGRRefCountedPtrBase<OGRSpatialReference>::reset(nullptr, false);
822 4 : }
823 :
824 : /** Reset the managed raw pointer.
825 : *
826 : * Release the current managed raw pointer and manages a new one.
827 : * By default, increases the reference count of the new raw pointer (when
828 : * not null).
829 : */
830 39869 : inline void reset(OGRSpatialReference *poRawPtr, bool add_ref)
831 : {
832 39869 : OGRRefCountedPtrBase<OGRSpatialReference>::reset(poRawPtr, add_ref);
833 39869 : }
834 :
835 : /** Use reset(OGRSpatialReference *poRawPtr, bool add_ref) to be explicit
836 : * about ref counting.
837 : */
838 : inline void reset(OGRSpatialReference *poRawPtr) = delete;
839 : };
840 :
841 : /** Smart pointer around OGRSpatialReference.
842 : *
843 : * It uses OGRSpatialReference built-in reference counting, to increase the reference
844 : * count when assigning a raw pointer to the smart pointer, and decrease it
845 : * when releasing it.
846 : * Somewhat similar to https://www.boost.org/doc/libs/latest/libs/smart_ptr/doc/html/smart_ptr.html#intrusive_ptr
847 : */
848 : using OGRSpatialReferenceRefCountedPtr = OGRRefCountedPtr<OGRSpatialReference>;
849 :
850 : /*! @endcond */
851 :
852 : /************************************************************************/
853 : /* OGRCoordinateTransformation */
854 : /* */
855 : /* This is really just used as a base class for a private */
856 : /* implementation. */
857 : /************************************************************************/
858 :
859 : /**
860 : * Interface for transforming between coordinate systems.
861 : *
862 : * Currently, the only implementation within OGR is OGRProjCT, which
863 : * requires the PROJ library.
864 : *
865 : * Also, see OGRCreateCoordinateTransformation() for creating transformations.
866 : */
867 :
868 21018 : class CPL_DLL OGRCoordinateTransformation
869 : {
870 : public:
871 : virtual ~OGRCoordinateTransformation();
872 :
873 : static void DestroyCT(OGRCoordinateTransformation *poCT);
874 :
875 : // From CT_CoordinateTransformation
876 :
877 : /** Fetch internal source coordinate system. */
878 : virtual const OGRSpatialReference *GetSourceCS() const = 0;
879 :
880 : /** Fetch internal target coordinate system. */
881 : virtual const OGRSpatialReference *GetTargetCS() const = 0;
882 :
883 : /** Whether the transformer will emit CPLError */
884 0 : virtual bool GetEmitErrors() const
885 : {
886 0 : return false;
887 : }
888 :
889 : /** Set if the transformer must emit CPLError */
890 0 : virtual void SetEmitErrors(bool /*bEmitErrors*/)
891 : {
892 0 : }
893 :
894 : // From CT_MathTransform
895 :
896 : /**
897 : * Transform points from source to destination space.
898 : *
899 : * This method is the same as the C function OCTTransformEx().
900 : *
901 : * @param nCount number of points to transform (`size_t` type since 3.9,
902 : * `int` in previous versions).
903 : * @param x array of nCount X vertices, modified in place. Should not be
904 : * NULL.
905 : * @param y array of nCount Y vertices, modified in place. Should not be
906 : * NULL.
907 : * @param z array of nCount Z vertices, modified in place. Might be NULL.
908 : * @param pabSuccess array of per-point flags set to TRUE if that point
909 : * transforms, or FALSE if it does not. Might be NULL.
910 : *
911 : * @return TRUE on success, or FALSE if some or all points fail to
912 : * transform. When FALSE is returned the pabSuccess[] array indicates which
913 : * points succeeded or failed to transform. When TRUE is returned, all
914 : * values in pabSuccess[] are set to true.
915 : */
916 : int Transform(size_t nCount, double *x, double *y, double *z = nullptr,
917 : int *pabSuccess = nullptr);
918 :
919 : /**
920 : * Transform points from source to destination space.
921 : *
922 : * This method is the same as the C function OCTTransform4D().
923 : *
924 : * @param nCount number of points to transform (`size_t` type since 3.9,
925 : * `int` in previous versions).
926 : * @param x array of nCount X vertices, modified in place. Should not be
927 : * NULL.
928 : * @param y array of nCount Y vertices, modified in place. Should not be
929 : * NULL.
930 : * @param z array of nCount Z vertices, modified in place. Might be NULL.
931 : * @param t array of nCount time values, modified in place. Might be NULL.
932 : * @param pabSuccess array of per-point flags set to TRUE if that point
933 : * transforms, or FALSE if it does not. Might be NULL.
934 : *
935 : * @return TRUE on success, or FALSE if some or all points fail to
936 : * transform. When FALSE is returned the pabSuccess[] array indicates which
937 : * points succeeded or failed to transform. When TRUE is returned, all
938 : * values in pabSuccess[] are set to true.
939 : * Caution: prior to GDAL 3.11, TRUE could be returned if a
940 : * transformation could be found but not all points may
941 : * have necessarily succeed to transform.
942 : */
943 : virtual int Transform(size_t nCount, double *x, double *y, double *z,
944 : double *t, int *pabSuccess) = 0;
945 :
946 : /**
947 : * Transform points from source to destination space.
948 : *
949 : * This method is the same as the C function OCTTransform4DWithErrorCodes().
950 : *
951 : * @param nCount number of points to transform (`size_t` type since 3.9,
952 : * `int` in previous versions).
953 : * @param x array of nCount X vertices, modified in place. Should not be
954 : * NULL.
955 : * @param y array of nCount Y vertices, modified in place. Should not be
956 : * NULL.
957 : * @param z array of nCount Z vertices, modified in place. Might be NULL.
958 : * @param t array of nCount time values, modified in place. Might be NULL.
959 : * @param panErrorCodes Output array of nCount value that will be set to 0
960 : * for success, or a non-zero value for failure. Refer to PROJ 8 public
961 : * error codes. Might be NULL
962 : * @return TRUE on success, or FALSE if some or all points fail to
963 : * transform. When FALSE is returned the panErrorCodes[] array indicates
964 : * which points succeeded or failed to transform. When TRUE is returned, all
965 : * values in panErrorCodes[] are set to zero.
966 : * Caution: prior to GDAL 3.11, TRUE could be returned if a
967 : * transformation could be found but not all points may
968 : * have necessarily succeed to transform.
969 : * @since GDAL 3.3, and PROJ 8 to be able to use PROJ public error codes
970 : */
971 : virtual int TransformWithErrorCodes(size_t nCount, double *x, double *y,
972 : double *z, double *t,
973 : int *panErrorCodes);
974 :
975 : /** \brief Transform boundary.
976 : *
977 : * This method is the same as the C function OCTTransformBounds().
978 : *
979 : * Transform boundary densifying the edges to account for nonlinear
980 : * transformations along these edges and extracting the outermost bounds.
981 : *
982 : * If the destination CRS is geographic, the first axis is longitude,
983 : * and xmax < xmin then the bounds crossed the antimeridian.
984 : * In this scenario there are two polygons, one on each side of the
985 : * antimeridian. The first polygon should be constructed with (xmin, ymin,
986 : * 180, ymax) and the second with (-180, ymin, xmax, ymax).
987 : *
988 : * If the destination CRS is geographic, the first axis is latitude,
989 : * and ymax < ymin then the bounds crossed the antimeridian.
990 : * In this scenario there are two polygons, one on each side of the
991 : * antimeridian. The first polygon should be constructed with (ymin, xmin,
992 : * ymax, 180) and the second with (ymin, -180, ymax, xmax).
993 : *
994 : * @param xmin Minimum bounding coordinate of the first axis in source CRS.
995 : * @param ymin Minimum bounding coordinate of the second axis in source CRS.
996 : * @param xmax Maximum bounding coordinate of the first axis in source CRS.
997 : * @param ymax Maximum bounding coordinate of the second axis in source CRS.
998 : * @param out_xmin Minimum bounding coordinate of the first axis in target
999 : * CRS
1000 : * @param out_ymin Minimum bounding coordinate of the second axis in target
1001 : * CRS.
1002 : * @param out_xmax Maximum bounding coordinate of the first axis in target
1003 : * CRS.
1004 : * @param out_ymax Maximum bounding coordinate of the second axis in target
1005 : * CRS.
1006 : * @param densify_pts Recommended to use 21. This is the number of points
1007 : * to use to densify the bounding polygon in the transformation.
1008 : * @return TRUE if successful. FALSE if failures encountered.
1009 : * @since 3.4
1010 : */
1011 0 : virtual int TransformBounds(const double xmin, const double ymin,
1012 : const double xmax, const double ymax,
1013 : double *out_xmin, double *out_ymin,
1014 : double *out_xmax, double *out_ymax,
1015 : const int densify_pts)
1016 : {
1017 : (void)xmin;
1018 : (void)xmax;
1019 : (void)ymin;
1020 : (void)ymax;
1021 : (void)densify_pts;
1022 0 : *out_xmin = HUGE_VAL;
1023 0 : *out_ymin = HUGE_VAL;
1024 0 : *out_xmax = HUGE_VAL;
1025 0 : *out_ymax = HUGE_VAL;
1026 0 : CPLError(CE_Failure, CPLE_AppDefined,
1027 : "TransformBounds not implemented.");
1028 0 : return false;
1029 : }
1030 :
1031 : /** Convert a OGRCoordinateTransformation* to a
1032 : * OGRCoordinateTransformationH.
1033 : */
1034 : static inline OGRCoordinateTransformationH
1035 3 : ToHandle(OGRCoordinateTransformation *poCT)
1036 : {
1037 3 : return reinterpret_cast<OGRCoordinateTransformationH>(poCT);
1038 : }
1039 :
1040 : /** Convert a OGRCoordinateTransformationH to a
1041 : * OGRCoordinateTransformation*.
1042 : */
1043 : static inline OGRCoordinateTransformation *
1044 1456 : FromHandle(OGRCoordinateTransformationH hCT)
1045 : {
1046 1456 : return reinterpret_cast<OGRCoordinateTransformation *>(hCT);
1047 : }
1048 :
1049 : /** Clone
1050 : * @since GDAL 3.1
1051 : */
1052 : virtual OGRCoordinateTransformation *Clone() const = 0;
1053 :
1054 : /** Return a coordinate transformation that performs the inverse
1055 : * transformation of the current one.
1056 : *
1057 : * In some cases, this is not possible, and this method might return
1058 : * nullptr, or fail to perform the transformations.
1059 : *
1060 : * @return the new coordinate transformation, or nullptr in case of error.
1061 : * @since GDAL 3.3
1062 : */
1063 : virtual OGRCoordinateTransformation *GetInverse() const = 0;
1064 :
1065 : protected:
1066 : /*! @cond Doxygen_Suppress */
1067 10098 : OGRCoordinateTransformation() = default;
1068 934 : OGRCoordinateTransformation(const OGRCoordinateTransformation &) = default;
1069 : OGRCoordinateTransformation &
1070 : operator=(const OGRCoordinateTransformation &) = default;
1071 1294 : OGRCoordinateTransformation(OGRCoordinateTransformation &&) = default;
1072 : OGRCoordinateTransformation &
1073 : operator=(OGRCoordinateTransformation &&) = default;
1074 : /*! @endcond */
1075 : };
1076 :
1077 : OGRCoordinateTransformation CPL_DLL *
1078 : OGRCreateCoordinateTransformation(const OGRSpatialReference *poSource,
1079 : const OGRSpatialReference *poTarget);
1080 :
1081 : /**
1082 : * Context for coordinate transformation.
1083 : *
1084 : * @since GDAL 3.0
1085 : */
1086 :
1087 : struct CPL_DLL OGRCoordinateTransformationOptions
1088 : {
1089 : /*! @cond Doxygen_Suppress */
1090 : private:
1091 : friend class OGRProjCT;
1092 : struct Private;
1093 : std::unique_ptr<Private> d;
1094 : /*! @endcond */
1095 :
1096 : public:
1097 : OGRCoordinateTransformationOptions();
1098 : OGRCoordinateTransformationOptions(
1099 : const OGRCoordinateTransformationOptions &);
1100 : OGRCoordinateTransformationOptions &
1101 : operator=(const OGRCoordinateTransformationOptions &);
1102 : ~OGRCoordinateTransformationOptions();
1103 :
1104 : bool SetAreaOfInterest(double dfWestLongitudeDeg, double dfSouthLatitudeDeg,
1105 : double dfEastLongitudeDeg,
1106 : double dfNorthLatitudeDeg);
1107 : bool SetDesiredAccuracy(double dfAccuracy);
1108 : bool SetBallparkAllowed(bool bAllowBallpark);
1109 : bool SetOnlyBest(bool bOnlyBest);
1110 :
1111 : bool SetCoordinateOperation(const char *pszCT, bool bReverseCT);
1112 : /*! @cond Doxygen_Suppress */
1113 : void SetSourceCenterLong(double dfCenterLong);
1114 : void SetTargetCenterLong(double dfCenterLong);
1115 : /*! @endcond */
1116 : };
1117 :
1118 : OGRCoordinateTransformation CPL_DLL *OGRCreateCoordinateTransformation(
1119 : const OGRSpatialReference *poSource, const OGRSpatialReference *poTarget,
1120 : const OGRCoordinateTransformationOptions &options);
1121 :
1122 : #endif /* ndef OGR_SPATIALREF_H_INCLUDED */
|