QGIS API Documentation  3.9.0-Master (224899f119)
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 : sherman@mrcc.com
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 #endif
48 #endif
49 
50 // forward declaration for sqlite3
51 typedef struct sqlite3 sqlite3 SIP_SKIP;
52 
53 #ifdef DEBUG
54 typedef struct OGRSpatialReferenceHS *OGRSpatialReferenceH SIP_SKIP;
55 #else
57 #endif
58 
61 
199 {
200  Q_GADGET
201 
202  Q_PROPERTY( QgsUnitTypes::DistanceUnit mapUnits READ mapUnits )
203  Q_PROPERTY( bool isGeographic READ isGeographic )
204 
205  public:
206 
208  enum CrsType
209  {
212  EpsgCrsId
213  };
214 
217 
219 
220  // TODO QGIS 4: remove "POSTGIS" and "INTERNAL", allow PROJ4 without the prefix
221 
236  explicit QgsCoordinateReferenceSystem( const QString &definition );
237 
238  // TODO QGIS 4: remove type and always use EPSG code
239 
247  explicit QgsCoordinateReferenceSystem( long id, CrsType type = PostgisCrsId );
248 
251 
254 
256  operator QVariant() const
257  {
258  return QVariant::fromValue( *this );
259  }
260 
268  static QList< long > validSrsIds();
269 
270  // static creators
271 
279  static QgsCoordinateReferenceSystem fromOgcWmsCrs( const QString &ogcCrs );
280 
287  Q_INVOKABLE static QgsCoordinateReferenceSystem fromEpsgId( long epsg );
288 
296  static QgsCoordinateReferenceSystem fromProj4( const QString &proj4 );
297 
305  static QgsCoordinateReferenceSystem fromWkt( const QString &wkt );
306 
315  static QgsCoordinateReferenceSystem fromSrsId( long srsId );
316 
317  // Misc helper functions -----------------------
318 
319  // TODO QGIS 4: remove type and always use EPSG code, rename to createFromEpsg
320 
327  bool createFromId( long id, CrsType type = PostgisCrsId );
328 
329  // TODO QGIS 4: remove "QGIS" and "CUSTOM", only support "USER" (also returned by authid())
330 
341  bool createFromOgcWmsCrs( const QString &crs );
342 
343  // TODO QGIS 4: remove unless really necessary - let's use EPSG codes instead
344 
350  bool createFromSrid( long srid );
351 
365  bool createFromWkt( const QString &wkt );
366 
377  bool createFromSrsId( long srsId );
378 
402  bool createFromProj4( const QString &projString );
403 
418  bool createFromString( const QString &definition );
419  // TODO QGIS3: rename to createFromStringOGR so it is clear it's similar to createFromString, just different backend
435  bool createFromUserInput( const QString &definition );
436 
446  static void setupESRIWktFix();
447 
449  bool isValid() const;
450 
462  void validate();
463 
464  // TODO QGIS 4: seems completely obsolete now (only compares proj4 - already done in createFromProj4)
465 
473  long findMatchingProj();
474 
480  bool operator==( const QgsCoordinateReferenceSystem &srs ) const;
481 
487  bool operator!=( const QgsCoordinateReferenceSystem &srs ) const;
488 
495  bool readXml( const QDomNode &node );
496 
503  bool writeXml( QDomNode &node, QDomDocument &doc ) const;
504 
505 
510  static void setCustomCrsValidation( CUSTOM_CRS_VALIDATION f ) SIP_SKIP;
511 
516  static CUSTOM_CRS_VALIDATION customCrsValidation() SIP_SKIP;
517 
518  // Accessors -----------------------------------
519 
524  long srsid() const;
525 
526  // TODO QGIS 4: remove unless really necessary - let's use EPSG codes instead
527 
532  long postgisSrid() const;
533 
546  QString authid() const;
547 
556  QString description() const;
557 
564  QString projectionAcronym() const;
565 
572  QString ellipsoidAcronym() const;
573 
576  {
583  };
584 
596  QString toWkt( WktVariant variant = WKT1_GDAL, bool multiline = false, int indentationWidth = 4 ) const;
597 
608  QString toProj4() const;
609 
614  bool isGeographic() const;
615 
620  bool hasAxisInverted() const;
621 
625  QgsUnitTypes::DistanceUnit mapUnits() const;
626 
635  QgsRectangle bounds() const;
636 
637  // Mutators -----------------------------------
638 
642  void setValidationHint( const QString &html );
643 
647  QString validationHint();
648 
655  static int syncDatabase();
656 
657 
663  long saveAsUserCrs( const QString &name );
664 
666  QString geographicCrsAuthId() const;
667 
668 #ifdef SIP_RUN
669  SIP_PYOBJECT __repr__();
670  % MethodCode
671  QString str = QStringLiteral( "<QgsCoordinateReferenceSystem: %1>" ).arg( sipCpp->authid() );
672  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
673  % End
674 #endif
675 
676 #ifndef SIP_RUN
677 #if PROJ_VERSION_MAJOR>=6
678 
688  PJ *projObject() const;
689 #endif
690 #endif
691 
697  static QStringList recentProjections();
698 
699 #ifndef SIP_RUN
700 
711  static void invalidateCache( bool disableCache = false );
712 #else
713 
721  static void invalidateCache( bool disableCache SIP_PYARGREMOVE = false );
722 #endif
723 
724  // Mutators -----------------------------------
725  // We don't want to expose these to the public api since they won't create
726  // a fully valid crs. Programmers should use the createFrom* methods rather
727  private:
728 
734  static QString proj4FromSrsId( int srsId );
735 
740  void setInternalId( long srsId );
741 
746  void setSrid( long srid );
747 
752  void setDescription( const QString &description );
753 
765  void setProj4String( const QString &proj4String );
766 
771  void setGeographicFlag( bool geoFlag );
772 
777  void setEpsg( long epsg );
778 
783  void setAuthId( const QString &theID );
784 
789  void setProjectionAcronym( const QString &projectionAcronym );
790 
795  void setEllipsoidAcronym( const QString &ellipsoidAcronym );
796 
800  void debugPrint();
801 
803  typedef QMap<QString, QString> RecordMap;
804 
812  RecordMap getRecord( const QString &sql );
813 
818  static int openDatabase( const QString &path, sqlite3_database_unique_ptr &database, bool readonly = true );
819 
821  void setMapUnits();
822 
824  long getRecordCount();
825 
826 #if PROJ_VERSION_MAJOR>=6
827  bool loadFromAuthCode( const QString &auth, const QString &code );
828 #endif
829 
834  bool loadFromDatabase( const QString &db, const QString &expression, const QString &value );
835 
836 #if PROJ_VERSION_MAJOR<6 // not used for proj >= 6.0
837  static bool loadIds( QHash<int, QString> &wkts );
838  static bool loadWkts( QHash<int, QString> &wkts, const char *filename );
839 
841  static bool syncDatumTransform( const QString &dbPath );
842 #endif
843 
844  QExplicitlySharedDataPointer<QgsCoordinateReferenceSystemPrivate> d;
845 
847  static CUSTOM_CRS_VALIDATION mCustomSrsValidation;
848 
849 
850  // cache
851 
852  static QReadWriteLock sSrIdCacheLock;
853  static QHash< long, QgsCoordinateReferenceSystem > sSrIdCache;
854  static bool sDisableSrIdCache;
855 
856  static QReadWriteLock sOgcLock;
857  static QHash< QString, QgsCoordinateReferenceSystem > sOgcCache;
858  static bool sDisableOgcCache;
859 
860  static QReadWriteLock sProj4CacheLock;
861  static QHash< QString, QgsCoordinateReferenceSystem > sProj4Cache;
862  static bool sDisableProj4Cache;
863 
864  static QReadWriteLock sCRSWktLock;
865  static QHash< QString, QgsCoordinateReferenceSystem > sWktCache;
866  static bool sDisableWktCache;
867 
868  static QReadWriteLock sCRSSrsIdLock;
869  static QHash< long, QgsCoordinateReferenceSystem > sSrsIdCache;
870  static bool sDisableSrsIdCache;
871 
872  static QReadWriteLock sCrsStringLock;
873  static QHash< QString, QgsCoordinateReferenceSystem > sStringCache;
874  static bool sDisableStringCache;
875 
876  friend class TestQgsCoordinateReferenceSystem;
877 };
878 
880 
881 #ifndef SIP_RUN
883 inline std::ostream &operator << ( std::ostream &os, const QgsCoordinateReferenceSystem &r )
884 {
885  QString mySummary( QStringLiteral( "\n\tSpatial Reference System:" ) );
886  mySummary += QLatin1String( "\n\t\tDescription : " );
887  if ( !r.description().isNull() )
888  {
889  mySummary += r.description();
890  }
891  else
892  {
893  mySummary += QLatin1String( "Undefined" );
894  }
895  mySummary += QLatin1String( "\n\t\tProjection : " );
896  if ( !r.projectionAcronym().isNull() )
897  {
898  mySummary += r.projectionAcronym();
899  }
900  else
901  {
902  mySummary += QLatin1String( "Undefined" );
903  }
904 
905  mySummary += QLatin1String( "\n\t\tEllipsoid : " );
906  if ( !r.ellipsoidAcronym().isNull() )
907  {
908  mySummary += r.ellipsoidAcronym();
909  }
910  else
911  {
912  mySummary += QLatin1String( "Undefined" );
913  }
914 
915  mySummary += QLatin1String( "\n\t\tProj4String : " );
916  if ( !r.toProj4().isNull() )
917  {
918  mySummary += r.toProj4();
919  }
920  else
921  {
922  mySummary += QLatin1String( "Undefined" );
923  }
924  // Using streams we need to use local 8 Bit
925  return os << mySummary.toLocal8Bit().data() << std::endl;
926 }
927 #endif
928 
929 #endif // QGSCOORDINATEREFERENCESYSTEM_H
A rectangle specified with double values.
Definition: qgsrectangle.h:41
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
bool operator!=(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
QString toProj4() const
Returns a Proj4 string representation of this CRS.
Full WKT2 string, conforming to ISO 19162:2015(E) / OGC 12-063r5 with all possible nodes and new keyw...
const QgsCoordinateReferenceSystem & crs
WKT2_2018 with the simplification rule of WKT2_SIMPLIFIED.
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...
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
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)
std::ostream & operator<<(std::ostream &os, const QgsCoordinateReferenceSystem &r)
Output stream operator.
CrsType
Enumeration of types of IDs accepted in createFromId() method.
struct sqlite3 sqlite3
Full WKT2 string, conforming to ISO 19162:2018 / OGC 18-010, with all possible nodes and new keyword ...
QString projectionAcronym() const
Returns the projection acronym for the projection used by the CRS.
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:54
Unique pointer for sqlite3 databases, which automatically closes the database when the pointer goes o...
#define SIP_PYARGREMOVE
Definition: qgis_sip.h:146
This class represents a coordinate reference system (CRS).
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.