QGIS API Documentation  3.17.0-Master (c90b8c8084)
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 "qgsunittypes.h"
36 #include "qgsrectangle.h"
37 #include "qgssqliteutils.h"
38 
39 class QDomNode;
40 class QDomDocument;
41 class QgsCoordinateReferenceSystemPrivate;
42 
43 #if PROJ_VERSION_MAJOR>=6
44 #ifndef SIP_RUN
45 struct PJconsts;
46 typedef struct PJconsts PJ;
47 
48 #if PROJ_VERSION_MAJOR>=8
49 struct pj_ctx;
50 typedef struct pj_ctx PJ_CONTEXT;
51 #else
52 struct projCtx_t;
53 typedef struct projCtx_t PJ_CONTEXT;
54 #endif
55 #endif
56 #endif
57 
58 // forward declaration for sqlite3
59 typedef struct sqlite3 sqlite3 SIP_SKIP;
60 
61 #ifdef DEBUG
62 typedef struct OGRSpatialReferenceHS *OGRSpatialReferenceH SIP_SKIP;
63 #else
65 #endif
66 
69 
210 {
211  Q_GADGET
212 
213  Q_PROPERTY( QgsUnitTypes::DistanceUnit mapUnits READ mapUnits )
214  Q_PROPERTY( bool isGeographic READ isGeographic )
215 
216  public:
217 
219  enum CrsType
220  {
223  EpsgCrsId
224  };
225 
227  enum Format
228  {
229  FormatWkt = 0,
231  };
232 
235 
237 
238  // TODO QGIS 4: remove "POSTGIS" and "INTERNAL"
239 
255  explicit QgsCoordinateReferenceSystem( const QString &definition );
256 
257  // TODO QGIS 4: remove type and always use EPSG code
258 
270  Q_DECL_DEPRECATED explicit QgsCoordinateReferenceSystem( long id, CrsType type = PostgisCrsId ) SIP_DEPRECATED;
271 
274 
277 
279  operator QVariant() const
280  {
281  return QVariant::fromValue( *this );
282  }
283 
291  static QList< long > validSrsIds();
292 
293  // static creators
294 
302  static QgsCoordinateReferenceSystem fromOgcWmsCrs( const QString &ogcCrs );
303 
310  Q_INVOKABLE static QgsCoordinateReferenceSystem fromEpsgId( long epsg );
311 
318  Q_DECL_DEPRECATED static QgsCoordinateReferenceSystem fromProj4( const QString &proj4 ) SIP_DEPRECATED;
319 
327  static QgsCoordinateReferenceSystem fromProj( const QString &proj );
328 
336  static QgsCoordinateReferenceSystem fromWkt( const QString &wkt );
337 
346  static QgsCoordinateReferenceSystem fromSrsId( long srsId );
347 
348  // Misc helper functions -----------------------
349 
350  // TODO QGIS 4: remove type and always use EPSG code, rename to createFromEpsg
351 
357  Q_DECL_DEPRECATED bool createFromId( long id, CrsType type = PostgisCrsId ) SIP_DEPRECATED;
358 
359  // TODO QGIS 4: remove "QGIS" and "CUSTOM", only support "USER" (also returned by authid())
360 
371  bool createFromOgcWmsCrs( const QString &crs );
372 
373  // TODO QGIS 4: remove unless really necessary - let's use EPSG codes instead
374 
382  Q_DECL_DEPRECATED bool createFromSrid( long srid ) SIP_DEPRECATED;
383 
396  bool createFromWkt( const QString &wkt );
397 
410  bool createFromSrsId( long srsId );
411 
435  Q_DECL_DEPRECATED bool createFromProj4( const QString &projString ) SIP_DEPRECATED;
436 
464 #ifndef SIP_RUN
465  bool createFromProj( const QString &projString, bool identify = true );
466 #else
467  bool createFromProj( const QString &projString );
468 #endif
469 
485  bool createFromString( const QString &definition );
486 
487  // TODO QGIS 4: rename to createFromStringOGR so it is clear it's similar to createFromString, just different backend
488 
504  bool createFromUserInput( const QString &definition );
505 
516  Q_DECL_DEPRECATED static void setupESRIWktFix() SIP_DEPRECATED;
517 
519  bool isValid() const;
520 
532  void validate();
533 
534  // TODO QGIS 4: seems completely obsolete now (only compares proj4 - already done in createFromProj4)
535 
544  Q_DECL_DEPRECATED long findMatchingProj() SIP_DEPRECATED;
545 
551  bool operator==( const QgsCoordinateReferenceSystem &srs ) const;
552 
558  bool operator!=( const QgsCoordinateReferenceSystem &srs ) const;
559 
566  bool readXml( const QDomNode &node );
567 
574  bool writeXml( QDomNode &node, QDomDocument &doc ) const;
575 
576 
581  static void setCustomCrsValidation( CUSTOM_CRS_VALIDATION f ) SIP_SKIP;
582 
587  static CUSTOM_CRS_VALIDATION customCrsValidation() SIP_SKIP;
588 
589  // Accessors -----------------------------------
590 
595  long srsid() const;
596 
597  // TODO QGIS 4: remove unless really necessary - let's use EPSG codes instead
598 
603  long postgisSrid() const;
604 
617  QString authid() const;
618 
626  QString description() const;
627 
634  {
638  };
639 
653  QString userFriendlyIdentifier( IdentifierType type = MediumString ) const;
654 
661  QString projectionAcronym() const;
662 
669  QString ellipsoidAcronym() const;
670 
673  {
680  WKT2_2019 = WKT2_2018,
681  WKT2_2019_SIMPLIFIED = WKT2_2018_SIMPLIFIED,
682 
683  WKT_PREFERRED = WKT2_2019,
684  WKT_PREFERRED_SIMPLIFIED = WKT2_2019_SIMPLIFIED,
685  WKT_PREFERRED_GDAL = WKT2_2019,
686  };
687 
699  QString toWkt( WktVariant variant = WKT1_GDAL, bool multiline = false, int indentationWidth = 4 ) const;
700 
713  Q_DECL_DEPRECATED QString toProj4() const SIP_DEPRECATED;
714 
727  QString toProj() const;
728 
733  bool isGeographic() const;
734 
739  bool hasAxisInverted() const;
740 
744  QgsUnitTypes::DistanceUnit mapUnits() const;
745 
754  QgsRectangle bounds() const;
755 
756  // Mutators -----------------------------------
757 
761  void setValidationHint( const QString &html );
762 
766  QString validationHint();
767 
774  static int syncDatabase();
775 
787  long saveAsUserCrs( const QString &name, Format nativeFormat = FormatWkt );
788 
790  QString geographicCrsAuthId() const;
791 
792 #ifdef SIP_RUN
793  SIP_PYOBJECT __repr__();
794  % MethodCode
795  const QString str = sipCpp->isValid() ? QStringLiteral( "<QgsCoordinateReferenceSystem: %1>" ).arg( !sipCpp->authid().isEmpty() ? sipCpp->authid() : sipCpp->toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) )
796  : QStringLiteral( "<QgsCoordinateReferenceSystem: invalid>" );
797  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
798  % End
799 #endif
800 
801 #ifndef SIP_RUN
802 #if PROJ_VERSION_MAJOR>=6
803 
813  PJ *projObject() const;
814 #endif
815 #endif
816 
822  Q_DECL_DEPRECATED static QStringList recentProjections() SIP_DEPRECATED;
823 
828  static QList< QgsCoordinateReferenceSystem > recentCoordinateReferenceSystems();
829 
834  static void pushRecentCoordinateReferenceSystem( const QgsCoordinateReferenceSystem &crs );
835 
836 #ifndef SIP_RUN
837 
848  static void invalidateCache( bool disableCache = false );
849 #else
850 
858  static void invalidateCache( bool disableCache SIP_PYARGREMOVE = false );
859 #endif
860 
861  // Mutators -----------------------------------
862  // We don't want to expose these to the public api since they won't create
863  // a fully valid crs. Programmers should use the createFrom* methods rather
864  private:
865 
871  static QString projFromSrsId( int srsId );
872 
878  void setProjString( const QString &projString );
879 
883  bool setWktString( const QString &wkt, bool allowProjFallback = true );
884 
888  void debugPrint();
889 
891  typedef QMap<QString, QString> RecordMap;
892 
900  RecordMap getRecord( const QString &sql );
901 
906  static int openDatabase( const QString &path, sqlite3_database_unique_ptr &database, bool readonly = true );
907 
909  void setMapUnits();
910 
912  long getRecordCount();
913 
914 #if PROJ_VERSION_MAJOR>=6
915  bool loadFromAuthCode( const QString &auth, const QString &code );
916 
920  static QList< long > userSrsIds();
921 
929  long matchToUserCrs() const;
930 #endif
931 
936  bool loadFromDatabase( const QString &db, const QString &expression, const QString &value );
937 
938  bool createFromWktInternal( const QString &wkt, const QString &description );
939 
940 #if PROJ_VERSION_MAJOR<6 // not used for proj >= 6.0
941  static bool loadIds( QHash<int, QString> &wkts );
942  static bool loadWkts( QHash<int, QString> &wkts, const char *filename );
943 
945  static bool syncDatumTransform( const QString &dbPath );
946 #endif
947 
948  QExplicitlySharedDataPointer<QgsCoordinateReferenceSystemPrivate> d;
949 
950  QString mValidationHint;
951 
952 #if PROJ_VERSION_MAJOR>=6
953  friend class QgsProjContext;
954 
955  // Only meant to be called by QgsProjContext::~QgsProjContext()
956  static void removeFromCacheObjectsBelongingToCurrentThread( PJ_CONTEXT *pj_context );
957 #endif
958 
960  static CUSTOM_CRS_VALIDATION sCustomSrsValidation;
961 
962  // cache
963 
964  static bool sDisableSrIdCache;
965  static bool sDisableOgcCache;
966  static bool sDisableProjCache;
967  static bool sDisableWktCache;
968  static bool sDisableSrsIdCache;
969  static bool sDisableStringCache;
970 
971  // for tests
972  static const QHash< QString, QgsCoordinateReferenceSystem > &stringCache();
973  static const QHash< QString, QgsCoordinateReferenceSystem > &projCache();
974  static const QHash< QString, QgsCoordinateReferenceSystem > &ogcCache();
975  static const QHash< QString, QgsCoordinateReferenceSystem > &wktCache();
976  static const QHash< long, QgsCoordinateReferenceSystem > &srsIdCache();
977  static const QHash< long, QgsCoordinateReferenceSystem > &srIdCache();
978 
979  friend class TestQgsCoordinateReferenceSystem;
980  friend class QgsPostgresProvider;
981 
982  bool createFromPostgisSrid( const long id );
983 };
984 
986 
987 #ifndef SIP_RUN
989 inline std::ostream &operator << ( std::ostream &os, const QgsCoordinateReferenceSystem &r )
990 {
991  QString mySummary( QStringLiteral( "\n\tSpatial Reference System:" ) );
992  mySummary += QLatin1String( "\n\t\tDescription : " );
993  if ( !r.description().isNull() )
994  {
995  mySummary += r.description();
996  }
997  else
998  {
999  mySummary += QLatin1String( "Undefined" );
1000  }
1001  mySummary += QLatin1String( "\n\t\tProjection : " );
1002  if ( !r.projectionAcronym().isNull() )
1003  {
1004  mySummary += r.projectionAcronym();
1005  }
1006  else
1007  {
1008  mySummary += QLatin1String( "Undefined" );
1009  }
1010 
1011  mySummary += QLatin1String( "\n\t\tEllipsoid : " );
1012  if ( !r.ellipsoidAcronym().isNull() )
1013  {
1014  mySummary += r.ellipsoidAcronym();
1015  }
1016  else
1017  {
1018  mySummary += QLatin1String( "Undefined" );
1019  }
1020 
1021  mySummary += QLatin1String( "\n\t\tProjString : " );
1022  if ( !r.toProj().isNull() )
1023  {
1024  mySummary += r.toProj();
1025  }
1026  else
1027  {
1028  mySummary += QLatin1String( "Undefined" );
1029  }
1030  // Using streams we need to use local 8 Bit
1031  return os << mySummary.toLocal8Bit().data() << std::endl;
1032 }
1033 #endif
1034 
1035 #endif // QGSCOORDINATEREFERENCESYSTEM_H
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QString toProj() const
Returns a Proj string representation of this CRS.
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
bool operator!=(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
Helper functions for various unit types.
Definition: qgsunittypes.h:38
Full WKT2 string, conforming to ISO 19162:2015(E) / OGC 12-063r5 with all possible nodes and new keyw...
SRID used in PostGIS. DEPRECATED – DO NOT USE.
const QgsCoordinateReferenceSystem & crs
Full definition – possibly a very lengthy string, e.g. with no truncation of custom WKT definitions...
Internal ID used by QGIS in the local SQLite database.
Same as WKT2_2015 with the following exceptions: UNIT keyword used. ID node only on top element...
Used to create and store a proj context object, correctly freeing the context upon destruction...
Definition: qgsprojutils.h:164
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
Format
Projection definition formats.
WKT1 as traditionally output by GDAL, deriving from OGC 01-009. A notable departure from WKT1_GDAL wi...
#define SIP_SKIP
Definition: qgis_sip.h:126
QString description() const
Returns the descriptive name of the CRS, e.g., "WGS 84" or "GDA 94 / Vicgrid94".
Q_DECLARE_METATYPE(QgsMeshTimeSettings)
IdentifierType
Type of identifier string to create.
std::ostream & operator<<(std::ostream &os, const QgsCoordinateReferenceSystem &r)
Output stream operator.
#define SIP_DEPRECATED
Definition: qgis_sip.h:106
CrsType
Enumeration of types of IDs accepted in createFromId() method.
struct sqlite3 sqlite3
A medium-length string, recommended for general purpose use.
QString projectionAcronym() const
Returns the projection acronym for the projection used by the CRS.
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019...
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:67
Unique pointer for sqlite3 databases, which automatically closes the database when the pointer goes o...
#define SIP_PYARGREMOVE
Definition: qgis_sip.h:146
void PJ_CONTEXT
Definition: qgsprojutils.h:154
This class represents a coordinate reference system (CRS).
A heavily abbreviated string, for use when a compact representation is required.
WktVariant
WKT formatting variants, only used for builds based on Proj >= 6.
void(* CUSTOM_CRS_VALIDATION)(QgsCoordinateReferenceSystem &)
void * OGRSpatialReferenceH
WKT1 as traditionally output by ESRI software, deriving from OGC 99-049.