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