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