46 QList<QgsCoordinateReferenceSystemRegistry::UserCrsDetails> res;
52 if ( result != SQLITE_OK )
58 const QString sql = QStringLiteral(
"select srs_id,description,parameters, wkt from tbl_srs" );
59 QgsDebugMsgLevel( QStringLiteral(
"Query to populate existing list:%1" ).arg( sql ), 4 );
61 if ( result == SQLITE_OK )
64 while ( preparedStatement.
step() == SQLITE_ROW )
72 if ( !details.
wkt.isEmpty() )
93 QString proj4String =
crs.d->mProj4;
94 if ( proj4String.isEmpty() )
108 if ( QgsCoordinateReferenceSystem::getRecordCount() == 0 )
110 mySql =
"insert into tbl_srs (srs_id,description,projection_acronym,ellipsoid_acronym,parameters,is_geo,wkt) values ("
114 +
',' + quotedEllipsoidString
122 mySql =
"insert into tbl_srs (description,projection_acronym,ellipsoid_acronym,parameters,is_geo,wkt) values ("
125 +
',' + quotedEllipsoidString
135 if ( myResult != SQLITE_OK )
137 QgsDebugError( QStringLiteral(
"Can't open or create database %1: %2" )
142 statement = database.
prepare( mySql, myResult );
144 qint64 returnId = -1;
145 if ( myResult == SQLITE_OK && statement.
step() == SQLITE_DONE )
149 returnId = sqlite3_last_insert_rowid( database.get() );
150 crs.d->mSrsId = returnId;
151 crs.d->mAuthId = QStringLiteral(
"USER:%1" ).arg( returnId );
152 crs.d->mDescription = name;
155 if ( returnId != -1 )
166 if ( returnId != -1 )
183 const QString sql =
"update tbl_srs set description="
196 if ( myResult != SQLITE_OK )
198 QgsDebugError( QStringLiteral(
"Can't open or create database %1: %2" )
205 QString errorMessage;
206 if ( database.
exec( sql, errorMessage ) != SQLITE_OK )
213 const int changed = sqlite3_changes( database.get() );
253 if ( result != SQLITE_OK )
255 QgsDebugError( QStringLiteral(
"Can't open database: %1 \n please notify QGIS developers of this error \n %2 (file name) " ).arg( database.
errorMessage(),
263 if ( result != SQLITE_OK || preparedStatement.
step() != SQLITE_DONE )
265 QgsDebugError( QStringLiteral(
"failed to remove custom CRS from database: %1 [%2]" ).arg( sql, database.
errorMessage() ) );
270 const int changed = sqlite3_changes( database.get() );
277 QgsMessageLog::logMessage( QObject::tr(
"Error removing user CRS [%1]: No matching ID found in database" ).arg(
id ), QObject::tr(
"CRS" ) );
296bool QgsCoordinateReferenceSystemRegistry::insertProjection(
const QString &projectionAcronym )
303 if ( result != SQLITE_OK )
305 QgsDebugError( QStringLiteral(
"Can't open database: %1 \n please notify QGIS developers of this error \n %2 (file name) " ).arg( database.
errorMessage(),
310 if ( result != SQLITE_OK )
318 const QString srsSql =
"select acronym,name,notes,parameters from tbl_projection where acronym=" +
QgsSqliteUtils::quotedString( projectionAcronym );
321 if ( srsResult == SQLITE_OK )
323 if ( srsPreparedStatement.
step() == SQLITE_ROW )
327 sql =
"insert into tbl_projection(acronym,name,notes,parameters) values ("
334 if ( result != SQLITE_OK || preparedStatement.
step() != SQLITE_DONE )
336 QgsDebugError( QStringLiteral(
"Could not insert projection into database: %1 [%2]" ).arg( sql, database.
errorMessage() ) );
352 static std::once_flag initialized;
353 std::call_once( initialized, [ = ]
357 const PJ_OPERATIONS *operation = proj_list_operations();
358 while ( operation && operation->id )
362 value.mId = QString( operation->id );
364 const QString description( *operation->descr );
365 const QStringList descriptionParts = description.split( QStringLiteral(
"\n\t" ) );
366 value.mDescription = descriptionParts.value( 0 );
367 value.mDetails = descriptionParts.mid( 1 ).join(
'\n' );
369 mProjOperations.insert( value.
id(), value );
375 return mProjOperations;
380#if PROJ_VERSION_MAJOR>8 || (PROJ_VERSION_MAJOR==8 && PROJ_VERSION_MINOR>=1)
382 static std::once_flag initialized;
383 std::call_once( initialized, [ = ]
390 PROJ_CELESTIAL_BODY_INFO **list = proj_get_celestial_body_list_from_database( context,
nullptr, &resultCount );
391 mCelestialBodies.reserve( resultCount );
392 for (
int i = 0; i < resultCount; i++ )
394 const PROJ_CELESTIAL_BODY_INFO *info = list[ i ];
400 body.mAuthority = QString( info->auth_name );
401 body.mName = QString( info->name );
403 mCelestialBodies << body;
405 proj_celestial_body_list_destroy( list );
408 return mCelestialBodies;
410 throw QgsNotSupportedException( QObject::tr(
"Retrieving celestial bodies requires a QGIS build based on PROJ 8.1 or later" ) );
416 static std::once_flag initialized;
417 std::call_once( initialized, [ = ]
422 PROJ_STRING_LIST
authorities = proj_get_authorities_from_database( pjContext );
424 for (
auto authIter =
authorities; authIter && *authIter; ++authIter )
426 const QString authority( *authIter );
427 mKnownAuthorities.insert( authority.toLower() );
433 return mKnownAuthorities;
438 static std::once_flag initialized;
439 std::call_once( initialized, [ = ]
442 if ( QFileInfo::exists( srsDatabaseFileName ) )
446 int result = database.
open_v2( srsDatabaseFileName, SQLITE_OPEN_READONLY,
nullptr );
447 if ( result == SQLITE_OK )
449 const QString sql = QStringLiteral(
"SELECT description, srs_id, auth_name, auth_id, projection_acronym, deprecated, srs_type FROM tbl_srs" );
451 if ( result == SQLITE_OK )
453 while ( preparedStatement.
step() == SQLITE_ROW )
463 mCrsDbRecords.append( record );
470 return mCrsDbRecords;
CrsDefinitionFormat
CRS definition formats.
@ Wkt
WKT format (always recommended over proj string format)
static QString qgisUserDatabaseFilePath()
Returns the path to the user qgis.db file.
static QString srsDatabaseFilePath()
Returns the path to the srs.db file.
Contains information about a celestial body.
Contains details of a custom (user defined) CRS.
QgsCoordinateReferenceSystem crs
QgsCoordinateReferenceSystem object representing the user-defined CRS.
QString proj
PROJ string definition of CRS.
QString wkt
WKT definition of CRS.
QString name
CRS name (or description)
QList< QgsCrsDbRecord > crsDbRecords() const
Returns the list of records from the QGIS srs db.
void userCrsAdded(const QString &id)
Emitted whenever a new user CRS definition is added.
void userCrsChanged(const QString &id)
Emitted whenever an existing user CRS definition is changed.
QList< QgsCelestialBody > celestialBodies() const
Returns a list of all known celestial bodies.
void userCrsRemoved(long id)
Emitted when the user CRS with matching id is removed from the database.
void crsDefinitionsChanged()
Emitted whenever an operation has caused any of the known CRS definitions (including user-defined CRS...
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.
QgsCoordinateReferenceSystemRegistry(QObject *parent=nullptr)
Constructor for QgsCoordinateReferenceSystemRegistry, with the specified parent object.
~QgsCoordinateReferenceSystemRegistry()
long addUserCrs(const QgsCoordinateReferenceSystem &crs, const QString &name, Qgis::CrsDefinitionFormat nativeFormat=Qgis::CrsDefinitionFormat::Wkt)
Adds a new crs definition as a custom ("USER") CRS.
QSet< QString > authorities() const
Returns a list of all known authorities.
bool removeUserCrs(long id)
Removes the existing user CRS with matching id.
QList< QgsCoordinateReferenceSystemRegistry::UserCrsDetails > userCrsList() const
Returns a list containing the details of all registered custom (user-defined) CRSes.
QMap< QString, QgsProjOperation > projOperations() const
Returns a map of all valid PROJ operations.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
bool createFromWkt(const QString &wkt)
Sets this CRS using a WKT definition.
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.
bool createFromProj(const QString &projString, bool identify=true)
Sets this CRS by passing it a PROJ style formatted string.
static void invalidateCache(bool disableCache=false)
Clears the internal cache used to initialize QgsCoordinateReferenceSystem objects.
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
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).
Custom exception class which is raised when an operation is not supported.
static PJ_CONTEXT * get()
Returns a thread local instance of a proj context, safe for use in the current thread.
Contains information about a PROJ operation.
QString id() const
ID of operation.
Scoped object for logging of the runtime for a single operation or group of operations.
static QString quotedString(const QString &value)
Returns a quoted string value, surround by ' characters and with special characters correctly escaped...
Unique pointer for sqlite3 databases, which automatically closes the database when the pointer goes o...
sqlite3_statement_unique_ptr prepare(const QString &sql, int &resultCode) const
Prepares a sql statement, returning the result.
int open(const QString &path)
Opens the database at the specified file path.
QString errorMessage() const
Returns the most recent error message encountered by the database.
int open_v2(const QString &path, int flags, const char *zVfs)
Opens the database at the specified file path.
int exec(const QString &sql, QString &errorMessage) const
Executes the sql command in the database.
Unique pointer for sqlite3 prepared statements, which automatically finalizes the statement when the ...
QString columnAsText(int column) const
Returns the column value from the current statement row as a string.
int step()
Steps to the next record in the statement, returning the sqlite3 result code.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
const int USER_CRS_START_ID
Magick number that determines whether a projection crsid is a system (srs.db) or user (~/....
struct projCtx_t PJ_CONTEXT
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
const QgsCoordinateReferenceSystem & crs
QString projectionAcronym