long QgsProjectionSelectionTreeWidget::getLargestCrsIdMatch( const QString &sql ) { long srsId = 0; // // Now perform the actual search // sqlite3 *database = nullptr; const char *tail = nullptr; sqlite3_stmt *stmt = nullptr; int result; // first we search the users db as any srsid there will be definition be greater than in sys db //check the db is available QString databaseFileName = QgsApplication::qgisUserDatabaseFilePath(); if ( QFileInfo::exists( databaseFileName ) ) //only bother trying to open if the file exists { result = sqlite3_open_v2( databaseFileName.toUtf8().data(), &database, SQLITE_OPEN_READONLY, nullptr ); if ( result ) { // XXX This will likely never happen since on open, sqlite creates the // database if it does not exist. But we checked earlier for its existence // and aborted in that case. This is because we may be running from read only // media such as live cd and don't want to force trying to create a db. showDBMissingWarning( databaseFileName ); return 0; } result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail ); // XXX Need to free memory from the error msg if one is set if ( result == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW ) { QString srsIdString = QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 0 ) ); srsId = srsIdString.toLong(); // close the sqlite3 statement sqlite3_finalize( stmt ); sqlite3_close( database ); return srsId; } } else { //only bother looking in srs.db if it wasn't found above result = sqlite3_open_v2( mSrsDatabaseFileName.toUtf8().data(), &database, SQLITE_OPEN_READONLY, nullptr ); if ( result ) { QgsDebugMsg( QString( "Can't open * user * database: %1" ).arg( sqlite3_errmsg( database ) ) ); //no need for assert because user db may not have been created yet return 0; } } result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail ); // XXX Need to free memory from the error msg if one is set if ( result == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW ) { QString srsIdString = QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 0 ) ); srsId = srsIdString.toLong(); } // close the sqlite3 statement sqlite3_finalize( stmt ); sqlite3_close( database ); return srsId; }
void QgsProjectionSelectionTreeWidget::loadUserCrsList( QSet<QString> *crsFilter ) { if ( mUserProjListDone ) return; QgsDebugMsgLevel( "Fetching user projection list...", 4 ); // convert our Coordinate Reference System filter into the SQL expression QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter ); // User defined coordinate system node // Make in an italic font to distinguish them from real projections mUserProjList = new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr( "User Defined Coordinate Systems" ) ) ); QFont fontTemp = mUserProjList->font( 0 ); fontTemp.setItalic( true ); fontTemp.setBold( true ); mUserProjList->setFont( 0, fontTemp ); mUserProjList->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/user.svg" ) ) ); //determine where the user proj database lives for this user. If none is found an empty //now only will be shown QString databaseFileName = QgsApplication::qgisUserDatabaseFilePath(); // first we look for ~/.qgis/qgis.db // if it doesn't exist we copy it in from the global resources dir //return straight away if the user has not created any custom projections if ( !QFileInfo::exists( databaseFileName ) ) { QgsDebugMsg( "Users qgis.db not found...skipping" ); mUserProjListDone = true; return; } sqlite3 *database = nullptr; const char *tail = nullptr; sqlite3_stmt *stmt = nullptr; //check the db is available int result = sqlite3_open_v2( databaseFileName.toUtf8().constData(), &database, SQLITE_OPEN_READONLY, nullptr ); if ( result ) { // XXX This will likely never happen since on open, sqlite creates the // database if it does not exist. But we checked earlier for its existence // and aborted in that case. This is because we may be running from read only // media such as live cd and don't want to force trying to create a db. showDBMissingWarning( databaseFileName ); return; } // Set up the query to retrieve the projection information needed to populate the list QString sql = QStringLiteral( "select description, srs_id from vw_srs where %1" ).arg( sqlFilter ); result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail ); // XXX Need to free memory from the error msg if one is set if ( result == SQLITE_OK ) { QTreeWidgetItem *newItem = nullptr; while ( sqlite3_step( stmt ) == SQLITE_ROW ) { newItem = new QTreeWidgetItem( mUserProjList, QStringList( QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 0 ) ) ) ); // EpsgCrsId for user projections is not always defined in some dbases. // It's also not written from customprojections dialog. // display the epsg (field 2) in the second column of the list view // newItem->setText( EPSG_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( stmt, 2 ) ) ); // display the qgis srs_id (field 1) in the third column of the list view newItem->setText( QgisCrsIdColumn, QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 1 ) ) ); newItem->setText( AuthidColumn, QStringLiteral( "USER:%1" ).arg( QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 1 ) ).toInt() ) ); } } // close the sqlite3 statement sqlite3_finalize( stmt ); sqlite3_close( database ); mUserProjListDone = true; }
void QgsProjectionSelectionTreeWidget::loadCrsList( QSet<QString> *crsFilter ) { if ( mProjListDone ) return; // convert our Coordinate Reference System filter into the SQL expression QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter ); // Create the top-level nodes for the list view of projections // Make in an italic font to distinguish them from real projections // // Geographic coordinate system node mGeoList = new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr( "Geographic Coordinate Systems" ) ) ); QFont fontTemp = mGeoList->font( 0 ); fontTemp.setItalic( true ); fontTemp.setBold( true ); mGeoList->setFont( 0, fontTemp ); mGeoList->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconProjectionEnabled.svg" ) ) ); // Projected coordinate system node mProjList = new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr( "Projected Coordinate Systems" ) ) ); fontTemp = mProjList->font( 0 ); fontTemp.setItalic( true ); fontTemp.setBold( true ); mProjList->setFont( 0, fontTemp ); mProjList->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/transformed.svg" ) ) ); //bail out in case the projections db does not exist //this is necessary in case the pc is running linux with a //read only filesystem because otherwise sqlite will try //to create the db file on the fly if ( !QFileInfo::exists( mSrsDatabaseFileName ) ) { mProjListDone = true; return; } // open the database containing the spatial reference data sqlite3 *database = nullptr; int rc = sqlite3_open_v2( mSrsDatabaseFileName.toUtf8().data(), &database, SQLITE_OPEN_READONLY, nullptr ); if ( rc ) { // XXX This will likely never happen since on open, sqlite creates the // database if it does not exist. showDBMissingWarning( mSrsDatabaseFileName ); return; } const char *tail = nullptr; sqlite3_stmt *stmt = nullptr; // Set up the query to retrieve the projection information needed to populate the list //note I am giving the full field names for clarity here and in case someone //changes the underlying view TS QString sql = QStringLiteral( "select description, srs_id, upper(auth_name||':'||auth_id), is_geo, name, parameters, deprecated from vw_srs where %1 order by name,description" ) .arg( sqlFilter ); rc = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail ); // XXX Need to free memory from the error msg if one is set if ( rc == SQLITE_OK ) { QTreeWidgetItem *newItem = nullptr; // Cache some stuff to speed up creating of the list of projected // spatial reference systems QString previousSrsType; QTreeWidgetItem *previousSrsTypeNode = nullptr; while ( sqlite3_step( stmt ) == SQLITE_ROW ) { // check to see if the srs is geographic int isGeo = sqlite3_column_int( stmt, 3 ); if ( isGeo ) { // this is a geographic coordinate system // Add it to the tree (field 0) newItem = new QTreeWidgetItem( mGeoList, QStringList( QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 0 ) ) ) ); // display the authority name (field 2) in the second column of the list view newItem->setText( AuthidColumn, QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 2 ) ) ); // display the qgis srs_id (field 1) in the third column of the list view newItem->setText( QgisCrsIdColumn, QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 1 ) ) ); } else { // This is a projected srs QTreeWidgetItem *node = nullptr; QString srsType = QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 4 ) ); // Find the node for this type and add the projection to it // If the node doesn't exist, create it if ( srsType == previousSrsType ) { node = previousSrsTypeNode; } else { // Different from last one, need to search QList<QTreeWidgetItem *> nodes = lstCoordinateSystems->findItems( srsType, Qt::MatchExactly | Qt::MatchRecursive, NameColumn ); if ( nodes.isEmpty() ) { // the node doesn't exist -- create it // Make in an italic font to distinguish them from real projections node = new QTreeWidgetItem( mProjList, QStringList( srsType ) ); QFont fontTemp = node->font( 0 ); fontTemp.setItalic( true ); node->setFont( 0, fontTemp ); } else { node = nodes.first(); } // Update the cache. previousSrsType = srsType; previousSrsTypeNode = node; } // add the item, setting the projection name in the first column of the list view newItem = new QTreeWidgetItem( node, QStringList( QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 0 ) ) ) ); // display the authority id (field 2) in the second column of the list view newItem->setText( AuthidColumn, QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 2 ) ) ); // display the qgis srs_id (field 1) in the third column of the list view newItem->setText( QgisCrsIdColumn, QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 1 ) ) ); // expand also parent node newItem->parent()->setExpanded( true ); } // display the qgis deprecated in the user data of the item newItem->setData( 0, RoleDeprecated, QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 6 ) ) ); newItem->setHidden( cbxHideDeprecated->isChecked() ); } mProjList->setExpanded( true ); } // close the sqlite3 statement sqlite3_finalize( stmt ); // close the database sqlite3_close( database ); mProjListDone = true; }
long QgsProjectionSelector::getLargestCRSIDMatch( QString theSql ) { long mySrsId = 0; // // Now perform the actual search // sqlite3 *myDatabase; const char *myTail; sqlite3_stmt *myPreparedStatement; int myResult; // first we search the users db as any srsid there will be definition be greater than in sys db //check the db is available QString myDatabaseFileName = QgsApplication::qgisUserDbFilePath(); QFileInfo myFileInfo; myFileInfo.setFile( myDatabaseFileName ); if ( myFileInfo.exists( ) ) //only bother trying to open if the file exists { myResult = sqlite3_open( myDatabaseFileName.toUtf8().data(), &myDatabase ); if ( myResult ) { // XXX This will likely never happen since on open, sqlite creates the // database if it does not exist. But we checked earlier for its existance // and aborted in that case. This is because we may be runnig from read only // media such as live cd and dont want to force trying to create a db. showDBMissingWarning( myDatabaseFileName ); return 0; } else { myResult = sqlite3_prepare( myDatabase, theSql.toUtf8(), theSql.length(), &myPreparedStatement, &myTail ); // XXX Need to free memory from the error msg if one is set if ( myResult == SQLITE_OK ) { myResult = sqlite3_step( myPreparedStatement ); if ( myResult == SQLITE_ROW ) { QString mySrsIdString = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) ); mySrsId = mySrsIdString.toLong(); // close the sqlite3 statement sqlite3_finalize( myPreparedStatement ); sqlite3_close( myDatabase ); return mySrsId; } } } } //only bother looking in srs.db if it wasnt found above myResult = sqlite3_open( mSrsDatabaseFileName.toUtf8().data(), &myDatabase ); if ( myResult ) { QgsDebugMsg( QString( "Can't open * user * database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) ); //no need for assert because user db may not have been created yet return 0; } myResult = sqlite3_prepare( myDatabase, theSql.toUtf8(), theSql.length(), &myPreparedStatement, &myTail ); // XXX Need to free memory from the error msg if one is set if ( myResult == SQLITE_OK ) { myResult = sqlite3_step( myPreparedStatement ); if ( myResult == SQLITE_ROW ) { QString mySrsIdString = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) ); mySrsId = mySrsIdString.toLong(); // close the sqlite3 statement sqlite3_finalize( myPreparedStatement ); sqlite3_close( myDatabase ); } } return mySrsId; }
// Returns the whole proj4 string for the selected projection node QString QgsProjectionSelectionTreeWidget::selectedProj4String() { // Only return the projection if there is a node in the tree // selected that has an srid. This prevents error if the user // selects a top-level node rather than an actual coordinate // system // // Get the selected node QTreeWidgetItem *item = lstCoordinateSystems->currentItem(); if ( !item || item->text( QgisCrsIdColumn ).isEmpty() ) return QString(); QString srsId = item->text( QgisCrsIdColumn ); QgsDebugMsgLevel( "srsId = " + srsId, 4 ); QgsDebugMsgLevel( "USER_CRS_START_ID = " + QString::number( USER_CRS_START_ID ), 4 ); // // Determine if this is a user projection or a system on // user projection defs all have srs_id >= 100000 // QString databaseFileName; if ( srsId.toLong() >= USER_CRS_START_ID ) { databaseFileName = QgsApplication::qgisUserDatabaseFilePath(); if ( !QFileInfo::exists( databaseFileName ) ) //its unlikely that this condition will ever be reached return QString(); } else //must be a system projection then { databaseFileName = mSrsDatabaseFileName; } QgsDebugMsgLevel( "db = " + databaseFileName, 4 ); sqlite3 *database = nullptr; int rc = sqlite3_open_v2( databaseFileName.toUtf8().data(), &database, SQLITE_OPEN_READONLY, nullptr ); if ( rc ) { showDBMissingWarning( databaseFileName ); return QString(); } // prepare the sql statement const char *tail = nullptr; sqlite3_stmt *stmt = nullptr; QString sql = QStringLiteral( "select parameters from tbl_srs where srs_id=%1" ).arg( srsId ); QgsDebugMsgLevel( "Selection sql: " + sql, 4 ); rc = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail ); // XXX Need to free memory from the error msg if one is set QString projString; if ( rc == SQLITE_OK && sqlite3_step( stmt ) == SQLITE_ROW ) { projString = QString::fromUtf8( ( char * )sqlite3_column_text( stmt, 0 ) ); } // close the statement sqlite3_finalize( stmt ); // close the database sqlite3_close( database ); Q_ASSERT( !projString.isEmpty() ); return projString; }
void QgsProjectionSelector::on_pbnFind_clicked() { QgsDebugMsg( "pbnFind..." ); QString mySearchString( sqlSafeString( leSearch->text() ) ); // Set up the query to retrieve the projection information needed to populate the list QString mySql; if ( radEpsgCrsId->isChecked() ) { mySql = "select srs_id from tbl_srs where epsg=" + mySearchString; } else if ( radName->isChecked() ) //name search { //we need to find what the largest srsid matching our query so we know whether to //loop backto the beginning mySql = "select srs_id from tbl_srs where description like '%" + mySearchString + "%'" + " order by srs_id desc limit 1"; long myLargestSrsId = getLargestCRSIDMatch( mySql ); QgsDebugMsg( QString( "Largest CRSID%1" ).arg( myLargestSrsId ) ); //a name search is ambiguous, so we find the first srsid after the current seelcted srsid // each time the find button is pressed. This means we can loop through all matches. if ( myLargestSrsId <= selectedCrsId() ) { //roll search around to the beginning mySql = "select srs_id from tbl_srs where description like '%" + mySearchString + "%'" + " order by srs_id limit 1"; } else { // search ahead of the current postion mySql = "select srs_id from tbl_srs where description like '%" + mySearchString + "%'" + " and srs_id > " + QString::number( selectedCrsId() ) + " order by srs_id limit 1"; } } QgsDebugMsg( QString( " Search sql: %1" ).arg( mySql ) ); // // Now perform the actual search // sqlite3 *myDatabase; const char *myTail; sqlite3_stmt *myPreparedStatement; int myResult; //check the db is available myResult = sqlite3_open( mSrsDatabaseFileName.toUtf8().data(), &myDatabase ); if ( myResult ) { // XXX This will likely never happen since on open, sqlite creates the // database if it does not exist. But we checked earlier for its existance // and aborted in that case. This is because we may be runnig from read only // media such as live cd and dont want to force trying to create a db. showDBMissingWarning( mSrsDatabaseFileName ); return; } myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail ); // XXX Need to free memory from the error msg if one is set if ( myResult == SQLITE_OK ) { myResult = sqlite3_step( myPreparedStatement ); if ( myResult == SQLITE_ROW ) { QString mySrsId = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) ); setSelectedCrsId( mySrsId.toLong() ); // close the sqlite3 statement sqlite3_finalize( myPreparedStatement ); sqlite3_close( myDatabase ); return; } } //search the users db QString myDatabaseFileName = QgsApplication::qgisUserDbFilePath(); QFileInfo myFileInfo; myFileInfo.setFile( myDatabaseFileName ); if ( !myFileInfo.exists( ) ) //its not critical if this happens { qDebug( "%s\nUser db does not exist", myDatabaseFileName.toUtf8().constData() ); return ; } myResult = sqlite3_open( myDatabaseFileName.toUtf8().data(), &myDatabase ); if ( myResult ) { QgsDebugMsg( QString( "Can't open * user * database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) ); //no need for assert because user db may not have been created yet return; } myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail ); // XXX Need to free memory from the error msg if one is set if ( myResult == SQLITE_OK ) { myResult = sqlite3_step( myPreparedStatement ); if ( myResult == SQLITE_ROW ) { QString mySrsId = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) ); setSelectedCrsId( mySrsId.toLong() ); // close the sqlite3 statement sqlite3_finalize( myPreparedStatement ); sqlite3_close( myDatabase ); } } }
void QgsProjectionSelector::loadCrsList( QSet<QString> * crsFilter ) { // convert our Coordinate Reference System filter into the SQL expression QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter ); // Create the top-level nodes for the list view of projections // Make in an italic font to distinguish them from real projections // // Geographic coordinate system node mGeoList = new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr( "Geographic Coordinate Systems" ) ) ); QFont fontTemp = mGeoList->font( 0 ); fontTemp.setItalic( TRUE ); fontTemp.setBold( TRUE ); mGeoList->setFont( 0, fontTemp ); mGeoList->setIcon( 0, QIcon( QgsApplication::activeThemePath() + "geographic.png" ) ); // Projected coordinate system node mProjList = new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr( "Projected Coordinate Systems" ) ) ); fontTemp = mProjList->font( 0 ); fontTemp.setItalic( TRUE ); fontTemp.setBold( TRUE ); mProjList->setFont( 0, fontTemp ); mProjList->setIcon( 0, QIcon( QgsApplication::activeThemePath() + "transformed.png" ) ); //bail out in case the projections db does not exist //this is neccessary in case the pc is running linux with a //read only filesystem because otherwise sqlite will try //to create the db file on the fly QFileInfo myFileInfo; myFileInfo.setFile( mSrsDatabaseFileName ); if ( !myFileInfo.exists( ) ) { mProjListDone = TRUE; return; } // open the database containing the spatial reference data sqlite3 *db; int rc; rc = sqlite3_open( mSrsDatabaseFileName.toUtf8().data(), &db ); if ( rc ) { // XXX This will likely never happen since on open, sqlite creates the // database if it does not exist. showDBMissingWarning( mSrsDatabaseFileName ); return ; } // prepare the sql statement const char *pzTail; sqlite3_stmt *ppStmt; // get total count of records in the projection table QString sql = "select count(*) from tbl_srs"; rc = sqlite3_prepare( db, sql.toUtf8(), sql.length(), &ppStmt, &pzTail ); assert( rc == SQLITE_OK ); sqlite3_step( ppStmt ); sqlite3_finalize( ppStmt ); // Set up the query to retrieve the projection information needed to populate the list //note I am giving the full field names for clarity here and in case someown //changes the underlying view TS sql = "select description, srs_id, epsg, is_geo, name, parameters from vw_srs "; sql += "where "; sql += sqlFilter; sql += " order by name, description"; rc = sqlite3_prepare( db, sql.toUtf8(), sql.length(), &ppStmt, &pzTail ); // XXX Need to free memory from the error msg if one is set if ( rc == SQLITE_OK ) { QTreeWidgetItem *newItem; // Cache some stuff to speed up creating of the list of projected // spatial reference systems QString previousSrsType( "" ); QTreeWidgetItem* previousSrsTypeNode = NULL; while ( sqlite3_step( ppStmt ) == SQLITE_ROW ) { // check to see if the srs is geographic int isGeo = sqlite3_column_int( ppStmt, 3 ); if ( isGeo ) { // this is a geographic coordinate system // Add it to the tree (field 0) newItem = new QTreeWidgetItem( mGeoList, QStringList( QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 0 ) ) ) ); // display the epsg (field 2) in the second column of the list view newItem->setText( EPSG_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 2 ) ) ); // display the qgis srs_id (field 1) in the third column of the list view newItem->setText( QGIS_CRS_ID_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 1 ) ) ); } else { // This is a projected srs QTreeWidgetItem *node; QString srsType = QString::fromUtf8(( char* )sqlite3_column_text( ppStmt, 4 ) ); // Find the node for this type and add the projection to it // If the node doesn't exist, create it if ( srsType == previousSrsType ) { node = previousSrsTypeNode; } else { // Different from last one, need to search QList<QTreeWidgetItem*> nodes = lstCoordinateSystems->findItems( srsType, Qt::MatchExactly | Qt::MatchRecursive, 0 ); if ( nodes.count() == 0 ) { // the node doesn't exist -- create it // Make in an italic font to distinguish them from real projections node = new QTreeWidgetItem( mProjList, QStringList( srsType ) ); QFont fontTemp = node->font( 0 ); fontTemp.setItalic( TRUE ); node->setFont( 0, fontTemp ); } else { node = nodes.first(); } // Update the cache. previousSrsType = srsType; previousSrsTypeNode = node; } // add the item, setting the projection name in the first column of the list view newItem = new QTreeWidgetItem( node, QStringList( QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 0 ) ) ) ); // display the epsg (field 2) in the second column of the list view newItem->setText( EPSG_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 2 ) ) ); // display the qgis srs_id (field 1) in the third column of the list view newItem->setText( QGIS_CRS_ID_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 1 ) ) ); } } mProjList->setExpanded( true ); } // close the sqlite3 statement sqlite3_finalize( ppStmt ); // close the database sqlite3_close( db ); mProjListDone = TRUE; }
void QgsProjectionSelector::loadUserCrsList( QSet<QString> * crsFilter ) { QgsDebugMsg( "Fetching user projection list..." ); // convert our Coordinate Reference System filter into the SQL expression QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter ); // User defined coordinate system node // Make in an italic font to distinguish them from real projections mUserProjList = new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr( "User Defined Coordinate Systems" ) ) ); QFont fontTemp = mUserProjList->font( 0 ); fontTemp.setItalic( TRUE ); fontTemp.setBold( TRUE ); mUserProjList->setFont( 0, fontTemp ); mUserProjList->setIcon( 0, QIcon( QgsApplication::activeThemePath() + "user.png" ) ); //determine where the user proj database lives for this user. If none is found an empty //now only will be shown QString myDatabaseFileName = QgsApplication::qgisUserDbFilePath(); // first we look for ~/.qgis/qgis.db // if it doesnt exist we copy it in from the global resources dir QFileInfo myFileInfo; myFileInfo.setFile( myDatabaseFileName ); //return straight away if the user has not created any custom projections if ( !myFileInfo.exists( ) ) { QgsDebugMsg( "Users qgis.db not found...skipping" ); mUserProjListDone = TRUE; return; } sqlite3 *myDatabase; const char *myTail; sqlite3_stmt *myPreparedStatement; int myResult; //check the db is available myResult = sqlite3_open( QString( myDatabaseFileName ).toUtf8().data(), &myDatabase ); if ( myResult ) { // XXX This will likely never happen since on open, sqlite creates the // database if it does not exist. But we checked earlier for its existance // and aborted in that case. This is because we may be runnig from read only // media such as live cd and dont want to force trying to create a db. showDBMissingWarning( myDatabaseFileName ); return; } // Set up the query to retrieve the projection information needed to populate the list QString mySql = "select description, srs_id from vw_srs "; mySql += "where "; mySql += sqlFilter; myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail ); // XXX Need to free memory from the error msg if one is set if ( myResult == SQLITE_OK ) { QTreeWidgetItem *newItem; while ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW ) { newItem = new QTreeWidgetItem( mUserProjList, QStringList( QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) ) ) ); // EpsgCrsId for user projections is not always defined in some dbases. // It's also not written from customprojections dialog. // display the epsg (field 2) in the second column of the list view // newItem->setText( EPSG_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 2 ) ) ); // display the qgis srs_id (field 1) in the third column of the list view newItem->setText( QGIS_CRS_ID_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 1 ) ) ); } } // close the sqlite3 statement sqlite3_finalize( myPreparedStatement ); sqlite3_close( myDatabase ); mUserProjListDone = TRUE; }
long QgsProjectionSelector::getSelectedLongAttribute( QString attributeName ) { // Only return the attribute if there is a node in the tree // selected that has an srs_id. This prevents error if the user // selects a top-level node rather than an actual coordinate // system // // Get the selected node QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem(); if ( lvi ) { // Make sure the selected node is a srs and not a top-level projection node if ( lvi->text( QGIS_CRS_ID_COLUMN ).length() > 0 ) { QString myDatabaseFileName; // // Determine if this is a user projection or a system on // user projection defs all have srs_id >= 100000 // if ( lvi->text( QGIS_CRS_ID_COLUMN ).toLong() >= USER_CRS_START_ID ) { myDatabaseFileName = QgsApplication::qgisUserDbFilePath(); QFileInfo myFileInfo; myFileInfo.setFile( myDatabaseFileName ); if ( !myFileInfo.exists( ) ) { QgsDebugMsg( " Projection selector : users qgis.db not found" ); return 0; } } else //must be a system projection then { myDatabaseFileName = mSrsDatabaseFileName; } // // set up the database // XXX We could probabaly hold the database open for the life of this object, // assuming that it will never be used anywhere else. Given the low overhead, // opening it each time seems to be a reasonable approach at this time. sqlite3 *db; int rc; rc = sqlite3_open( myDatabaseFileName.toUtf8().data(), &db ); if ( rc ) { showDBMissingWarning( myDatabaseFileName ); return 0; } // prepare the sql statement const char *pzTail; sqlite3_stmt *ppStmt; QString sql = "select "; sql += attributeName; sql += " from tbl_srs where srs_id = "; sql += lvi->text( QGIS_CRS_ID_COLUMN ); QgsDebugMsg( QString( "Finding selected attribute using : %1" ).arg( sql ) ); rc = sqlite3_prepare( db, sql.toUtf8(), sql.length(), &ppStmt, &pzTail ); // XXX Need to free memory from the error msg if one is set QString myAttributeValue; if ( rc == SQLITE_OK ) { // get the first row of the result set if ( sqlite3_step( ppStmt ) == SQLITE_ROW ) { // get the attribute myAttributeValue = QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 0 ) ); } } // close the statement sqlite3_finalize( ppStmt ); // close the database sqlite3_close( db ); // return the srs wkt return myAttributeValue.toLong(); } } // No node is selected, return null return 0; }
// Returns the whole proj4 string for the selected projection node QString QgsProjectionSelector::selectedProj4String() { // Only return the projection if there is a node in the tree // selected that has an srid. This prevents error if the user // selects a top-level node rather than an actual coordinate // system // // Get the selected node QTreeWidgetItem *myItem = lstCoordinateSystems->currentItem(); if ( myItem ) { if ( myItem->text( QGIS_CRS_ID_COLUMN ).length() > 0 ) { QString myDatabaseFileName; QString mySrsId = myItem->text( QGIS_CRS_ID_COLUMN ); QgsDebugMsg( "mySrsId = " + mySrsId ); QgsDebugMsg( "USER_CRS_START_ID = " + QString::number( USER_CRS_START_ID ) ); // // Determine if this is a user projection or a system on // user projection defs all have srs_id >= 100000 // if ( mySrsId.toLong() >= USER_CRS_START_ID ) { myDatabaseFileName = QgsApplication::qgisUserDbFilePath(); QFileInfo myFileInfo; myFileInfo.setFile( myDatabaseFileName ); if ( !myFileInfo.exists( ) ) //its unlikely that this condition will ever be reached { QgsDebugMsg( "users qgis.db not found" ); return QString( "" ); } else { QgsDebugMsg( "users qgis.db found" ); } } else //must be a system projection then { myDatabaseFileName = mSrsDatabaseFileName; } QgsDebugMsg( "db = " + myDatabaseFileName ); sqlite3 *db; int rc; rc = sqlite3_open( myDatabaseFileName.toUtf8().data(), &db ); if ( rc ) { showDBMissingWarning( myDatabaseFileName ); return QString( "" ); } // prepare the sql statement const char *pzTail; sqlite3_stmt *ppStmt; QString sql = "select parameters from tbl_srs where srs_id = "; sql += mySrsId; QgsDebugMsg( "Selection sql: " + sql ); rc = sqlite3_prepare( db, sql.toUtf8(), sql.length(), &ppStmt, &pzTail ); // XXX Need to free memory from the error msg if one is set QString myProjString; if ( rc == SQLITE_OK ) { if ( sqlite3_step( ppStmt ) == SQLITE_ROW ) { myProjString = QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 0 ) ); } } // close the statement sqlite3_finalize( ppStmt ); // close the database sqlite3_close( db ); assert( myProjString.length() > 0 ); return myProjString; } else { // No node is selected, return null return QString( "" ); } } else { // No node is selected, return null return QString( "" ); } }