QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgscoordinatereferencesystemregistry.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscoordinatereferencesystemregistry.cpp
3  -------------------
4  begin : January 2021
5  copyright : (C) 2021 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
20 #include "qgscoordinatetransform.h"
21 #include "qgsapplication.h"
22 #include "qgslogger.h"
23 #include "qgsmessagelog.h"
24 #include "qgssqliteutils.h"
25 #include "qgscelestialbody.h"
26 #include "qgsprojutils.h"
27 #include "qgsruntimeprofiler.h"
28 #include "qgsexception.h"
29 #include "qgsprojoperation.h"
30 
31 #include <sqlite3.h>
32 #include <mutex>
33 #include <proj.h>
34 
36  : QObject( parent )
37 {
38 
39 }
40 
42 
43 QList<QgsCoordinateReferenceSystemRegistry::UserCrsDetails> QgsCoordinateReferenceSystemRegistry::userCrsList() const
44 {
45  QList<QgsCoordinateReferenceSystemRegistry::UserCrsDetails> res;
46 
47  //Setup connection to the existing custom CRS database:
49  //check the db is available
50  int result = database.open_v2( QgsApplication::qgisUserDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
51  if ( result != SQLITE_OK )
52  {
53  QgsDebugMsg( QStringLiteral( "Can't open database: %1" ).arg( database.errorMessage() ) );
54  return res;
55  }
56 
57  const QString sql = QStringLiteral( "select srs_id,description,parameters, wkt from tbl_srs" );
58  QgsDebugMsgLevel( QStringLiteral( "Query to populate existing list:%1" ).arg( sql ), 4 );
59  sqlite3_statement_unique_ptr preparedStatement = database.prepare( sql, result );
60  if ( result == SQLITE_OK )
61  {
63  while ( preparedStatement.step() == SQLITE_ROW )
64  {
65  UserCrsDetails details;
66  details.id = preparedStatement.columnAsText( 0 ).toLong();
67  details.name = preparedStatement.columnAsText( 1 );
68  details.proj = preparedStatement.columnAsText( 2 );
69  details.wkt = preparedStatement.columnAsText( 3 );
70 
71  if ( !details.wkt.isEmpty() )
72  details.crs.createFromWkt( details.wkt );
73  else
74  details.crs.createFromProj( details.proj );
75 
76  res << details;
77  }
78  }
79  return res;
80 }
81 
83 {
84  if ( !crs.isValid() )
85  {
86  QgsDebugMsgLevel( QStringLiteral( "Can't save an invalid CRS!" ), 4 );
87  return -1;
88  }
89 
90  QString mySql;
91 
92  QString proj4String = crs.d->mProj4;
93  if ( proj4String.isEmpty() )
94  {
95  proj4String = crs.toProj();
96  }
97  const QString wktString = crs.toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED );
98 
99  // ellipsoid acroynym column is incorrectly marked as not null in many crs database instances,
100  // hack around this by using an empty string instead
101  const QString quotedEllipsoidString = crs.ellipsoidAcronym().isNull() ? QStringLiteral( "''" ) : QgsSqliteUtils::quotedString( crs.ellipsoidAcronym() );
102 
103  //if this is the first record we need to ensure that its srs_id is 10000. For
104  //any rec after that sqlite3 will take care of the autonumbering
105  //this was done to support sqlite 3.0 as it does not yet support
106  //the autoinc related system tables.
107  if ( QgsCoordinateReferenceSystem::getRecordCount() == 0 )
108  {
109  mySql = "insert into tbl_srs (srs_id,description,projection_acronym,ellipsoid_acronym,parameters,is_geo,wkt) values ("
110  + QString::number( USER_CRS_START_ID )
111  + ',' + QgsSqliteUtils::quotedString( name )
112  + ',' + ( !crs.d->mProjectionAcronym.isEmpty() ? QgsSqliteUtils::quotedString( crs.d->mProjectionAcronym ) : QStringLiteral( "''" ) )
113  + ',' + quotedEllipsoidString
114  + ',' + ( !proj4String.isEmpty() ? QgsSqliteUtils::quotedString( proj4String ) : QStringLiteral( "''" ) )
115  + ",0," // <-- is_geo shamelessly hard coded for now
116  + ( nativeFormat == Qgis::CrsDefinitionFormat::Wkt ? QgsSqliteUtils::quotedString( wktString ) : QStringLiteral( "''" ) )
117  + ')';
118  }
119  else
120  {
121  mySql = "insert into tbl_srs (description,projection_acronym,ellipsoid_acronym,parameters,is_geo,wkt) values ("
123  + ',' + ( !crs.d->mProjectionAcronym.isEmpty() ? QgsSqliteUtils::quotedString( crs.d->mProjectionAcronym ) : QStringLiteral( "''" ) )
124  + ',' + quotedEllipsoidString
125  + ',' + ( !proj4String.isEmpty() ? QgsSqliteUtils::quotedString( proj4String ) : QStringLiteral( "''" ) )
126  + ",0," // <-- is_geo shamelessly hard coded for now
127  + ( nativeFormat == Qgis::CrsDefinitionFormat::Wkt ? QgsSqliteUtils::quotedString( wktString ) : QStringLiteral( "''" ) )
128  + ')';
129  }
132  //check the db is available
133  int myResult = database.open( QgsApplication::qgisUserDatabaseFilePath() );
134  if ( myResult != SQLITE_OK )
135  {
136  QgsDebugMsg( QStringLiteral( "Can't open or create database %1: %2" )
138  database.errorMessage() ) );
139  return false;
140  }
141  statement = database.prepare( mySql, myResult );
142 
143  qint64 returnId = -1;
144  if ( myResult == SQLITE_OK && statement.step() == SQLITE_DONE )
145  {
146  QgsMessageLog::logMessage( QObject::tr( "Saved user CRS [%1]" ).arg( crs.toProj() ), QObject::tr( "CRS" ) );
147 
148  returnId = sqlite3_last_insert_rowid( database.get() );
149  crs.d->mSrsId = returnId;
150  crs.d->mAuthId = QStringLiteral( "USER:%1" ).arg( returnId );
151  crs.d->mDescription = name;
152  }
153 
154  if ( returnId != -1 )
155  {
156  // If we have a projection acronym not in the user db previously, add it.
157  // This is a must, or else we can't select it from the vw_srs table.
158  // Actually, add it always and let the SQL PRIMARY KEY remove duplicates.
159  insertProjection( crs.projectionAcronym() );
160  }
161 
164 
165  if ( returnId != -1 )
166  {
167  emit userCrsAdded( crs.d->mAuthId );
168  emit crsDefinitionsChanged();
169  }
170 
171  return returnId;
172 }
173 
175 {
176  if ( !crs.isValid() )
177  {
178  QgsDebugMsgLevel( QStringLiteral( "Can't save an invalid CRS!" ), 4 );
179  return false;
180  }
181 
182  const QString sql = "update tbl_srs set description="
184  + ",projection_acronym=" + ( !crs.projectionAcronym().isEmpty() ? QgsSqliteUtils::quotedString( crs.projectionAcronym() ) : QStringLiteral( "''" ) )
185  + ",ellipsoid_acronym=" + ( !crs.ellipsoidAcronym().isEmpty() ? QgsSqliteUtils::quotedString( crs.ellipsoidAcronym() ) : QStringLiteral( "''" ) )
186  + ",parameters=" + ( !crs.toProj().isEmpty() ? QgsSqliteUtils::quotedString( crs.toProj() ) : QStringLiteral( "''" ) )
187  + ",is_geo=0" // <--shamelessly hard coded for now
188  + ",wkt=" + ( nativeFormat == Qgis::CrsDefinitionFormat::Wkt ? QgsSqliteUtils::quotedString( crs.toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED, false ) ) : QStringLiteral( "''" ) )
189  + " where srs_id=" + QgsSqliteUtils::quotedString( QString::number( id ) )
190  ;
191 
193  //check the db is available
194  const int myResult = database.open( QgsApplication::qgisUserDatabaseFilePath() );
195  if ( myResult != SQLITE_OK )
196  {
197  QgsDebugMsg( QStringLiteral( "Can't open or create database %1: %2" )
199  database.errorMessage() ) );
200  return false;
201  }
202 
203  bool res = true;
204  QString errorMessage;
205  if ( database.exec( sql, errorMessage ) != SQLITE_OK )
206  {
207  QgsMessageLog::logMessage( QObject::tr( "Error saving user CRS [%1]: %2" ).arg( crs.toProj(), errorMessage ), QObject::tr( "CRS" ) );
208  res = false;
209  }
210  else
211  {
212  const int changed = sqlite3_changes( database.get() );
213  if ( changed )
214  {
215  QgsMessageLog::logMessage( QObject::tr( "Saved user CRS [%1]" ).arg( crs.toProj() ), QObject::tr( "CRS" ) );
216  }
217  else
218  {
219  QgsMessageLog::logMessage( QObject::tr( "Error saving user CRS [%1]: No matching ID found in database" ).arg( crs.toProj() ), QObject::tr( "CRS" ) );
220  res = false;
221  }
222  }
223 
224  if ( res )
225  {
226  // If we have a projection acronym not in the user db previously, add it.
227  // This is a must, or else we can't select it from the vw_srs table.
228  // Actually, add it always and let the SQL PRIMARY KEY remove duplicates.
229  insertProjection( crs.projectionAcronym() );
230  }
231 
234 
235  if ( res )
236  {
237  emit userCrsChanged( crs.d->mAuthId );
238  emit crsDefinitionsChanged();
239  }
240 
241  return res;
242 }
243 
245 {
247 
248  const QString sql = "delete from tbl_srs where srs_id=" + QgsSqliteUtils::quotedString( QString::number( id ) );
249  QgsDebugMsgLevel( sql, 4 );
250  //check the db is available
251  int result = database.open( QgsApplication::qgisUserDatabaseFilePath() );
252  if ( result != SQLITE_OK )
253  {
254  QgsDebugMsg( QStringLiteral( "Can't open database: %1 \n please notify QGIS developers of this error \n %2 (file name) " ).arg( database.errorMessage(),
256  return false;
257  }
258 
259  bool res = true;
260  {
261  sqlite3_statement_unique_ptr preparedStatement = database.prepare( sql, result );
262  if ( result != SQLITE_OK || preparedStatement.step() != SQLITE_DONE )
263  {
264  QgsDebugMsg( QStringLiteral( "failed to remove custom CRS from database: %1 [%2]" ).arg( sql, database.errorMessage() ) );
265  res = false;
266  }
267  else
268  {
269  const int changed = sqlite3_changes( database.get() );
270  if ( changed )
271  {
272  QgsMessageLog::logMessage( QObject::tr( "Removed user CRS [%1]" ).arg( id ), QObject::tr( "CRS" ) );
273  }
274  else
275  {
276  QgsMessageLog::logMessage( QObject::tr( "Error removing user CRS [%1]: No matching ID found in database" ).arg( id ), QObject::tr( "CRS" ) );
277  res = false;
278  }
279  }
280  }
281 
284 
285  if ( res )
286  {
287  emit userCrsRemoved( id );
288  emit crsDefinitionsChanged();
289  }
290 
291  return res;
292 }
293 
294 
295 bool QgsCoordinateReferenceSystemRegistry::insertProjection( const QString &projectionAcronym )
296 {
298  sqlite3_database_unique_ptr srsDatabase;
299  QString sql;
300  //check the db is available
301  int result = database.open( QgsApplication::qgisUserDatabaseFilePath() );
302  if ( result != SQLITE_OK )
303  {
304  QgsDebugMsg( QStringLiteral( "Can't open database: %1 \n please notify QGIS developers of this error \n %2 (file name) " ).arg( database.errorMessage(),
306  return false;
307  }
308  int srsResult = srsDatabase.open( QgsApplication::srsDatabaseFilePath() );
309  if ( result != SQLITE_OK )
310  {
311  QgsDebugMsg( QStringLiteral( "Can't open database %1 [%2]" ).arg( QgsApplication::srsDatabaseFilePath(),
312  srsDatabase.errorMessage() ) );
313  return false;
314  }
315 
316  // Set up the query to retrieve the projection information needed to populate the PROJECTION list
317  const QString srsSql = "select acronym,name,notes,parameters from tbl_projection where acronym=" + QgsSqliteUtils::quotedString( projectionAcronym );
318 
319  sqlite3_statement_unique_ptr srsPreparedStatement = srsDatabase.prepare( srsSql, srsResult );
320  if ( srsResult == SQLITE_OK )
321  {
322  if ( srsPreparedStatement.step() == SQLITE_ROW )
323  {
324  QgsDebugMsgLevel( QStringLiteral( "Trying to insert projection" ), 4 );
325  // We have the result from system srs.db. Now insert into user db.
326  sql = "insert into tbl_projection(acronym,name,notes,parameters) values ("
327  + QgsSqliteUtils::quotedString( srsPreparedStatement.columnAsText( 0 ) )
328  + ',' + QgsSqliteUtils::quotedString( srsPreparedStatement.columnAsText( 1 ) )
329  + ',' + QgsSqliteUtils::quotedString( srsPreparedStatement.columnAsText( 2 ) )
330  + ',' + QgsSqliteUtils::quotedString( srsPreparedStatement.columnAsText( 3 ) )
331  + ')';
332  sqlite3_statement_unique_ptr preparedStatement = database.prepare( sql, result );
333  if ( result != SQLITE_OK || preparedStatement.step() != SQLITE_DONE )
334  {
335  QgsDebugMsg( QStringLiteral( "Could not insert projection into database: %1 [%2]" ).arg( sql, database.errorMessage() ) );
336  return false;
337  }
338  }
339  }
340  else
341  {
342  QgsDebugMsg( QStringLiteral( "prepare failed: %1 [%2]" ).arg( srsSql, srsDatabase.errorMessage() ) );
343  return false;
344  }
345 
346  return true;
347 }
348 
349 QMap<QString, QgsProjOperation> QgsCoordinateReferenceSystemRegistry::projOperations() const
350 {
351  static std::once_flag initialized;
352  std::call_once( initialized, [ = ]
353  {
354  const QgsScopedRuntimeProfile profile( QObject::tr( "Initialize PROJ operations" ) );
355 
356  const PJ_OPERATIONS *operation = proj_list_operations();
357  while ( operation && operation->id )
358  {
359  QgsProjOperation value;
360  value.mValid = true;
361  value.mId = QString( operation->id );
362 
363  const QString description( *operation->descr );
364  const QStringList descriptionParts = description.split( QStringLiteral( "\n\t" ) );
365  value.mDescription = descriptionParts.value( 0 );
366  value.mDetails = descriptionParts.mid( 1 ).join( '\n' );
367 
368  mProjOperations.insert( value.id(), value );
369 
370  operation++;
371  }
372  } );
373 
374  return mProjOperations;
375 }
376 
378 {
379 #if PROJ_VERSION_MAJOR>8 || (PROJ_VERSION_MAJOR==8 && PROJ_VERSION_MINOR>=1)
380 
381  static std::once_flag initialized;
382  std::call_once( initialized, [ = ]
383  {
384  QgsScopedRuntimeProfile profile( QObject::tr( "Initialize celestial bodies" ) );
385 
386  PJ_CONTEXT *context = QgsProjContext::get();
387 
388  int resultCount = 0;
389  PROJ_CELESTIAL_BODY_INFO **list = proj_get_celestial_body_list_from_database( context, nullptr, &resultCount );
390  mCelestialBodies.reserve( resultCount );
391  for ( int i = 0; i < resultCount; i++ )
392  {
393  const PROJ_CELESTIAL_BODY_INFO *info = list[ i ];
394  if ( !info )
395  break;
396 
397  QgsCelestialBody body;
398  body.mValid = true;
399  body.mAuthority = QString( info->auth_name );
400  body.mName = QString( info->name );
401 
402  mCelestialBodies << body;
403  }
404  proj_celestial_body_list_destroy( list );
405  } );
406 
407  return mCelestialBodies;
408 #else
409  throw QgsNotSupportedException( QStringLiteral( "Retrieving celestial bodies requires a QGIS build based on PROJ 8.1 or later" ) );
410 #endif
411 }
QgsProjContext::get
static PJ_CONTEXT * get()
Returns a thread local instance of a proj context, safe for use in the current thread.
Definition: qgsprojutils.cpp:48
QgsCoordinateReferenceSystem::createFromWkt
bool createFromWkt(const QString &wkt)
Sets this CRS using a WKT definition.
Definition: qgscoordinatereferencesystem.cpp:899
sqlite3_database_unique_ptr::open
int open(const QString &path)
Opens the database at the specified file path.
Definition: qgssqliteutils.cpp:78
qgsruntimeprofiler.h
Qgis::CrsDefinitionFormat
CrsDefinitionFormat
CRS definition formats.
Definition: qgis.h:1687
QgsCoordinateReferenceSystemRegistry::UserCrsDetails::wkt
QString wkt
WKT definition of CRS.
Definition: qgscoordinatereferencesystemregistry.h:73
USER_CRS_START_ID
const int USER_CRS_START_ID
Magick number that determines whether a projection crsid is a system (srs.db) or user (~/....
Definition: qgis.h:2768
QgsCoordinateReferenceSystem::projectionAcronym
QString projectionAcronym() const
Returns the projection acronym for the projection used by the CRS.
Definition: qgscoordinatereferencesystem.cpp:1239
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
sqlite3_database_unique_ptr::prepare
sqlite3_statement_unique_ptr prepare(const QString &sql, int &resultCode) const
Prepares a sql statement, returning the result.
Definition: qgssqliteutils.cpp:99
QgsCoordinateReferenceSystem::WKT_PREFERRED
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
Definition: qgscoordinatereferencesystem.h:680
crs
const QgsCoordinateReferenceSystem & crs
Definition: qgswfsgetfeature.cpp:105
QgsCoordinateReferenceSystemRegistry::removeUserCrs
bool removeUserCrs(long id)
Removes the existing user CRS with matching id.
Definition: qgscoordinatereferencesystemregistry.cpp:244
PJ_CONTEXT
struct projCtx_t PJ_CONTEXT
Definition: qgscoordinatereferencesystem.h:56
qgsprojoperation.h
QgsSqliteUtils::quotedString
static QString quotedString(const QString &value)
Returns a quoted string value, surround by ' characters and with special characters correctly escaped...
Definition: qgssqliteutils.cpp:249
QgsCoordinateReferenceSystemRegistry::projOperations
QMap< QString, QgsProjOperation > projOperations() const
Returns a map of all valid PROJ operations.
Definition: qgscoordinatereferencesystemregistry.cpp:349
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsCoordinateReferenceSystemRegistry::updateUserCrs
bool updateUserCrs(long id, const QgsCoordinateReferenceSystem &crs, const QString &name, Qgis::CrsDefinitionFormat nativeFormat=Qgis::CrsDefinitionFormat::Wkt)
Updates the definition of the existing user CRS with matching id.
Definition: qgscoordinatereferencesystemregistry.cpp:174
QgsCelestialBody
Contains information about a celestial body.
Definition: qgscelestialbody.h:31
sqlite3_database_unique_ptr::errorMessage
QString errorMessage() const
Returns the most recent error message encountered by the database.
Definition: qgssqliteutils.cpp:94
QgsProjOperation
Contains information about a PROJ operation.
Definition: qgsprojoperation.h:30
QgsCoordinateTransform::invalidateCache
static void invalidateCache(bool disableCache=false)
Clears the internal cache used to initialize QgsCoordinateTransform objects.
Definition: qgscoordinatetransform.cpp:1061
qgscelestialbody.h
QgsCoordinateReferenceSystemRegistry::celestialBodies
QList< QgsCelestialBody > celestialBodies() const
Returns a list of all known celestial bodies.
Definition: qgscoordinatereferencesystemregistry.cpp:377
sqlite3_statement_unique_ptr::step
int step()
Steps to the next record in the statement, returning the sqlite3 result code.
Definition: qgssqliteutils.cpp:41
QgsCoordinateReferenceSystemRegistry::UserCrsDetails::crs
QgsCoordinateReferenceSystem crs
QgsCoordinateReferenceSystem object representing the user-defined CRS.
Definition: qgscoordinatereferencesystemregistry.h:76
qgsapplication.h
QgsApplication::srsDatabaseFilePath
static QString srsDatabaseFilePath()
Returns the path to the srs.db file.
Definition: qgsapplication.cpp:1124
QgsCoordinateReferenceSystemRegistry::userCrsRemoved
void userCrsRemoved(long id)
Emitted when the user CRS with matching id is removed from the database.
QgsCoordinateReferenceSystemRegistry::crsDefinitionsChanged
void crsDefinitionsChanged()
Emitted whenever an operation has caused any of the known CRS definitions (including user-defined CRS...
QgsCoordinateReferenceSystemRegistry::userCrsList
QList< QgsCoordinateReferenceSystemRegistry::UserCrsDetails > userCrsList() const
Returns a list containing the details of all registered custom (user-defined) CRSes.
Definition: qgscoordinatereferencesystemregistry.cpp:43
QgsCoordinateReferenceSystemRegistry::UserCrsDetails
Contains details of a custom (user defined) CRS.
Definition: qgscoordinatereferencesystemregistry.h:56
QgsCoordinateReferenceSystemRegistry::QgsCoordinateReferenceSystemRegistry
QgsCoordinateReferenceSystemRegistry(QObject *parent=nullptr)
Constructor for QgsCoordinateReferenceSystemRegistry, with the specified parent object.
Definition: qgscoordinatereferencesystemregistry.cpp:35
QgsCoordinateReferenceSystem::toWkt
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
Definition: qgscoordinatereferencesystem.cpp:1810
QgsMessageLog::logMessage
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Definition: qgsmessagelog.cpp:27
QgsCoordinateReferenceSystem::isValid
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Definition: qgscoordinatereferencesystem.cpp:977
qgscoordinatetransform.h
QgsCoordinateReferenceSystem::toProj
QString toProj() const
Returns a Proj string representation of this CRS.
Definition: qgscoordinatereferencesystem.cpp:1293
sqlite3_database_unique_ptr::open_v2
int open_v2(const QString &path, int flags, const char *zVfs)
Opens the database at the specified file path.
Definition: qgssqliteutils.cpp:86
QgsCoordinateReferenceSystem
This class represents a coordinate reference system (CRS).
Definition: qgscoordinatereferencesystem.h:211
QgsCoordinateReferenceSystemRegistry::addUserCrs
long addUserCrs(const QgsCoordinateReferenceSystem &crs, const QString &name, Qgis::CrsDefinitionFormat nativeFormat=Qgis::CrsDefinitionFormat::Wkt)
Adds a new crs definition as a custom ("USER") CRS.
Definition: qgscoordinatereferencesystemregistry.cpp:82
sqlite3_statement_unique_ptr::columnAsText
QString columnAsText(int column) const
Returns the column value from the current statement row as a string.
Definition: qgssqliteutils.cpp:61
QgsCoordinateReferenceSystem::invalidateCache
static void invalidateCache(bool disableCache=false)
Clears the internal cache used to initialize QgsCoordinateReferenceSystem objects.
Definition: qgscoordinatereferencesystem.cpp:2921
QgsCoordinateReferenceSystemRegistry::UserCrsDetails::proj
QString proj
PROJ string definition of CRS.
Definition: qgscoordinatereferencesystemregistry.h:67
QgsProjOperation::id
QString id() const
ID of operation.
Definition: qgsprojoperation.h:56
QgsCoordinateReferenceSystem::createFromProj
bool createFromProj(const QString &projString, bool identify=true)
Sets this CRS by passing it a PROJ style formatted string.
Definition: qgscoordinatereferencesystem.cpp:987
qgsprojutils.h
sqlite3_database_unique_ptr::exec
int exec(const QString &sql, QString &errorMessage) const
Executes the sql command in the database.
Definition: qgssqliteutils.cpp:109
QgsScopedRuntimeProfile
Scoped object for logging of the runtime for a single operation or group of operations.
Definition: qgsruntimeprofiler.h:327
QgsApplication::qgisUserDatabaseFilePath
static QString qgisUserDatabaseFilePath()
Returns the path to the user qgis.db file.
Definition: qgsapplication.cpp:1104
qgssqliteutils.h
qgsexception.h
QgsCoordinateReferenceSystem::ellipsoidAcronym
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
Definition: qgscoordinatereferencesystem.cpp:1251
qgscoordinatereferencesystem_p.h
QgsCoordinateReferenceSystemRegistry::userCrsAdded
void userCrsAdded(const QString &id)
Emitted whenever a new user CRS definition is added.
QgsNotSupportedException
Custom exception class which is raised when an operation is not supported.
Definition: qgsexception.h:117
QgsCoordinateReferenceSystemRegistry::UserCrsDetails::name
QString name
CRS name (or description)
Definition: qgscoordinatereferencesystemregistry.h:64
QgsCoordinateReferenceSystemRegistry::UserCrsDetails::id
long id
CRS ID.
Definition: qgscoordinatereferencesystemregistry.h:61
qgslogger.h
QgsCoordinateReferenceSystemRegistry::~QgsCoordinateReferenceSystemRegistry
~QgsCoordinateReferenceSystemRegistry()
sqlite3_database_unique_ptr
Unique pointer for sqlite3 databases, which automatically closes the database when the pointer goes o...
Definition: qgssqliteutils.h:118
qgscoordinatereferencesystemregistry.h
sqlite3_statement_unique_ptr
Unique pointer for sqlite3 prepared statements, which automatically finalizes the statement when the ...
Definition: qgssqliteutils.h:69
QgsCoordinateReferenceSystemRegistry::userCrsChanged
void userCrsChanged(const QString &id)
Emitted whenever an existing user CRS definition is changed.
qgsmessagelog.h