QGIS API Documentation  3.27.0-Master (597e8eebd4)
qgscoordinatereferencesystem.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgscoordinatereferencesystem.h
3 
4  -------------------
5  begin : 2007
6  copyright : (C) 2007 by Gary E. Sherman
7  email : [email protected]
8 ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 #ifndef QGSCOORDINATEREFERENCESYSTEM_H
19 #define QGSCOORDINATEREFERENCESYSTEM_H
20 
21 //Standard includes
22 #include "qgis_core.h"
23 #include <ostream>
24 
25 //qt includes
26 #include <QString>
27 #include <QMap>
28 #include <QHash>
29 #include <QReadWriteLock>
30 #include <QExplicitlySharedDataPointer>
31 #include <QObject>
32 
33 //qgis includes
34 #include "qgis_sip.h"
35 #include "qgsconfig.h"
36 #include "qgsunittypes.h"
37 #include "qgsrectangle.h"
38 #include "qgssqliteutils.h"
39 
40 class QDomNode;
41 class QDomDocument;
42 class QgsCoordinateReferenceSystemPrivate;
43 class QgsDatumEnsemble;
45 class QgsProjOperation;
46 
47 #ifndef SIP_RUN
48 struct PJconsts;
49 typedef struct PJconsts PJ;
50 
51 #if PROJ_VERSION_MAJOR>=8
52 struct pj_ctx;
53 typedef struct pj_ctx PJ_CONTEXT;
54 #else
55 struct projCtx_t;
56 typedef struct projCtx_t PJ_CONTEXT;
57 #endif
58 #endif
59 
60 // forward declaration for sqlite3
61 typedef struct sqlite3 sqlite3 SIP_SKIP;
62 
63 #ifdef DEBUG
64 typedef struct OGRSpatialReferenceHS *OGRSpatialReferenceH SIP_SKIP;
65 #else
67 #endif
68 
71 
212 {
213  Q_GADGET
214 
215  Q_PROPERTY( QgsUnitTypes::DistanceUnit mapUnits READ mapUnits )
216  Q_PROPERTY( bool isGeographic READ isGeographic )
217  Q_PROPERTY( QString authid READ authid )
218  Q_PROPERTY( QString description READ description )
219 
220  public:
221 
223  enum CrsType
224  {
227  EpsgCrsId
228  };
229 
232 
234 
235  // TODO QGIS 4: remove "POSTGIS" and "INTERNAL"
236 
252  explicit QgsCoordinateReferenceSystem( const QString &definition );
253 
254  // TODO QGIS 4: remove type and always use EPSG code
255 
267  Q_DECL_DEPRECATED explicit QgsCoordinateReferenceSystem( long id, CrsType type = PostgisCrsId ) SIP_DEPRECATED;
268 
271 
274 
276  operator QVariant() const
277  {
278  return QVariant::fromValue( *this );
279  }
280 
288  static QList< long > validSrsIds();
289 
290  // static creators
291 
299  static QgsCoordinateReferenceSystem fromOgcWmsCrs( const QString &ogcCrs );
300 
307  Q_INVOKABLE static QgsCoordinateReferenceSystem fromEpsgId( long epsg );
308 
315  Q_DECL_DEPRECATED static QgsCoordinateReferenceSystem fromProj4( const QString &proj4 ) SIP_DEPRECATED;
316 
324  static QgsCoordinateReferenceSystem fromProj( const QString &proj );
325 
333  static QgsCoordinateReferenceSystem fromWkt( const QString &wkt );
334 
343  static QgsCoordinateReferenceSystem fromSrsId( long srsId );
344 
345  // Misc helper functions -----------------------
346 
347  // TODO QGIS 4: remove type and always use EPSG code, rename to createFromEpsg
348 
354  Q_DECL_DEPRECATED bool createFromId( long id, CrsType type = PostgisCrsId ) SIP_DEPRECATED;
355 
356  // TODO QGIS 4: remove "QGIS" and "CUSTOM", only support "USER" (also returned by authid())
357 
368  bool createFromOgcWmsCrs( const QString &crs );
369 
370  // TODO QGIS 4: remove unless really necessary - let's use EPSG codes instead
371 
379  Q_DECL_DEPRECATED bool createFromSrid( long srid ) SIP_DEPRECATED;
380 
393  bool createFromWkt( const QString &wkt );
394 
407  bool createFromSrsId( long srsId );
408 
432  Q_DECL_DEPRECATED bool createFromProj4( const QString &projString ) SIP_DEPRECATED;
433 
461 #ifndef SIP_RUN
462  bool createFromProj( const QString &projString, bool identify = true );
463 #else
464  bool createFromProj( const QString &projString );
465 #endif
466 
482  bool createFromString( const QString &definition );
483 
484  // TODO QGIS 4: rename to createFromStringOGR so it is clear it's similar to createFromString, just different backend
485 
501  bool createFromUserInput( const QString &definition );
502 
513  Q_DECL_DEPRECATED static void setupESRIWktFix() SIP_DEPRECATED;
514 
516  bool isValid() const;
517 
529  void validate();
530 
531  // TODO QGIS 4: seems completely obsolete now (only compares proj4 - already done in createFromProj4)
532 
541  Q_DECL_DEPRECATED long findMatchingProj() SIP_DEPRECATED;
542 
548  bool operator==( const QgsCoordinateReferenceSystem &srs ) const;
549 
555  bool operator!=( const QgsCoordinateReferenceSystem &srs ) const;
556 
563  bool readXml( const QDomNode &node );
564 
571  bool writeXml( QDomNode &node, QDomDocument &doc ) const;
572 
573 
578  static void setCustomCrsValidation( CUSTOM_CRS_VALIDATION f ) SIP_SKIP;
579 
584  static CUSTOM_CRS_VALIDATION customCrsValidation() SIP_SKIP;
585 
586  // Accessors -----------------------------------
587 
592  long srsid() const;
593 
594  // TODO QGIS 4: remove unless really necessary - let's use EPSG codes instead
595 
600  long postgisSrid() const;
601 
614  QString authid() const;
615 
623  QString description() const;
624 
631  {
635  };
636 
650  QString userFriendlyIdentifier( IdentifierType type = MediumString ) const;
651 
658  QString projectionAcronym() const;
659 
666  QString ellipsoidAcronym() const;
667 
670  {
677  WKT2_2019 = WKT2_2018,
678  WKT2_2019_SIMPLIFIED = WKT2_2018_SIMPLIFIED,
679 
680  WKT_PREFERRED = WKT2_2019,
681  WKT_PREFERRED_SIMPLIFIED = WKT2_2019_SIMPLIFIED,
682  WKT_PREFERRED_GDAL = WKT2_2019,
683  };
684 
696  QString toWkt( WktVariant variant = WKT1_GDAL, bool multiline = false, int indentationWidth = 4 ) const;
697 
710  Q_DECL_DEPRECATED QString toProj4() const SIP_DEPRECATED;
711 
724  QString toProj() const;
725 
730  bool isGeographic() const;
731 
740  bool isDynamic() const;
741 
754  QgsDatumEnsemble datumEnsemble() const SIP_THROW( QgsNotSupportedException );
755 
765  QString celestialBodyName() const SIP_THROW( QgsNotSupportedException );
766 
790  void setCoordinateEpoch( double epoch );
791 
815  double coordinateEpoch() const;
816 
828  QgsProjectionFactors factors( const QgsPoint &point ) const;
829 
836  QgsProjOperation operation() const;
837 
842  bool hasAxisInverted() const;
843 
849 #ifndef SIP_RUN
850  QList< Qgis::CrsAxisDirection > axisOrdering() const;
851 #else
852  SIP_PYOBJECT axisOrdering() const SIP_TYPEHINT( List[Qgis.CrsAxisDirection] );
853  % MethodCode
854  // adapted from the qpymultimedia_qlist.sip file from the PyQt6 sources
855 
856  const QList< Qgis::CrsAxisDirection > cppRes = sipCpp->axisOrdering();
857 
858  PyObject *l = PyList_New( cppRes.size() );
859 
860  if ( !l )
861  sipIsErr = 1;
862  else
863  {
864  for ( int i = 0; i < cppRes.size(); ++i )
865  {
866  PyObject *eobj = sipConvertFromEnum( static_cast<int>( cppRes.at( i ) ),
867  sipType_Qgis_CrsAxisDirection );
868 
869  if ( !eobj )
870  {
871  sipIsErr = 1;
872  }
873 
874  PyList_SetItem( l, i, eobj );
875  }
876 
877  if ( !sipIsErr )
878  {
879  sipRes = l;
880  }
881  else
882  {
883  Py_DECREF( l );
884  }
885  }
886  % End
887 #endif
888 
892  QgsUnitTypes::DistanceUnit mapUnits() const;
893 
902  QgsRectangle bounds() const;
903 
904  // Mutators -----------------------------------
905 
922  void updateDefinition();
923 
927  void setValidationHint( const QString &html );
928 
932  QString validationHint() const;
933 
940  static int syncDatabase();
941 
955  long saveAsUserCrs( const QString &name, Qgis::CrsDefinitionFormat nativeFormat = Qgis::CrsDefinitionFormat::Wkt );
956 
966  void setNativeFormat( Qgis::CrsDefinitionFormat format );
967 
977  Qgis::CrsDefinitionFormat nativeFormat() const;
978 
988  QgsCoordinateReferenceSystem toGeographicCrs() const;
989 
991  QString geographicCrsAuthId() const;
992 
993 #ifdef SIP_RUN
994  SIP_PYOBJECT __repr__();
995  % MethodCode
996  const QString str = sipCpp->isValid() ? QStringLiteral( "<QgsCoordinateReferenceSystem: %1%2>" ).arg( !sipCpp->authid().isEmpty() ? sipCpp->authid() : sipCpp->toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ),
997  std::isfinite( sipCpp->coordinateEpoch() ) ? QStringLiteral( " @ %1" ).arg( sipCpp->coordinateEpoch() ) : QString() )
998  : QStringLiteral( "<QgsCoordinateReferenceSystem: invalid>" );
999  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
1000  % End
1001 #endif
1002 
1003 #ifndef SIP_RUN
1004 
1014  PJ *projObject() const;
1015 
1026  static QgsCoordinateReferenceSystem fromProjObject( PJ *object );
1027 
1036  bool createFromProjObject( PJ *object );
1037 #endif
1038 
1044  Q_DECL_DEPRECATED static QStringList recentProjections() SIP_DEPRECATED;
1045 
1050  static QList< QgsCoordinateReferenceSystem > recentCoordinateReferenceSystems();
1051 
1056  static void pushRecentCoordinateReferenceSystem( const QgsCoordinateReferenceSystem &crs );
1057 
1058 #ifndef SIP_RUN
1059 
1070  static void invalidateCache( bool disableCache = false );
1071 #else
1072 
1080  static void invalidateCache( bool disableCache SIP_PYARGREMOVE = false );
1081 #endif
1082 
1083  // Mutators -----------------------------------
1084  // We don't want to expose these to the public api since they won't create
1085  // a fully valid crs. Programmers should use the createFrom* methods rather
1086  private:
1087 
1093  static QString projFromSrsId( int srsId );
1094 
1100  void setProjString( const QString &projString );
1101 
1105  bool setWktString( const QString &wkt );
1106 
1110  void debugPrint();
1111 
1113  typedef QMap<QString, QString> RecordMap;
1114 
1122  RecordMap getRecord( const QString &sql );
1123 
1128  static int openDatabase( const QString &path, sqlite3_database_unique_ptr &database, bool readonly = true );
1129 
1131  void setMapUnits();
1132 
1134  static long getRecordCount();
1135 
1136  bool loadFromAuthCode( const QString &auth, const QString &code );
1137 
1141  static QList< long > userSrsIds();
1142 
1150  long matchToUserCrs() const;
1151 
1156  bool loadFromDatabase( const QString &db, const QString &expression, const QString &value );
1157 
1158  bool createFromWktInternal( const QString &wkt, const QString &description );
1159 
1160  QExplicitlySharedDataPointer<QgsCoordinateReferenceSystemPrivate> d;
1161 
1162  QString mValidationHint;
1163 
1164  Qgis::CrsDefinitionFormat mNativeFormat = Qgis::CrsDefinitionFormat::Wkt;
1165 
1166  friend class QgsProjContext;
1167 
1168  // Only meant to be called by QgsProjContext::~QgsProjContext()
1169  static void removeFromCacheObjectsBelongingToCurrentThread( PJ_CONTEXT *pj_context );
1170 
1172  static CUSTOM_CRS_VALIDATION sCustomSrsValidation;
1173 
1174  // cache
1175 
1176  static bool sDisableSrIdCache;
1177  static bool sDisableOgcCache;
1178  static bool sDisableProjCache;
1179  static bool sDisableWktCache;
1180  static bool sDisableSrsIdCache;
1181  static bool sDisableStringCache;
1182 
1183  // for tests
1184  static const QHash< QString, QgsCoordinateReferenceSystem > &stringCache();
1185  static const QHash< QString, QgsCoordinateReferenceSystem > &projCache();
1186  static const QHash< QString, QgsCoordinateReferenceSystem > &ogcCache();
1187  static const QHash< QString, QgsCoordinateReferenceSystem > &wktCache();
1188  static const QHash< long, QgsCoordinateReferenceSystem > &srsIdCache();
1189  static const QHash< long, QgsCoordinateReferenceSystem > &srIdCache();
1190 
1191  friend class TestQgsCoordinateReferenceSystem;
1193  friend bool CORE_EXPORT operator> ( const QgsCoordinateReferenceSystem &c1, const QgsCoordinateReferenceSystem &c2 );
1194  friend bool CORE_EXPORT operator< ( const QgsCoordinateReferenceSystem &c1, const QgsCoordinateReferenceSystem &c2 );
1195  friend bool CORE_EXPORT operator>= ( const QgsCoordinateReferenceSystem &c1, const QgsCoordinateReferenceSystem &c2 );
1196  friend bool CORE_EXPORT operator<= ( const QgsCoordinateReferenceSystem &c1, const QgsCoordinateReferenceSystem &c2 );
1197 
1198  bool createFromPostgisSrid( const long id );
1199 };
1200 
1202 
1203 #ifndef SIP_RUN
1205 inline std::ostream &operator << ( std::ostream &os, const QgsCoordinateReferenceSystem &r )
1206 {
1207  QString mySummary( QStringLiteral( "\n\tSpatial Reference System:" ) );
1208  mySummary += QLatin1String( "\n\t\tDescription : " );
1209  if ( !r.description().isNull() )
1210  {
1211  mySummary += r.description();
1212  }
1213  else
1214  {
1215  mySummary += QLatin1String( "Undefined" );
1216  }
1217  mySummary += QLatin1String( "\n\t\tProjection : " );
1218  if ( !r.projectionAcronym().isNull() )
1219  {
1220  mySummary += r.projectionAcronym();
1221  }
1222  else
1223  {
1224  mySummary += QLatin1String( "Undefined" );
1225  }
1226 
1227  mySummary += QLatin1String( "\n\t\tEllipsoid : " );
1228  if ( !r.ellipsoidAcronym().isNull() )
1229  {
1230  mySummary += r.ellipsoidAcronym();
1231  }
1232  else
1233  {
1234  mySummary += QLatin1String( "Undefined" );
1235  }
1236 
1237  mySummary += QLatin1String( "\n\t\tProjString : " );
1238  if ( !r.toProj().isNull() )
1239  {
1240  mySummary += r.toProj();
1241  }
1242  else
1243  {
1244  mySummary += QLatin1String( "Undefined" );
1245  }
1246  // Using streams we need to use local 8 Bit
1247  return os << mySummary.toLocal8Bit().data() << std::endl;
1248 }
1249 
1250 bool CORE_EXPORT operator> ( const QgsCoordinateReferenceSystem &c1, const QgsCoordinateReferenceSystem &c2 );
1251 bool CORE_EXPORT operator< ( const QgsCoordinateReferenceSystem &c1, const QgsCoordinateReferenceSystem &c2 );
1252 bool CORE_EXPORT operator>= ( const QgsCoordinateReferenceSystem &c1, const QgsCoordinateReferenceSystem &c2 );
1253 bool CORE_EXPORT operator<= ( const QgsCoordinateReferenceSystem &c1, const QgsCoordinateReferenceSystem &c2 );
1254 #endif
1255 
1256 #endif // QGSCOORDINATEREFERENCESYSTEM_H
The Qgis class provides global constants for use throughout the application.
Definition: qgis.h:72
CrsDefinitionFormat
CRS definition formats.
Definition: qgis.h:1706
A registry for known coordinate reference system (CRS) definitions, including any user-defined CRSes.
This class represents a coordinate reference system (CRS).
QString toProj() const
Returns a Proj string representation of this CRS.
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
QString projectionAcronym() const
Returns the projection acronym for the projection used by the CRS.
CrsType
Enumeration of types of IDs accepted in createFromId() method.
@ InternalCrsId
Internal ID used by QGIS in the local SQLite database.
@ PostgisCrsId
SRID used in PostGIS. DEPRECATED – DO NOT USE.
IdentifierType
Type of identifier string to create.
@ MediumString
A medium-length string, recommended for general purpose use.
@ FullString
Full definition – possibly a very lengthy string, e.g. with no truncation of custom WKT definitions.
@ ShortString
A heavily abbreviated string, for use when a compact representation is required.
WktVariant
WKT formatting variants, only used for builds based on Proj >= 6.
@ WKT1_GDAL
WKT1 as traditionally output by GDAL, deriving from OGC 01-009. A notable departure from WKT1_GDAL wi...
@ WKT2_2018_SIMPLIFIED
Alias for WKT2_2019_SIMPLIFIED.
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
@ WKT2_2015
Full WKT2 string, conforming to ISO 19162:2015(E) / OGC 12-063r5 with all possible nodes and new keyw...
@ WKT1_ESRI
WKT1 as traditionally output by ESRI software, deriving from OGC 99-049.
@ WKT2_2015_SIMPLIFIED
Same as WKT2_2015 with the following exceptions: UNIT keyword used. ID node only on top element....
Contains information about a datum ensemble.
Definition: qgsdatums.h:95
Custom exception class which is raised when an operation is not supported.
Definition: qgsexception.h:118
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
Used to create and store a proj context object, correctly freeing the context upon destruction.
Definition: qgsprojutils.h:231
Contains information about a PROJ operation.
contains various cartographic properties, such as scale factors, angular distortion and meridian conv...
A rectangle specified with double values.
Definition: qgsrectangle.h:42
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:68
Unique pointer for sqlite3 databases, which automatically closes the database when the pointer goes o...
#define str(x)
Definition: qgis.cpp:37
#define SIP_THROW(name)
Definition: qgis_sip.h:198
#define SIP_TYPEHINT(type)
Definition: qgis_sip.h:227
#define SIP_DEPRECATED
Definition: qgis_sip.h:106
#define SIP_SKIP
Definition: qgis_sip.h:126
#define SIP_PYARGREMOVE
Definition: qgis_sip.h:151
struct sqlite3 sqlite3
void * OGRSpatialReferenceH
bool CORE_EXPORT operator<(const QgsCoordinateReferenceSystem &c1, const QgsCoordinateReferenceSystem &c2)
bool CORE_EXPORT operator>(const QgsCoordinateReferenceSystem &c1, const QgsCoordinateReferenceSystem &c2)
bool CORE_EXPORT operator<=(const QgsCoordinateReferenceSystem &c1, const QgsCoordinateReferenceSystem &c2)
struct PJconsts PJ
std::ostream & operator<<(std::ostream &os, const QgsCoordinateReferenceSystem &r)
Output stream operator.
struct projCtx_t PJ_CONTEXT
bool CORE_EXPORT operator>=(const QgsCoordinateReferenceSystem &c1, const QgsCoordinateReferenceSystem &c2)
void(* CUSTOM_CRS_VALIDATION)(QgsCoordinateReferenceSystem &)
Q_DECLARE_METATYPE(QgsDatabaseQueryLogEntry)
const QgsCoordinateReferenceSystem & crs
bool hasAxisInverted