00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <qgsprojectionselector.h>
00013
00014
00015 #include <cassert>
00016 #include <sqlite3.h>
00017
00018
00019 #include "qgis.h"
00020 #include "qgsapplication.h"
00021 #include "qgslogger.h"
00022 #include <qgscoordinatereferencesystem.h>
00023
00024
00025 #include <QDir>
00026 #include <QFileInfo>
00027 #include <QTextStream>
00028 #include <QHeaderView>
00029 #include <QResizeEvent>
00030 #include <QMessageBox>
00031 #include <QSettings>
00032 #include "qgslogger.h"
00033
00034 const int NAME_COLUMN = 0;
00035 const int AUTHID_COLUMN = 1;
00036 const int QGIS_CRS_ID_COLUMN = 2;
00037
00038 QgsProjectionSelector::QgsProjectionSelector( QWidget* parent, const char * name, Qt::WFlags fl )
00039 : QWidget( parent, fl )
00040 , mProjListDone( false )
00041 , mUserProjListDone( false )
00042 , mCRSNameSelectionPending( false )
00043 , mCRSIDSelectionPending( false )
00044 , mAuthIDSelectionPending( false )
00045 {
00046 setupUi( this );
00047 connect( lstCoordinateSystems, SIGNAL( currentItemChanged( QTreeWidgetItem*, QTreeWidgetItem* ) ),
00048 this, SLOT( coordinateSystemSelected( QTreeWidgetItem* ) ) );
00049
00050
00051 mSrsDatabaseFileName = QgsApplication::srsDbFilePath();
00052 lstCoordinateSystems->header()->setResizeMode( AUTHID_COLUMN, QHeaderView::Stretch );
00053 lstCoordinateSystems->header()->resizeSection( QGIS_CRS_ID_COLUMN, 0 );
00054 lstCoordinateSystems->header()->setResizeMode( QGIS_CRS_ID_COLUMN, QHeaderView::Fixed );
00055
00056 lstRecent->header()->setResizeMode( AUTHID_COLUMN, QHeaderView::Stretch );
00057 lstRecent->header()->resizeSection( QGIS_CRS_ID_COLUMN, 0 );
00058 lstRecent->header()->setResizeMode( QGIS_CRS_ID_COLUMN, QHeaderView::Fixed );
00059
00060 cbxAuthority->addItem( tr( "All" ) );
00061 cbxAuthority->addItems( authorities() );
00062
00063
00064 QSettings settings;
00065 mRecentProjections = settings.value( "/UI/recentProjections" ).toStringList();
00066
00067
00068
00069 QStringList projectionsEpsg = settings.value( "/UI/recentProjectionsEpsg" ).toStringList();
00070 QStringList projectionsProj4 = settings.value( "/UI/recentProjectionsProj4" ).toStringList();
00071 if ( projectionsEpsg.size() >= mRecentProjections.size() )
00072 {
00073
00074
00075 QgsDebugMsg( "Use popular projection list from EPSG/Proj4 saved state" );
00076 mRecentProjections.clear();
00077 for ( int i = 0; i < projectionsEpsg.size(); i++ )
00078 {
00079
00080 QgsCoordinateReferenceSystem crs( projectionsEpsg.at( i ).toLong(), QgsCoordinateReferenceSystem::EpsgCrsId );
00081 if ( ! crs.isValid() )
00082 {
00083
00084 if ( ! crs.createFromProj4( projectionsProj4.at( i ) ) )
00085 {
00086
00087 continue;
00088 }
00089 }
00090 mRecentProjections << QString::number( crs.srsid() );
00091 }
00092 }
00093 }
00094
00095
00096 QgsProjectionSelector::~QgsProjectionSelector()
00097 {
00098
00099 QSettings settings;
00100 long crsId;
00101
00102
00103 crsId = selectedCrsId();
00104 if ( crsId )
00105 {
00106 mRecentProjections.removeAll( QString::number( crsId ) );
00107 mRecentProjections.prepend( QString::number( crsId ) );
00108
00109 while ( mRecentProjections.size() > 4 )
00110 {
00111 mRecentProjections.removeLast();
00112 }
00113
00114 settings.setValue( "/UI/recentProjections", mRecentProjections );
00115
00116
00117
00118 QStringList projectionsEpsg;
00119 QStringList projectionsProj4;
00120 for ( int i = 0; i < mRecentProjections.size(); i++ )
00121 {
00122
00123 QgsCoordinateReferenceSystem crs( mRecentProjections.at( i ).toLong(), QgsCoordinateReferenceSystem::InternalCrsId );
00124 if ( ! crs.isValid() )
00125 {
00126
00127 continue;
00128 }
00129 projectionsEpsg << QString::number( crs.epsg() );
00130 projectionsProj4 << crs.toProj4();
00131 }
00132 settings.setValue( "/UI/recentProjectionsEpsg", projectionsEpsg );
00133 settings.setValue( "/UI/recentProjectionsProj4", projectionsProj4 );
00134 }
00135 }
00136
00137
00138 void QgsProjectionSelector::resizeEvent( QResizeEvent * theEvent )
00139 {
00140 lstCoordinateSystems->header()->resizeSection( NAME_COLUMN, theEvent->size().width() - 240 );
00141 lstCoordinateSystems->header()->resizeSection( AUTHID_COLUMN, 240 );
00142 lstCoordinateSystems->header()->resizeSection( QGIS_CRS_ID_COLUMN, 0 );
00143
00144 lstRecent->header()->resizeSection( NAME_COLUMN, theEvent->size().width() - 240 );
00145 lstRecent->header()->resizeSection( AUTHID_COLUMN, 240 );
00146 lstRecent->header()->resizeSection( QGIS_CRS_ID_COLUMN, 0 );
00147 }
00148
00149 void QgsProjectionSelector::showEvent( QShowEvent * theEvent )
00150 {
00151
00152
00153
00154 if ( !mProjListDone )
00155 {
00156 loadCrsList( &mCrsFilter );
00157 }
00158
00159 if ( !mUserProjListDone )
00160 {
00161 loadUserCrsList( &mCrsFilter );
00162 }
00163
00164
00165
00166 if ( mCRSNameSelectionPending )
00167 {
00168 applyCRSNameSelection();
00169 }
00170 if ( mCRSIDSelectionPending )
00171 {
00172 applyCRSIDSelection();
00173 }
00174 if ( mAuthIDSelectionPending )
00175 {
00176 applyAuthIDSelection();
00177 }
00178
00179 for ( int i = mRecentProjections.size() - 1; i >= 0; i-- )
00180 insertRecent( mRecentProjections.at( i ).toLong() );
00181
00182
00183 QWidget::showEvent( theEvent );
00184 }
00185
00186 QString QgsProjectionSelector::ogcWmsCrsFilterAsSqlExpression( QSet<QString> * crsFilter )
00187 {
00188 QString sqlExpression = "1";
00189 QMap<QString, QStringList> authParts;
00190
00191 if ( !crsFilter )
00192 {
00193 return sqlExpression;
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 foreach( QString auth_id, crsFilter->values() )
00215 {
00216 QStringList parts = auth_id.split( ":" );
00217
00218 if ( parts.size() < 2 )
00219 continue;
00220
00221 authParts[ parts.at( 0 ).toUpper()].append( parts.at( 1 ).toUpper() );
00222 }
00223
00224 if ( authParts.isEmpty() )
00225 return sqlExpression;
00226
00227 if ( authParts.size() > 0 )
00228 {
00229 QString prefix = " AND (";
00230 foreach( QString auth_name, authParts.keys() )
00231 {
00232 sqlExpression += QString( "%1(upper(auth_name)='%2' AND upper(auth_id) IN ('%3'))" )
00233 .arg( prefix )
00234 .arg( auth_name )
00235 .arg( authParts[auth_name].join( "','" ) );
00236 prefix = " OR ";
00237 }
00238 sqlExpression += ")";
00239 }
00240
00241 QgsDebugMsg( "exiting with '" + sqlExpression + "'." );
00242
00243 return sqlExpression;
00244 }
00245
00246
00247 void QgsProjectionSelector::setSelectedCrsName( QString theCRSName )
00248 {
00249 mCRSNameSelection = theCRSName;
00250 mCRSNameSelectionPending = true;
00251 mCRSIDSelectionPending = false;
00252 mAuthIDSelectionPending = true;
00253
00254 if ( isVisible() )
00255 {
00256 applyCRSNameSelection();
00257 }
00258
00259
00260
00261 }
00262
00263
00264 void QgsProjectionSelector::setSelectedCrsId( long theCRSID )
00265 {
00266 mCRSIDSelection = theCRSID;
00267 mCRSIDSelectionPending = true;
00268 mCRSNameSelectionPending = false;
00269 mAuthIDSelectionPending = false;
00270
00271 if ( isVisible() )
00272 {
00273 applyCRSIDSelection();
00274 }
00275
00276
00277
00278 }
00279
00280 void QgsProjectionSelector::setSelectedEpsg( long id )
00281 {
00282 setSelectedAuthId( QString( "EPSG:%1" ).arg( id ) );
00283 }
00284
00285 void QgsProjectionSelector::setSelectedAuthId( QString id )
00286 {
00287 mAuthIDSelection = id;
00288 mCRSIDSelectionPending = false;
00289 mAuthIDSelectionPending = true;
00290 mCRSNameSelectionPending = false;
00291 }
00292
00293 void QgsProjectionSelector::applyCRSNameSelection()
00294 {
00295 if (
00296 mCRSNameSelectionPending &&
00297 mProjListDone &&
00298 mUserProjListDone
00299 )
00300 {
00301
00302 QgsDebugMsg( "called with " + mCRSNameSelection );
00303 QList<QTreeWidgetItem*> nodes = lstCoordinateSystems->findItems( mCRSNameSelection, Qt::MatchExactly | Qt::MatchRecursive, 0 );
00304
00305 if ( nodes.count() > 0 )
00306 {
00307 lstCoordinateSystems->setCurrentItem( nodes.first() );
00308 lstCoordinateSystems->scrollToItem( nodes.first() );
00309 }
00310 else
00311 {
00312 lstCoordinateSystems->clearSelection();
00313 teProjection->setText( "" );
00314 }
00315
00316 mCRSNameSelectionPending = false;
00317 }
00318 }
00319
00320 void QgsProjectionSelector::insertRecent( long theCrsId )
00321 {
00322 if ( !mProjListDone || !mUserProjListDone )
00323 return;
00324
00325 QList<QTreeWidgetItem*> nodes = lstCoordinateSystems->findItems( QString::number( theCrsId ), Qt::MatchExactly | Qt::MatchRecursive, QGIS_CRS_ID_COLUMN );
00326
00327 if ( nodes.count() == 0 )
00328 return;
00329
00330 lstRecent->insertTopLevelItem( 0, new QTreeWidgetItem( lstRecent, QStringList()
00331 << nodes.first()->text( NAME_COLUMN )
00332 << nodes.first()->text( AUTHID_COLUMN )
00333 << nodes.first()->text( QGIS_CRS_ID_COLUMN ) ) );
00334 }
00335
00336 void QgsProjectionSelector::applyAuthIDSelection()
00337 {
00338 if ( mAuthIDSelectionPending && mProjListDone && mUserProjListDone )
00339 {
00340
00341 QgsDebugMsg( "called with " + mAuthIDSelection );
00342 QList<QTreeWidgetItem*> nodes = lstCoordinateSystems->findItems( mAuthIDSelection, Qt::MatchExactly | Qt::MatchRecursive, AUTHID_COLUMN );
00343
00344 if ( nodes.count() > 0 )
00345 {
00346 lstCoordinateSystems->setCurrentItem( nodes.first() );
00347 lstCoordinateSystems->scrollToItem( nodes.first() );
00348 }
00349 else
00350 {
00351 lstCoordinateSystems->clearSelection();
00352 teProjection->setText( "" );
00353 }
00354
00355 mAuthIDSelectionPending = false;
00356 }
00357 }
00358
00359 void QgsProjectionSelector::applyCRSIDSelection()
00360 {
00361 if ( mCRSIDSelectionPending && mProjListDone && mUserProjListDone )
00362 {
00363 QString myCRSIDString = QString::number( mCRSIDSelection );
00364
00365 QList<QTreeWidgetItem*> nodes = lstCoordinateSystems->findItems( myCRSIDString, Qt::MatchExactly | Qt::MatchRecursive, QGIS_CRS_ID_COLUMN );
00366
00367 if ( nodes.count() > 0 )
00368 {
00369 lstCoordinateSystems->setCurrentItem( nodes.first() );
00370 lstCoordinateSystems->scrollToItem( nodes.first() );
00371 }
00372 else
00373 {
00374 lstCoordinateSystems->clearSelection();
00375 teProjection->setText( "" );
00376 }
00377
00378 mCRSIDSelectionPending = false;
00379 }
00380 }
00381
00382
00383
00384 QString QgsProjectionSelector::selectedName()
00385 {
00386
00387 QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
00388 if ( lvi )
00389 {
00390 return lvi->text( 0 );
00391 }
00392 else
00393 {
00394 return QString::null;
00395 }
00396 }
00397
00398 QString QgsProjectionSelector::selectedProj4String()
00399 {
00400
00401
00402
00403
00404
00405
00406 QTreeWidgetItem *myItem = lstCoordinateSystems->currentItem();
00407 if ( myItem )
00408 {
00409
00410 if ( myItem->text( QGIS_CRS_ID_COLUMN ).length() > 0 )
00411 {
00412 QString myDatabaseFileName;
00413 QString mySrsId = myItem->text( QGIS_CRS_ID_COLUMN );
00414
00415 QgsDebugMsg( "mySrsId = " + mySrsId );
00416 QgsDebugMsg( "USER_CRS_START_ID = " + QString::number( USER_CRS_START_ID ) );
00417
00418
00419
00420
00421 if ( mySrsId.toLong() >= USER_CRS_START_ID )
00422 {
00423 myDatabaseFileName = QgsApplication::qgisUserDbFilePath();
00424 QFileInfo myFileInfo;
00425 myFileInfo.setFile( myDatabaseFileName );
00426 if ( !myFileInfo.exists( ) )
00427 {
00428 QgsDebugMsg( "users qgis.db not found" );
00429 return QString( "" );
00430 }
00431 else
00432 {
00433 QgsDebugMsg( "users qgis.db found" );
00434 }
00435 }
00436 else
00437 {
00438 myDatabaseFileName = mSrsDatabaseFileName;
00439 }
00440 QgsDebugMsg( "db = " + myDatabaseFileName );
00441
00442
00443 sqlite3 *db;
00444 int rc;
00445 rc = sqlite3_open( myDatabaseFileName.toUtf8().data(), &db );
00446 if ( rc )
00447 {
00448 showDBMissingWarning( myDatabaseFileName );
00449 return QString( "" );
00450 }
00451
00452 const char *pzTail;
00453 sqlite3_stmt *ppStmt;
00454 QString sql = QString( "select parameters from tbl_srs where srs_id = %1" ).arg( mySrsId );
00455
00456 QgsDebugMsg( "Selection sql: " + sql );
00457
00458 rc = sqlite3_prepare( db, sql.toUtf8(), sql.toUtf8().length(), &ppStmt, &pzTail );
00459
00460 QString myProjString;
00461 if ( rc == SQLITE_OK )
00462 {
00463 if ( sqlite3_step( ppStmt ) == SQLITE_ROW )
00464 {
00465 myProjString = QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 0 ) );
00466 }
00467 }
00468
00469 sqlite3_finalize( ppStmt );
00470
00471 sqlite3_close( db );
00472 assert( myProjString.length() > 0 );
00473 return myProjString;
00474 }
00475 else
00476 {
00477
00478 return QString( "" );
00479 }
00480 }
00481 else
00482 {
00483
00484 return QString( "" );
00485 }
00486
00487 }
00488
00489 QString QgsProjectionSelector::getSelectedExpression( QString expression )
00490 {
00491
00492
00493
00494
00495
00496
00497 QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
00498 if ( lvi )
00499 {
00500
00501 if ( lvi->text( QGIS_CRS_ID_COLUMN ).length() > 0 )
00502 {
00503 QString myDatabaseFileName;
00504
00505
00506
00507
00508 if ( lvi->text( QGIS_CRS_ID_COLUMN ).toLong() >= USER_CRS_START_ID )
00509 {
00510 myDatabaseFileName = QgsApplication::qgisUserDbFilePath();
00511 QFileInfo myFileInfo;
00512 myFileInfo.setFile( myDatabaseFileName );
00513 if ( !myFileInfo.exists( ) )
00514 {
00515 QgsDebugMsg( " Projection selector : users qgis.db not found" );
00516 return 0;
00517 }
00518 }
00519 else
00520 {
00521 myDatabaseFileName = mSrsDatabaseFileName;
00522 }
00523
00524
00525
00526
00527
00528 sqlite3 *db;
00529 int rc;
00530 rc = sqlite3_open( myDatabaseFileName.toUtf8().data(), &db );
00531 if ( rc )
00532 {
00533 showDBMissingWarning( myDatabaseFileName );
00534 return 0;
00535 }
00536
00537 const char *pzTail;
00538 sqlite3_stmt *ppStmt;
00539 QString sql = QString( "select %1 from tbl_srs where srs_id=%2" )
00540 .arg( expression )
00541 .arg( lvi->text( QGIS_CRS_ID_COLUMN ) );
00542
00543 QgsDebugMsg( QString( "Finding selected attribute using : %1" ).arg( sql ) );
00544 rc = sqlite3_prepare( db, sql.toUtf8(), sql.toUtf8().length(), &ppStmt, &pzTail );
00545
00546 QString myAttributeValue;
00547 if ( rc == SQLITE_OK )
00548 {
00549
00550 if ( sqlite3_step( ppStmt ) == SQLITE_ROW )
00551 {
00552
00553 myAttributeValue = QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 0 ) );
00554 }
00555 }
00556
00557 sqlite3_finalize( ppStmt );
00558
00559 sqlite3_close( db );
00560
00561 return myAttributeValue;
00562 }
00563 }
00564
00565
00566 return 0;
00567 }
00568
00569 long QgsProjectionSelector::selectedEpsg()
00570 {
00571 if ( getSelectedExpression( "auth_name" ).compare( "EPSG", Qt::CaseInsensitive ) == 0 )
00572 {
00573 return getSelectedExpression( "auth_id" ).toLong();
00574 }
00575 else
00576 {
00577 QgsDebugMsg( "selected projection is NOT EPSG" );
00578 return 0;
00579 }
00580 }
00581
00582 long QgsProjectionSelector::selectedPostgresSrId()
00583 {
00584 return getSelectedExpression( "srid" ).toLong();
00585 }
00586
00587
00588 QString QgsProjectionSelector::selectedAuthId()
00589 {
00590 return getSelectedExpression( "upper(auth_name||':'||auth_id)" );
00591 }
00592
00593
00594 long QgsProjectionSelector::selectedCrsId()
00595 {
00596 QTreeWidgetItem* item = lstCoordinateSystems->currentItem();
00597
00598 if ( item != NULL && item->text( QGIS_CRS_ID_COLUMN ).length() > 0 )
00599 {
00600 return lstCoordinateSystems->currentItem()->text( QGIS_CRS_ID_COLUMN ).toLong();
00601 }
00602 else
00603 {
00604 return 0;
00605 }
00606 }
00607
00608
00609 void QgsProjectionSelector::setOgcWmsCrsFilter( QSet<QString> crsFilter )
00610 {
00611 mCrsFilter = crsFilter;
00612 mProjListDone = false;
00613 mUserProjListDone = false;
00614 lstCoordinateSystems->clear();
00615 }
00616
00617
00618 void QgsProjectionSelector::loadUserCrsList( QSet<QString> * crsFilter )
00619 {
00620 QgsDebugMsg( "Fetching user projection list..." );
00621
00622
00623 QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter );
00624
00625
00626
00627 mUserProjList = new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr( "User Defined Coordinate Systems" ) ) );
00628
00629 QFont fontTemp = mUserProjList->font( 0 );
00630 fontTemp.setItalic( true );
00631 fontTemp.setBold( true );
00632 mUserProjList->setFont( 0, fontTemp );
00633 mUserProjList->setIcon( 0, QIcon( QgsApplication::activeThemePath() + "user.png" ) );
00634
00635
00636
00637 QString myDatabaseFileName = QgsApplication::qgisUserDbFilePath();
00638
00639
00640 QFileInfo myFileInfo;
00641 myFileInfo.setFile( myDatabaseFileName );
00642
00643 if ( !myFileInfo.exists( ) )
00644 {
00645 QgsDebugMsg( "Users qgis.db not found...skipping" );
00646
00647 mUserProjListDone = true;
00648 return;
00649 }
00650
00651 sqlite3 *myDatabase;
00652 const char *myTail;
00653 sqlite3_stmt *myPreparedStatement;
00654 int myResult;
00655
00656 myResult = sqlite3_open( QString( myDatabaseFileName ).toUtf8().data(), &myDatabase );
00657 if ( myResult )
00658 {
00659
00660
00661
00662
00663 showDBMissingWarning( myDatabaseFileName );
00664 return;
00665 }
00666
00667
00668 QString mySql = QString( "select description, srs_id from vw_srs where %1" ).arg( sqlFilter );
00669
00670 myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
00671
00672 if ( myResult == SQLITE_OK )
00673 {
00674 QTreeWidgetItem *newItem;
00675 while ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
00676 {
00677 newItem = new QTreeWidgetItem( mUserProjList, QStringList( QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) ) ) );
00678
00679
00680
00681
00682
00683 newItem->setText( QGIS_CRS_ID_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 1 ) ) );
00684 }
00685 }
00686
00687 sqlite3_finalize( myPreparedStatement );
00688 sqlite3_close( myDatabase );
00689
00690 mUserProjListDone = true;
00691 }
00692
00693 void QgsProjectionSelector::loadCrsList( QSet<QString> *crsFilter )
00694 {
00695
00696 QString sqlFilter = ogcWmsCrsFilterAsSqlExpression( crsFilter );
00697
00698
00699
00700
00701
00702 mGeoList = new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr( "Geographic Coordinate Systems" ) ) );
00703
00704 QFont fontTemp = mGeoList->font( 0 );
00705 fontTemp.setItalic( true );
00706 fontTemp.setBold( true );
00707 mGeoList->setFont( 0, fontTemp );
00708 mGeoList->setIcon( 0, QIcon( QgsApplication::activeThemePath() + "geographic.png" ) );
00709
00710
00711 mProjList = new QTreeWidgetItem( lstCoordinateSystems, QStringList( tr( "Projected Coordinate Systems" ) ) );
00712
00713 fontTemp = mProjList->font( 0 );
00714 fontTemp.setItalic( true );
00715 fontTemp.setBold( true );
00716 mProjList->setFont( 0, fontTemp );
00717 mProjList->setIcon( 0, QIcon( QgsApplication::activeThemePath() + "transformed.png" ) );
00718
00719
00720
00721
00722
00723
00724 QFileInfo myFileInfo;
00725 myFileInfo.setFile( mSrsDatabaseFileName );
00726 if ( !myFileInfo.exists( ) )
00727 {
00728 mProjListDone = true;
00729 return;
00730 }
00731
00732
00733 sqlite3 *db;
00734 int rc;
00735 rc = sqlite3_open( mSrsDatabaseFileName.toUtf8().data(), &db );
00736 if ( rc )
00737 {
00738
00739
00740 showDBMissingWarning( mSrsDatabaseFileName );
00741 return ;
00742 }
00743
00744 const char *pzTail;
00745 sqlite3_stmt *ppStmt;
00746
00747 QString sql = "select count(*) from tbl_srs";
00748
00749 rc = sqlite3_prepare( db, sql.toUtf8(), sql.toUtf8().length(), &ppStmt, &pzTail );
00750 assert( rc == SQLITE_OK );
00751 sqlite3_step( ppStmt );
00752
00753 sqlite3_finalize( ppStmt );
00754
00755
00756
00757
00758 sql = QString( "select description, srs_id, upper(auth_name||':'||auth_id), is_geo, name, parameters, deprecated from vw_srs where %1 order by name,description" )
00759 .arg( sqlFilter );
00760
00761 rc = sqlite3_prepare( db, sql.toUtf8(), sql.toUtf8().length(), &ppStmt, &pzTail );
00762
00763 if ( rc == SQLITE_OK )
00764 {
00765 QTreeWidgetItem *newItem;
00766
00767
00768 QString previousSrsType( "" );
00769 QTreeWidgetItem* previousSrsTypeNode = NULL;
00770
00771 while ( sqlite3_step( ppStmt ) == SQLITE_ROW )
00772 {
00773
00774 int isGeo = sqlite3_column_int( ppStmt, 3 );
00775 if ( isGeo )
00776 {
00777
00778
00779 newItem = new QTreeWidgetItem( mGeoList, QStringList( QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 0 ) ) ) );
00780
00781
00782 newItem->setText( AUTHID_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 2 ) ) );
00783
00784
00785 newItem->setText( QGIS_CRS_ID_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 1 ) ) );
00786 }
00787 else
00788 {
00789
00790 QTreeWidgetItem *node;
00791 QString srsType = QString::fromUtf8(( char* )sqlite3_column_text( ppStmt, 4 ) );
00792
00793
00794 if ( srsType == previousSrsType )
00795 {
00796 node = previousSrsTypeNode;
00797 }
00798 else
00799 {
00800 QList<QTreeWidgetItem*> nodes = lstCoordinateSystems->findItems( srsType, Qt::MatchExactly | Qt::MatchRecursive, 0 );
00801 if ( nodes.count() == 0 )
00802 {
00803
00804
00805 node = new QTreeWidgetItem( mProjList, QStringList( srsType ) );
00806
00807 QFont fontTemp = node->font( 0 );
00808 fontTemp.setItalic( true );
00809 node->setFont( 0, fontTemp );
00810 }
00811 else
00812 {
00813 node = nodes.first();
00814 }
00815
00816 previousSrsType = srsType;
00817 previousSrsTypeNode = node;
00818 }
00819
00820 newItem = new QTreeWidgetItem( node, QStringList( QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 0 ) ) ) );
00821
00822 newItem->setText( AUTHID_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 2 ) ) );
00823
00824 newItem->setText( QGIS_CRS_ID_COLUMN, QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 1 ) ) );
00825
00826 }
00827
00828
00829 newItem->setData( 0, Qt::UserRole, QString::fromUtf8(( char * )sqlite3_column_text( ppStmt, 6 ) ) );
00830 newItem->setHidden( cbxHideDeprecated->isChecked() );
00831 }
00832 mProjList->setExpanded( true );
00833 }
00834
00835 sqlite3_finalize( ppStmt );
00836
00837 sqlite3_close( db );
00838
00839 mProjListDone = true;
00840 }
00841
00842
00843
00844 void QgsProjectionSelector::coordinateSystemSelected( QTreeWidgetItem * theItem )
00845 {
00846
00847
00848 if ( theItem && theItem->childCount() == 0 )
00849 {
00850
00851 QString myDescription;
00852 emit sridSelected( QString::number( selectedCrsId() ) );
00853 QString myProjString = selectedProj4String();
00854 lstCoordinateSystems->scrollToItem( theItem );
00855 teProjection->setText( myProjString );
00856
00857 lstRecent->clearSelection();
00858 }
00859 else
00860 {
00861
00862 theItem->setSelected( false );
00863 teProjection->setText( "" );
00864 }
00865 }
00866
00867 void QgsProjectionSelector::hideDeprecated( QTreeWidgetItem *item )
00868 {
00869 if ( item->data( 0, Qt::UserRole ).toBool() )
00870 {
00871 item->setHidden( cbxHideDeprecated->isChecked() );
00872 if ( item->isSelected() && item->isHidden() )
00873 {
00874 teProjection->setText( "" );
00875 item->setSelected( false );
00876 }
00877 }
00878
00879 for ( int i = 0; i < item->childCount(); i++ )
00880 hideDeprecated( item->child( i ) );
00881 }
00882
00883 void QgsProjectionSelector::on_cbxHideDeprecated_stateChanged()
00884 {
00885 for ( int i = 0; i < lstCoordinateSystems->topLevelItemCount(); i++ )
00886 hideDeprecated( lstCoordinateSystems->topLevelItem( i ) );
00887 }
00888
00889 void QgsProjectionSelector::on_lstRecent_currentItemChanged( QTreeWidgetItem *current, QTreeWidgetItem *previous )
00890 {
00891 setSelectedCrsId( current->text( QGIS_CRS_ID_COLUMN ).toLong() );
00892 }
00893
00894 void QgsProjectionSelector::on_pbnFind_clicked()
00895 {
00896 QgsDebugMsg( "pbnFind..." );
00897
00898 QString mySearchString( sqlSafeString( leSearch->text() ) );
00899
00900
00901 QString mySql = "select srs_id from tbl_srs where ";
00902 if ( cbxAuthority->currentIndex() > 0 )
00903 {
00904 mySql += QString( "auth_name='%1' AND " ).arg( cbxAuthority->currentText() );
00905 }
00906
00907 if ( cbxHideDeprecated->isChecked() )
00908 {
00909 mySql += "not deprecated AND ";
00910 }
00911
00912 if ( cbxMode->currentIndex() == 0 )
00913 {
00914 mySql += QString( "auth_id='%1'" ).arg( mySearchString );
00915 }
00916 else
00917 {
00918 mySql += "upper(description) like '%" + mySearchString.toUpper() + "%' ";
00919
00920 long myLargestSrsId = getLargestCRSIDMatch( QString( "%1 order by srs_id desc limit 1" ).arg( mySql ) );
00921 QgsDebugMsg( QString( "Largest CRSID%1" ).arg( myLargestSrsId ) );
00922
00923
00924
00925 if ( myLargestSrsId <= selectedCrsId() )
00926 {
00927 mySql = QString( "%1 order by srs_id limit 1" ).arg( mySql );
00928 }
00929 else
00930 {
00931
00932 mySql = QString( "%1 and srs_id > %2 order by srs_id limit 1" ).arg( mySql ).arg( selectedCrsId() );
00933 }
00934 }
00935 QgsDebugMsg( QString( " Search sql: %1" ).arg( mySql ) );
00936
00937
00938
00939
00940
00941 sqlite3 *myDatabase;
00942 const char *myTail;
00943 sqlite3_stmt *myPreparedStatement;
00944 int myResult;
00945
00946 myResult = sqlite3_open( mSrsDatabaseFileName.toUtf8().data(), &myDatabase );
00947 if ( myResult )
00948 {
00949
00950
00951
00952
00953 showDBMissingWarning( mSrsDatabaseFileName );
00954 return;
00955 }
00956
00957 myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
00958
00959 if ( myResult == SQLITE_OK )
00960 {
00961 myResult = sqlite3_step( myPreparedStatement );
00962 if ( myResult == SQLITE_ROW )
00963 {
00964 QString mySrsId = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) );
00965 setSelectedCrsId( mySrsId.toLong() );
00966
00967 sqlite3_finalize( myPreparedStatement );
00968 sqlite3_close( myDatabase );
00969 return;
00970 }
00971 }
00972
00973 QString myDatabaseFileName = QgsApplication::qgisUserDbFilePath();
00974 QFileInfo myFileInfo;
00975 myFileInfo.setFile( myDatabaseFileName );
00976 if ( !myFileInfo.exists( ) )
00977 {
00978 QgsDebugMsg( QString( "%1\nUser db does not exist" ).arg( myDatabaseFileName ) );
00979 return ;
00980 }
00981 myResult = sqlite3_open( myDatabaseFileName.toUtf8().data(), &myDatabase );
00982 if ( myResult )
00983 {
00984 QgsDebugMsg( QString( "Can't open * user * database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
00985
00986 return;
00987 }
00988
00989 myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
00990
00991 if ( myResult == SQLITE_OK )
00992 {
00993 myResult = sqlite3_step( myPreparedStatement );
00994 if ( myResult == SQLITE_ROW )
00995 {
00996 QString mySrsId = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) );
00997 setSelectedCrsId( mySrsId.toLong() );
00998
00999 sqlite3_finalize( myPreparedStatement );
01000 sqlite3_close( myDatabase );
01001 return;
01002 }
01003 }
01004
01005 QMessageBox::information( this, tr( "Find projection" ), tr( "No matching projection found." ) );
01006 lstCoordinateSystems->clearSelection();
01007 teProjection->setText( "" );
01008 }
01009
01010 long QgsProjectionSelector::getLargestCRSIDMatch( QString theSql )
01011 {
01012 long mySrsId = 0;
01013
01014
01015
01016
01017 sqlite3 *myDatabase;
01018 const char *myTail;
01019 sqlite3_stmt *myPreparedStatement;
01020 int myResult;
01021
01022
01023
01024
01025 QString myDatabaseFileName = QgsApplication::qgisUserDbFilePath();
01026 QFileInfo myFileInfo;
01027 myFileInfo.setFile( myDatabaseFileName );
01028 if ( myFileInfo.exists( ) )
01029 {
01030 myResult = sqlite3_open( myDatabaseFileName.toUtf8().data(), &myDatabase );
01031 if ( myResult )
01032 {
01033
01034
01035
01036
01037 showDBMissingWarning( myDatabaseFileName );
01038 return 0;
01039 }
01040 else
01041 {
01042 myResult = sqlite3_prepare( myDatabase, theSql.toUtf8(), theSql.toUtf8().length(), &myPreparedStatement, &myTail );
01043
01044 if ( myResult == SQLITE_OK )
01045 {
01046 myResult = sqlite3_step( myPreparedStatement );
01047 if ( myResult == SQLITE_ROW )
01048 {
01049 QString mySrsIdString = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) );
01050 mySrsId = mySrsIdString.toLong();
01051
01052 sqlite3_finalize( myPreparedStatement );
01053 sqlite3_close( myDatabase );
01054 return mySrsId;
01055 }
01056 }
01057 }
01058 }
01059
01060
01061
01062 myResult = sqlite3_open( mSrsDatabaseFileName.toUtf8().data(), &myDatabase );
01063 if ( myResult )
01064 {
01065 QgsDebugMsg( QString( "Can't open * user * database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
01066
01067 return 0;
01068 }
01069
01070 myResult = sqlite3_prepare( myDatabase, theSql.toUtf8(), theSql.toUtf8().length(), &myPreparedStatement, &myTail );
01071
01072 if ( myResult == SQLITE_OK )
01073 {
01074 myResult = sqlite3_step( myPreparedStatement );
01075 if ( myResult == SQLITE_ROW )
01076 {
01077 QString mySrsIdString = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) );
01078 mySrsId = mySrsIdString.toLong();
01079
01080 sqlite3_finalize( myPreparedStatement );
01081 sqlite3_close( myDatabase );
01082 }
01083 }
01084 return mySrsId;
01085 }
01086
01087 QStringList QgsProjectionSelector::authorities()
01088 {
01089 sqlite3 *myDatabase;
01090 const char *myTail;
01091 sqlite3_stmt *myPreparedStatement;
01092 int myResult;
01093
01094 myResult = sqlite3_open( mSrsDatabaseFileName.toUtf8().data(), &myDatabase );
01095 if ( myResult )
01096 {
01097 QgsDebugMsg( QString( "Can't open * user * database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
01098
01099 return QStringList();
01100 }
01101
01102 QString theSql = "select distinct auth_name from tbl_srs";
01103 myResult = sqlite3_prepare( myDatabase, theSql.toUtf8(), theSql.toUtf8().length(), &myPreparedStatement, &myTail );
01104
01105 QStringList authorities;
01106
01107 if ( myResult == SQLITE_OK )
01108 {
01109 while ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
01110 {
01111 authorities << QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) );
01112 }
01113
01114
01115 sqlite3_finalize( myPreparedStatement );
01116 sqlite3_close( myDatabase );
01117 }
01118
01119 return authorities;
01120 }
01121
01131 const QString QgsProjectionSelector::sqlSafeString( const QString theSQL )
01132 {
01133 QString myRetval = theSQL;
01134 myRetval.replace( "\\", "\\\\" );
01135 myRetval.replace( '\"', "\\\"" );
01136 myRetval.replace( "\'", "\\'" );
01137 myRetval.replace( "%", "\\%" );
01138 return myRetval;
01139 }
01140
01141 void QgsProjectionSelector::showDBMissingWarning( const QString theFileName )
01142 {
01143
01144 QMessageBox::critical( this, tr( "Resource Location Error" ),
01145 tr( "Error reading database file from: \n %1\n"
01146 "Because of this the projection selector will not work..." )
01147 .arg( theFileName ) );
01148 }