41#include "moc_qgscoordinatereferencesystemregistry.cpp"
43using namespace Qt::StringLiterals;
60 QList<QgsCoordinateReferenceSystemRegistry::UserCrsDetails> res;
66 if ( result != SQLITE_OK )
72 const QString sql = u
"select srs_id,description,parameters, wkt from tbl_srs"_s;
75 if ( result == SQLITE_OK )
78 while ( preparedStatement.
step() == SQLITE_ROW )
86 if ( !details.
wkt.isEmpty() )
107 QString proj4String = crs.d->mProj4;
108 if ( proj4String.isEmpty() )
110 proj4String = crs.
toProj();
122 if ( QgsCoordinateReferenceSystem::getRecordCount() == 0 )
124 mySql =
"insert into tbl_srs (srs_id,description,projection_acronym,ellipsoid_acronym,parameters,is_geo,wkt) values ("
131 + quotedEllipsoidString
140 mySql =
"insert into tbl_srs (description,projection_acronym,ellipsoid_acronym,parameters,is_geo,wkt) values ("
145 + quotedEllipsoidString
156 if ( myResult != SQLITE_OK )
161 statement = database.
prepare( mySql, myResult );
163 qint64 returnId = -1;
164 if ( myResult == SQLITE_OK && statement.
step() == SQLITE_DONE )
168 returnId = sqlite3_last_insert_rowid( database.get() );
169 crs.d->mSrsId = returnId;
170 crs.d->mAuthId = u
"USER:%1"_s.arg( returnId );
171 crs.d->mDescription = name;
174 if ( returnId != -1 )
185 if ( returnId != -1 )
202 const QString sql =
"update tbl_srs set description="
204 +
",projection_acronym="
206 +
",ellipsoid_acronym="
219 if ( myResult != SQLITE_OK )
226 QString errorMessage;
227 if ( database.
exec( sql, errorMessage ) != SQLITE_OK )
234 const int changed = sqlite3_changes( database.get() );
274 if ( result != SQLITE_OK )
283 if ( result != SQLITE_OK || preparedStatement.
step() != SQLITE_DONE )
290 const int changed = sqlite3_changes( database.get() );
297 QgsMessageLog::logMessage( QObject::tr(
"Error removing user CRS [%1]: No matching ID found in database" ).arg(
id ), QObject::tr(
"CRS" ) );
316bool QgsCoordinateReferenceSystemRegistry::insertProjection(
const QString &projectionAcronym )
323 if ( result != SQLITE_OK )
329 if ( result != SQLITE_OK )
336 const QString srsSql =
"select acronym,name,notes,parameters from tbl_projection where acronym=" +
QgsSqliteUtils::quotedString( projectionAcronym );
338 sqlite3_statement_unique_ptr srsPreparedStatement = srsDatabase.
prepare( srsSql, srsResult );
339 if ( srsResult == SQLITE_OK )
341 if ( srsPreparedStatement.
step() == SQLITE_ROW )
345 sql =
"insert into tbl_projection(acronym,name,notes,parameters) values ("
354 sqlite3_statement_unique_ptr preparedStatement = database.
prepare( sql, result );
355 if ( result != SQLITE_OK || preparedStatement.
step() != SQLITE_DONE )
373 static std::once_flag initialized;
374 static QMap< QString, QgsProjOperation > sProjOperations;
375 std::call_once( initialized, [] {
378 const PJ_OPERATIONS *operation = proj_list_operations();
379 while ( operation && operation->id )
383 value.mId = QString( operation->id );
385 const QString description( *operation->descr );
386 const QStringList descriptionParts = description.split( u
"\n\t"_s );
387 value.mDescription = descriptionParts.value( 0 );
388 value.mDetails = descriptionParts.mid( 1 ).join(
'\n' );
390 sProjOperations.insert( value.
id(), value );
396 return sProjOperations;
401 static QList< QgsCelestialBody > sCelestialBodies;
402 static std::once_flag initialized;
403 std::call_once( initialized, [] {
409 PROJ_CELESTIAL_BODY_INFO **list = proj_get_celestial_body_list_from_database( context,
nullptr, &resultCount );
410 sCelestialBodies.reserve( resultCount );
411 for (
int i = 0; i < resultCount; i++ )
413 const PROJ_CELESTIAL_BODY_INFO *info = list[i];
419 body.mAuthority = QString( info->auth_name );
420 body.mName = QString( info->name );
422 sCelestialBodies << body;
424 proj_celestial_body_list_destroy( list );
427 return sCelestialBodies;
432 static QSet< QString > sKnownAuthorities;
433 static std::once_flag initialized;
434 std::call_once( initialized, [] {
438 PROJ_STRING_LIST
authorities = proj_get_authorities_from_database( pjContext );
440 for (
auto authIter =
authorities; authIter && *authIter; ++authIter )
442 const QString authority( *authIter );
443 sKnownAuthorities.insert( authority.toLower() );
449 return sKnownAuthorities;
455 if ( mCrsDbRecordsPopulated )
456 return mCrsDbRecords;
461 if ( QFileInfo::exists( srsDatabaseFileName ) )
465 int result = database.
open_v2( srsDatabaseFileName, SQLITE_OPEN_READONLY,
nullptr );
466 if ( result == SQLITE_OK )
468 const QString sql = u
"SELECT description, srs_id, auth_name, auth_id, projection_acronym, deprecated, srs_type FROM tbl_srs"_s;
470 if ( result == SQLITE_OK )
472 while ( preparedStatement.
step() == SQLITE_ROW )
482 mCrsDbRecords.append( record );
488 mCrsDbRecordsPopulated =
true;
489 return mCrsDbRecords;
494 QList<QgsCoordinateReferenceSystem> res;
500 int max = std::max( projectionsAuthId.size(), std::max( projectionsProj4.size(), projectionsWkt.size() ) );
502 for (
int i = 0; i < max; ++i )
504 const QString proj = projectionsProj4.value( i );
505 const QString wkt = projectionsWkt.value( i );
506 const QString authid = projectionsAuthId.value( i );
509 if ( !authid.isEmpty() )
511 if ( !crs.
isValid() && !wkt.isEmpty() )
513 if ( !crs.
isValid() && !proj.isEmpty() )
537 QList<QgsCoordinateReferenceSystem> recent =
recentCrs();
538 recent.removeAll( crs );
539 recent.insert( 0, crs );
542 switch ( crs.
type() )
563 QList<QgsCoordinateReferenceSystem> recentSameType;
564 std::copy_if( recent.begin(), recent.end(), std::back_inserter( recentSameType ), [crs, &hasVertical](
const QgsCoordinateReferenceSystem &it ) { return hasVertical( it ) == hasVertical( crs ); } );
567 const QList<QgsCoordinateReferenceSystem> toTrim = recentSameType.mid( 30 );
570 recent.removeOne( crsTrimmed );
575 authids.reserve( recent.size() );
577 proj.reserve( recent.size() );
579 wkt.reserve( recent.size() );
582 authids <<
c.authid();
599 QList<QgsCoordinateReferenceSystem> recent =
recentCrs();
600 recent.removeAll( crs );
602 authids.reserve( recent.size() );
604 proj.reserve( recent.size() );
606 wkt.reserve( recent.size() );
609 authids <<
c.authid();
@ Compound
Compound (horizontal + vertical) CRS.
@ Projected
Projected CRS.
@ DerivedProjected
Derived projected CRS.
@ Engineering
Engineering CRS.
@ Geographic3d
3D geopraphic CRS
@ Geographic2d
2D geographic CRS
@ Geocentric
Geocentric CRS.
CrsDefinitionFormat
CRS definition formats.
@ Wkt
WKT format (always recommended over proj string format).
static const int USER_CRS_START_ID
Minimum ID number for a user-defined projection.
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
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.
static const QgsSettingsEntryStringList * settingsRecentProjectionsProj4
void userCrsAdded(const QString &id)
Emitted whenever a new user CRS definition is added.
void recentCrsRemoved(const QgsCoordinateReferenceSystem &crs)
Emitted when a recently used CRS has been removed from the recent CRS list.
void userCrsChanged(const QString &id)
Emitted whenever an existing user CRS definition is changed.
void recentCrsCleared()
Emitted when the list of recently used CRS has been cleared.
void recentCrsPushed(const QgsCoordinateReferenceSystem &crs)
Emitted when a recently used CRS has been pushed to the top of the recent CRS list.
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.
void removeRecent(const QgsCoordinateReferenceSystem &crs)
Removes a CRS from the list of recently used CRS.
~QgsCoordinateReferenceSystemRegistry() override
static const QgsSettingsEntryStringList * settingsRecentProjectionsWkt
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.
static const QgsSettingsEntryStringList * settingsRecentProjectionsAuthId
bool removeUserCrs(long id)
Removes the existing user CRS with matching id.
void clearRecent()
Cleans the list of recently used CRS.
QList< QgsCoordinateReferenceSystemRegistry::UserCrsDetails > userCrsList() const
Returns a list containing the details of all registered custom (user-defined) CRSes.
QList< QgsCoordinateReferenceSystem > recentCrs()
Returns a list of recently used CRS.
void pushRecent(const QgsCoordinateReferenceSystem &crs)
Pushes a recently used CRS to the top of the recent CRS list.
QMap< QString, QgsProjOperation > projOperations() const
Returns a map of all valid PROJ operations.
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.
QString toWkt(Qgis::CrsWktVariant variant=Qgis::CrsWktVariant::Wkt1Gdal, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
long srsid() const
Returns the internal CRS ID, if available.
Qgis::CrsType type() const
Returns the type of the CRS.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
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.
A convenience class that simplifies locking and unlocking QReadWriteLocks.
void changeMode(Mode mode)
Change the mode of the lock to mode.
Scoped object for logging of the runtime for a single operation or group of operations.
A string list settings entry.
static QgsSettingsTreeNode * sTreeCrs
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.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
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.
#define BUILTIN_UNREACHABLE
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
QString projectionAcronym