src/app/qgscustomprojectiondialog.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           qgscustomprojectiondialog.cpp
00003 
00004                              -------------------
00005     begin                : 2005
00006     copyright            : (C) 2005 by Tim Sutton
00007     email                : tim@linfiniti.com
00008 ***************************************************************************/
00009 
00010 /***************************************************************************
00011  *                                                                         *
00012  *   This program is free software; you can redistribute it and/or modify  *
00013  *   it under the terms of the GNU General Public License as published by  *
00014  *   the Free Software Foundation; either version 2 of the License, or     *
00015  *   (at your option) any later version.                                   *
00016  *                                                                         *
00017  ***************************************************************************/
00018 
00019 #include "qgscustomprojectiondialog.h"
00020 
00021 //qgis includes
00022 #include "qgis.h" //<--magick numbers
00023 #include "qgisapp.h" //<--theme icons
00024 #include "qgsapplication.h"
00025 #include "qgslogger.h"
00026 
00027 //qt includes
00028 #include <QFileInfo>
00029 #include <QMessageBox>
00030 
00031 //stdc++ includes
00032 #include <cassert>
00033 #include <fstream>
00034 #include <sqlite3.h>
00035 #include "qgslogger.h"
00036 
00037 //proj4 includes
00038 extern "C"
00039 {
00040 #include <proj_api.h>
00041 }
00042 
00043 
00044 QgsCustomProjectionDialog::QgsCustomProjectionDialog( QWidget *parent, Qt::WFlags fl )
00045     : QDialog( parent, fl )
00046 {
00047   setupUi( this );
00048 
00049   pbnFirst->setIcon( QgisApp::getThemeIcon( "mIconFirst.png" ) );
00050   pbnPrevious->setIcon( QgisApp::getThemeIcon( "mIconPrevious.png" ) );
00051   pbnNext->setIcon( QgisApp::getThemeIcon( "mIconNext.png" ) );
00052   pbnLast->setIcon( QgisApp::getThemeIcon( "mIconLast.png" ) );
00053   pbnNew->setIcon( QgisApp::getThemeIcon( "mIconNew.png" ) );
00054   pbnSave->setIcon( QgisApp::getThemeIcon( "mActionFileSave.png" ) );
00055   pbnDelete->setIcon( QgisApp::getThemeIcon( "mIconDelete.png" ) );
00056   // user database is created at QGIS startup in QgisApp::createDB
00057   // we just check whether there is our database [MD]
00058   QFileInfo myFileInfo;
00059   myFileInfo.setFile( QgsApplication::qgisSettingsDirPath() );
00060   if ( !myFileInfo.exists( ) )
00061   {
00062     QgsDebugMsg( "The qgis.db does not exist" );
00063   }
00064 
00065   //
00066   // Setup member vars
00067   //
00068   mCurrentRecordId = "";
00069 
00070   //
00071   // Set up databound controls
00072   //
00073 
00074   // deprecated methods
00075   //getProjList();
00076   //getEllipsoidList();
00077   mRecordCountLong = getRecordCount();
00078   if ( mRecordCountLong > 0 )
00079     on_pbnFirst_clicked();
00080   else
00081     on_pbnNew_clicked();
00082   //automatically go to insert mode if there are not recs yet
00083   if ( mRecordCountLong < 1 )
00084   {
00085     on_pbnNew_clicked();
00086   }
00087 }
00088 
00089 QgsCustomProjectionDialog::~QgsCustomProjectionDialog()
00090 {
00091 
00092 }
00093 /*
00094  * These two methods will be deprecated
00095  *
00096 void QgsCustomProjectionDialog::getProjList ()
00097 {
00098   //
00099   // Populate the projection combo
00100   //
00101   sqlite3      *myDatabase;
00102   const char   *myTail;
00103   sqlite3_stmt *myPreparedStatement;
00104   int           myResult;
00105   //check the db is available
00106   myResult = sqlite3_open(QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase);
00107   if(myResult!=SQLITE_OK)
00108   {
00109     QgsDebugMsg(QString("Can't open database: %1").arg(sqlite3_errmsg(myDatabase)));
00110     // XXX This will likely never happen since on open, sqlite creates the
00111     //     database if it does not exist.
00112     assert(myResult == SQLITE_OK);
00113   }
00114   // Set up the query to retrieve the projection information needed to populate the CRS list
00115   QString mySql = "select * from tbl_projection order by name";
00116   myResult = sqlite3_prepare(myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail);
00117   // XXX Need to free memory from the error msg if one is set
00118   if(myResult == SQLITE_OK)
00119   {
00120     while(sqlite3_step(myPreparedStatement) == SQLITE_ROW)
00121     {
00122       cboProjectionFamily->insertItem(QString::fromUtf8((char *)sqlite3_column_text(myPreparedStatement,1)));
00123     }
00124   }
00125   sqlite3_finalize(myPreparedStatement);
00126   sqlite3_close(myDatabase);
00127 }
00128 
00129 void QgsCustomProjectionDialog::getEllipsoidList()
00130 {
00131 
00132   //
00133   // Populate the ellipsoid combo
00134   //
00135   sqlite3      *myDatabase;
00136   const char   *myTail;
00137   sqlite3_stmt *myPreparedStatement;
00138   int           myResult;
00139   //check the db is available
00140   myResult = sqlite3_open(QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase);
00141   if(myResult!=SQLITE_OK)
00142   {
00143     QgsDebugMsg(QString("Can't open database: %1").arg(sqlite3_errmsg(myDatabase)));
00144     // XXX This will likely never happen since on open, sqlite creates the
00145     //     database if it does not exist.
00146     assert(myResult == SQLITE_OK);
00147   }
00148   // Set up the query to retrieve the projection information needed to populate the ELLIPSOID list
00149   QString mySql = "select * from tbl_ellipsoid order by name";
00150   myResult = sqlite3_prepare(myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail);
00151   // XXX Need to free memory from the error msg if one is set
00152   if(myResult == SQLITE_OK)
00153   {
00154     while(sqlite3_step(myPreparedStatement) == SQLITE_ROW)
00155     {
00156       cboEllipsoid->insertItem(QString::fromUtf8((char *)sqlite3_column_text(myPreparedStatement,1)));
00157     }
00158   }
00159   // close the sqlite3 statement
00160   sqlite3_finalize(myPreparedStatement);
00161   sqlite3_close(myDatabase);
00162 }
00163 */
00164 
00165 void QgsCustomProjectionDialog::on_pbnDelete_clicked()
00166 {
00167 
00168   if ( QMessageBox::Ok != QMessageBox::warning(
00169          this,
00170          tr( "Delete Projection Definition?" ),
00171          tr( "Deleting a projection definition is not reversable. Do you want to delete it?" ),
00172          QMessageBox::Ok | QMessageBox::Cancel ) )
00173   {
00174     return ;
00175   }
00176 
00177   sqlite3      *myDatabase;
00178   const char   *myTail;
00179   sqlite3_stmt *myPreparedStatement;
00180   int           myResult;
00181   QString       myName;
00182   //check the db is available
00183   myResult = sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase );
00184   if ( myResult != SQLITE_OK )
00185   {
00186     QgsDebugMsg( QString( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
00187     // XXX This will likely never happen since on open, sqlite creates the
00188     //     database if it does not exist.
00189     assert( myResult == SQLITE_OK );
00190   }
00191   // Set up the query to retrieve the projection information needed to populate the ELLIPSOID list
00192   QString mySql = "delete from tbl_srs where srs_id='" + mCurrentRecordId + "'";
00193   myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail );
00194   // XXX Need to free memory from the error msg if one is set
00195   QgsDebugMsg( QString( "Query to delete current:%1" ).arg( mySql ) );
00196   if ( myResult == SQLITE_OK )
00197   {
00198     sqlite3_step( myPreparedStatement );
00199   }
00200   // close the sqlite3 statement
00201   sqlite3_finalize( myPreparedStatement );
00202   sqlite3_close( myDatabase );
00203   //move to an appropriate rec now this one is gone
00204   --mRecordCountLong;
00205   if ( mRecordCountLong < 1 )
00206   {
00207     on_pbnNew_clicked();
00208   }
00209   else if ( mCurrentRecordLong == 1 )
00210   {
00211     on_pbnFirst_clicked();
00212   }
00213   else if ( mCurrentRecordLong > mRecordCountLong )
00214   {
00215     on_pbnLast_clicked();
00216   }
00217   else
00218   {
00219     mCurrentRecordLong = mCurrentRecordLong - 2;
00220     on_pbnNext_clicked();
00221   }
00222   return ;
00223 }
00224 
00225 void QgsCustomProjectionDialog::on_pbnClose_clicked()
00226 {
00227   close();
00228 }
00229 
00230 
00231 
00232 
00233 long QgsCustomProjectionDialog::getRecordCount()
00234 {
00235   sqlite3      *myDatabase;
00236   const char   *myTail;
00237   sqlite3_stmt *myPreparedStatement;
00238   int           myResult;
00239   long          myRecordCount = 0;
00240   //check the db is available
00241   myResult = sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase );
00242   if ( myResult != SQLITE_OK )
00243   {
00244     QgsDebugMsg( QString( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
00245     // XXX This will likely never happen since on open, sqlite creates the
00246     //     database if it does not exist.
00247     assert( myResult == SQLITE_OK );
00248   }
00249   // Set up the query to retrieve the projection information needed to populate the ELLIPSOID list
00250   QString mySql = "select count(*) from tbl_srs";
00251   myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail );
00252   // XXX Need to free memory from the error msg if one is set
00253   if ( myResult == SQLITE_OK )
00254   {
00255     if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
00256     {
00257       QString myRecordCountString = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) );
00258       myRecordCount = myRecordCountString.toLong();
00259     }
00260   }
00261   // close the sqlite3 statement
00262   sqlite3_finalize( myPreparedStatement );
00263   sqlite3_close( myDatabase );
00264   return myRecordCount;
00265 
00266 }
00267 
00268 QString QgsCustomProjectionDialog::getProjectionFamilyName( QString theProjectionFamilyAcronym )
00269 {
00270   sqlite3      *myDatabase;
00271   const char   *myTail;
00272   sqlite3_stmt *myPreparedStatement;
00273   int           myResult;
00274   QString       myName;
00275   //check the db is available
00276   myResult = sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase );
00277   if ( myResult != SQLITE_OK )
00278   {
00279     QgsDebugMsg( QString( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
00280     // XXX This will likely never happen since on open, sqlite creates the
00281     //     database if it does not exist.
00282     assert( myResult == SQLITE_OK );
00283   }
00284   // Set up the query to retrieve the projection information needed to populate the ELLIPSOID list
00285   QString mySql = "select name from tbl_projection where acronym='" + theProjectionFamilyAcronym + "'";
00286   myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail );
00287   // XXX Need to free memory from the error msg if one is set
00288   if ( myResult == SQLITE_OK )
00289   {
00290     if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
00291       myName = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) );
00292   }
00293   // close the sqlite3 statement
00294   sqlite3_finalize( myPreparedStatement );
00295   sqlite3_close( myDatabase );
00296   return myName;
00297 
00298 }
00299 QString QgsCustomProjectionDialog::getEllipsoidName( QString theEllipsoidAcronym )
00300 {
00301   sqlite3      *myDatabase;
00302   const char   *myTail;
00303   sqlite3_stmt *myPreparedStatement;
00304   int           myResult;
00305   QString       myName;
00306   //check the db is available
00307   myResult = sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase );
00308   if ( myResult != SQLITE_OK )
00309   {
00310     QgsDebugMsg( QString( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
00311     // XXX This will likely never happen since on open, sqlite creates the
00312     //     database if it does not exist.
00313     assert( myResult == SQLITE_OK );
00314   }
00315   // Set up the query to retrieve the projection information needed to populate the ELLIPSOID list
00316   QString mySql = "select name from tbl_ellipsoid where acronym='" + theEllipsoidAcronym + "'";
00317   myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail );
00318   // XXX Need to free memory from the error msg if one is set
00319   if ( myResult == SQLITE_OK )
00320   {
00321     if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
00322       myName = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) );
00323   }
00324   // close the sqlite3 statement
00325   sqlite3_finalize( myPreparedStatement );
00326   sqlite3_close( myDatabase );
00327   return myName;
00328 
00329 }
00330 QString QgsCustomProjectionDialog::getProjectionFamilyAcronym( QString theProjectionFamilyName )
00331 {
00332   sqlite3      *myDatabase;
00333   const char   *myTail;
00334   sqlite3_stmt *myPreparedStatement;
00335   int           myResult;
00336   QString       myName;
00337   //check the db is available
00338   myResult = sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase );
00339   if ( myResult != SQLITE_OK )
00340   {
00341     QgsDebugMsg( QString( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
00342     // XXX This will likely never happen since on open, sqlite creates the
00343     //     database if it does not exist.
00344     assert( myResult == SQLITE_OK );
00345   }
00346   // Set up the query to retrieve the projection information needed to populate the ELLIPSOID list
00347   QString mySql = "select acronym from tbl_projection where name='" + theProjectionFamilyName + "'";
00348   myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail );
00349   // XXX Need to free memory from the error msg if one is set
00350   if ( myResult == SQLITE_OK )
00351   {
00352     if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
00353       myName = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) );
00354   }
00355   // close the sqlite3 statement
00356   sqlite3_finalize( myPreparedStatement );
00357   sqlite3_close( myDatabase );
00358   return myName;
00359 
00360 }
00361 QString QgsCustomProjectionDialog::getEllipsoidAcronym( QString theEllipsoidName )
00362 {
00363   sqlite3      *myDatabase;
00364   const char   *myTail;
00365   sqlite3_stmt *myPreparedStatement;
00366   int           myResult;
00367   QString       myName;
00368   //check the db is available
00369   myResult = sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase );
00370   if ( myResult != SQLITE_OK )
00371   {
00372     QgsDebugMsg( QString( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
00373     // XXX This will likely never happen since on open, sqlite creates the
00374     //     database if it does not exist.
00375     assert( myResult == SQLITE_OK );
00376   }
00377   // Set up the query to retrieve the projection information needed to populate the ELLIPSOID list
00378   QString mySql = "select acronym from tbl_ellipsoid where name='" + theEllipsoidName + "'";
00379   myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail );
00380   // XXX Need to free memory from the error msg if one is set
00381   if ( myResult == SQLITE_OK )
00382   {
00383     if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
00384       myName = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) );
00385   }
00386   // close the sqlite3 statement
00387   sqlite3_finalize( myPreparedStatement );
00388   sqlite3_close( myDatabase );
00389   return myName;
00390 
00391 }
00392 
00393 void QgsCustomProjectionDialog::on_pbnFirst_clicked()
00394 {
00395   QgsDebugMsg( "entered." );
00396   sqlite3      *myDatabase;
00397   const char   *myTail;
00398   sqlite3_stmt *myPreparedStatement;
00399   int           myResult;
00400   //check the db is available
00401   myResult = sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase );
00402   if ( myResult != SQLITE_OK )
00403   {
00404     QgsDebugMsg( QString( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
00405     // XXX This will likely never happen since on open, sqlite creates the
00406     //     database if it does not exist.
00407     assert( myResult == SQLITE_OK );
00408   }
00409 
00410   QString mySql = "select * from tbl_srs order by srs_id limit 1";
00411   QgsDebugMsg( QString( "Query to move first:%1" ).arg( mySql ) );
00412   myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail );
00413   // XXX Need to free memory from the error msg if one is set
00414   if ( myResult == SQLITE_OK )
00415   {
00416     if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
00417     {
00418       mCurrentRecordId = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) );
00419       leName->setText( QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 1 ) ) );
00420       //QString myProjectionFamilyId = QString::fromUtf8((char *)sqlite3_column_text(myPreparedStatement,2));
00421       //cboProjectionFamily->setCurrentText(getProjectionFamilyName(myProjectionFamilyId));
00422       //QString myEllipsoidId = QString::fromUtf8((char *)sqlite3_column_text(myPreparedStatement,3));
00423       //cboEllipsoid->setCurrentText(getEllipsoidName(myEllipsoidId));
00424       leParameters->setText( QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 4 ) ) );
00425       mCurrentRecordLong = 1;
00426       lblRecordNo->setText( QString::number( mCurrentRecordLong ) + " of " + QString::number( mRecordCountLong ) );
00427     }
00428   }
00429   else
00430   {
00431     QgsDebugMsg( QString( "pbnFirst query failed: %1" ).arg( mySql ) );
00432 
00433   }
00434   sqlite3_finalize( myPreparedStatement );
00435   sqlite3_close( myDatabase );
00436 
00437   //enable nav buttons as appropriate
00438   pbnFirst->setEnabled( false );
00439   pbnPrevious->setEnabled( false );
00440   //automatically go to insert mode if there are not recs yet
00441   if ( mRecordCountLong < 1 )
00442   {
00443     on_pbnNew_clicked();
00444     pbnDelete->setEnabled( false );
00445   }
00446   else if ( mCurrentRecordLong == mRecordCountLong )
00447   {
00448     pbnNext->setEnabled( false );
00449     pbnLast->setEnabled( false );
00450     pbnDelete->setEnabled( true );
00451   }
00452   else
00453   {
00454     pbnNext->setEnabled( true );
00455     pbnLast->setEnabled( true );
00456     pbnDelete->setEnabled( true );
00457   }
00458 }
00459 
00460 
00461 void QgsCustomProjectionDialog::on_pbnPrevious_clicked()
00462 {
00463   QgsDebugMsg( "entered." );
00464   if ( mCurrentRecordLong <= 1 )
00465   {
00466     return;
00467   }
00468   sqlite3      *myDatabase;
00469   const char   *myTail;
00470   sqlite3_stmt *myPreparedStatement;
00471   int           myResult;
00472   //check the db is available
00473   myResult = sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase );
00474   if ( myResult != SQLITE_OK )
00475   {
00476     QgsDebugMsg( QString( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
00477     // XXX This will likely never happen since on open, sqlite creates the
00478     //     database if it does not exist.
00479     assert( myResult == SQLITE_OK );
00480   }
00481 
00482   QString mySql = "select * from tbl_srs where srs_id < " + mCurrentRecordId + " order by srs_id desc limit 1";
00483   QgsDebugMsg( QString( "Query to move previous:%1" ).arg( mySql ) );
00484   myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail );
00485   // XXX Need to free memory from the error msg if one is set
00486   if ( myResult == SQLITE_OK )
00487   {
00488     if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
00489     {
00490       mCurrentRecordId = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) );
00491       leName->setText( QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 1 ) ) );
00492       //QString myProjectionFamilyId = QString::fromUtf8((char *)sqlite3_column_text(myPreparedStatement,2));
00493       //cboProjectionFamily->setCurrentText(getProjectionFamilyName(myProjectionFamilyId));
00494       //QString myEllipsoidId = QString::fromUtf8((char *)sqlite3_column_text(myPreparedStatement,3));
00495       //cboEllipsoid->setCurrentText(getEllipsoidName(myEllipsoidId));
00496       leParameters->setText( QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 4 ) ) ),
00497       --mCurrentRecordLong;
00498       lblRecordNo->setText( QString::number( mCurrentRecordLong ) + " of " + QString::number( mRecordCountLong ) );
00499     }
00500   }
00501   else
00502   {
00503     QgsDebugMsg( QString( "pbnPrevious query failed: %1" ).arg( mySql ) );
00504 
00505   }
00506   sqlite3_finalize( myPreparedStatement );
00507   sqlite3_close( myDatabase );
00508 
00509   //enable nav buttons as appropriate
00510   if ( mCurrentRecordLong <= 1 )
00511   {
00512     pbnFirst->setEnabled( false );
00513     pbnPrevious->setEnabled( false );
00514   }
00515   else
00516   {
00517     pbnFirst->setEnabled( true );
00518     pbnPrevious->setEnabled( true );
00519   }
00520   if ( mCurrentRecordLong == mRecordCountLong )
00521   {
00522     pbnNext->setEnabled( false );
00523     pbnLast->setEnabled( false );
00524   }
00525   else
00526   {
00527     pbnNext->setEnabled( true );
00528     pbnLast->setEnabled( true );
00529   }
00530 
00531 }
00532 
00533 
00534 void QgsCustomProjectionDialog::on_pbnNext_clicked()
00535 {
00536   QgsDebugMsg( "entered." );
00537   if ( mCurrentRecordLong >= mRecordCountLong )
00538   {
00539     return;
00540   }
00541   sqlite3      *myDatabase;
00542   const char   *myTail;
00543   sqlite3_stmt *myPreparedStatement;
00544   int           myResult;
00545   //check the db is available
00546   myResult = sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase );
00547   if ( myResult != SQLITE_OK )
00548   {
00549     QgsDebugMsg( QString( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
00550     // XXX This will likely never happen since on open, sqlite creates the
00551     //     database if it does not exist.
00552     assert( myResult == SQLITE_OK );
00553   }
00554 
00555   QString mySql = "select * from tbl_srs where srs_id > " + mCurrentRecordId + " order by srs_id asc limit 1";
00556   QgsDebugMsg( QString( "Query to move next:%1" ).arg( mySql ) );
00557   myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail );
00558   // XXX Need to free memory from the error msg if one is set
00559   if ( myResult == SQLITE_OK )
00560   {
00561     if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
00562     {
00563       mCurrentRecordId = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) );
00564       leName->setText( QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 1 ) ) );
00565       //QString myProjectionFamilyId = QString::fromUtf8((char *)sqlite3_column_text(myPreparedStatement,2));
00566       //cboProjectionFamily->setCurrentText(getProjectionFamilyName(myProjectionFamilyId));
00567       //QString myEllipsoidId = QString::fromUtf8((char *)sqlite3_column_text(myPreparedStatement,3));
00568       //cboEllipsoid->setCurrentText(getEllipsoidName(myEllipsoidId));
00569       leParameters->setText( QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 4 ) ) );
00570       ++mCurrentRecordLong;
00571       lblRecordNo->setText( QString::number( mCurrentRecordLong ) + " of " + QString::number( mRecordCountLong ) );
00572     }
00573   }
00574   else
00575   {
00576     QgsDebugMsg( QString( "pbnNext query failed: %1" ).arg( mySql ) );
00577 
00578   }
00579   sqlite3_finalize( myPreparedStatement );
00580   sqlite3_close( myDatabase );
00581 
00582   //enable nav buttons as appropriate
00583   if ( mCurrentRecordLong == mRecordCountLong )
00584   {
00585     pbnNext->setEnabled( false );
00586     pbnLast->setEnabled( false );
00587   }
00588   else
00589   {
00590     pbnNext->setEnabled( true );
00591     pbnLast->setEnabled( true );
00592   }
00593   if ( mRecordCountLong <= 1 )
00594   {
00595     pbnFirst->setEnabled( false );
00596     pbnPrevious->setEnabled( false );
00597   }
00598   else
00599   {
00600     pbnFirst->setEnabled( true );
00601     pbnPrevious->setEnabled( true );
00602   }
00603 
00604 }
00605 
00606 
00607 void QgsCustomProjectionDialog::on_pbnLast_clicked()
00608 {
00609   QgsDebugMsg( "entered." );
00610   sqlite3      *myDatabase;
00611   const char   *myTail;
00612   sqlite3_stmt *myPreparedStatement;
00613   int           myResult;
00614   //check the db is available
00615   myResult = sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase );
00616   if ( myResult != SQLITE_OK )
00617   {
00618     QgsDebugMsg( QString( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
00619     // XXX This will likely never happen since on open, sqlite creates the
00620     //     database if it does not exist.
00621     assert( myResult == SQLITE_OK );
00622   }
00623 
00624   QString mySql = "select * from tbl_srs order by srs_id desc limit 1";
00625   QgsDebugMsg( QString( "Query to move last:%1" ).arg( mySql ) );
00626   myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail );
00627   // XXX Need to free memory from the error msg if one is set
00628   if ( myResult == SQLITE_OK )
00629   {
00630     if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
00631     {
00632       mCurrentRecordId = QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 0 ) );
00633       leName->setText( QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 1 ) ) );
00634       //QString myProjectionFamilyId = QString::fromUtf8((char *)sqlite3_column_text(myPreparedStatement,2));
00635       //cboProjectionFamily->setCurrentText(getProjectionFamilyName(myProjectionFamilyId));
00636       //QString myEllipsoidId = QString::fromUtf8((char *)sqlite3_column_text(myPreparedStatement,3));
00637       //cboEllipsoid->setCurrentText(getEllipsoidName(myEllipsoidId));
00638       leParameters->setText( QString::fromUtf8(( char * )sqlite3_column_text( myPreparedStatement, 4 ) ) );
00639       mCurrentRecordLong = mRecordCountLong;
00640       lblRecordNo->setText( QString::number( mCurrentRecordLong ) + " of " + QString::number( mRecordCountLong ) );
00641     }
00642   }
00643   else
00644   {
00645     QgsDebugMsg( QString( "pbnLast query failed: %1" ).arg( mySql ) );
00646 
00647   }
00648   sqlite3_finalize( myPreparedStatement );
00649   sqlite3_close( myDatabase );
00650 
00651   //enable nav buttons as appropriate
00652   pbnNext->setEnabled( false );
00653   pbnLast->setEnabled( false );
00654   if ( mRecordCountLong <= 1 )
00655   {
00656     pbnFirst->setEnabled( false );
00657     pbnPrevious->setEnabled( false );
00658   }
00659   else
00660   {
00661     pbnFirst->setEnabled( true );
00662     pbnPrevious->setEnabled( true );
00663   }
00664 }
00665 
00666 
00667 void QgsCustomProjectionDialog::on_pbnNew_clicked()
00668 {
00669   if ( pbnNew->text() == tr( "Abort" ) )
00670   {
00671     //if we get here, user has aborted add record
00672     pbnNew->setIcon( QgisApp::getThemeIcon( "mIconNew.png" ) );
00673     //next line needed for new/abort logic
00674     pbnNew->setText( tr( "New" ) );
00675     //get back to the last used record before insert was pressed
00676     if ( mCurrentRecordId.isEmpty() )
00677     {
00678       on_pbnFirst_clicked();
00679     }
00680     else
00681     {
00682       mCurrentRecordLong = mLastRecordLong;
00683       on_pbnNext_clicked();
00684     }
00685   }
00686   else
00687   {
00688     //if we get here user has elected to add new record
00689     pbnFirst->setEnabled( false );
00690     pbnPrevious->setEnabled( false );
00691     pbnNext->setEnabled( false );
00692     pbnLast->setEnabled( false );
00693     pbnDelete->setEnabled( false );
00694     pbnNew->setIcon( QgisApp::getThemeIcon( "mIconNew.png" ) );
00695     //next line needed for new/abort logic
00696     pbnNew->setText( tr( "Abort" ) );
00697     //clear the controls
00698     leName->setText( "" );
00699     leParameters->setText( "" );
00700     //cboProjectionFamily->setCurrentItem(0);
00701     //cboEllipsoid->setCurrentItem(0);
00702     lblRecordNo->setText( "* of " + QString::number( mRecordCountLong ) );
00703     //remember the rec we are on in case the user aborts
00704     mLastRecordLong = mCurrentRecordLong;
00705     mCurrentRecordId = "";
00706   }
00707 
00708 }
00709 
00710 
00711 void QgsCustomProjectionDialog::on_pbnSave_clicked()
00712 {
00713   QgsDebugMsg( "entered." );
00714 
00715   QString myName = leName->text();
00716   QString myParameters = leParameters->text();
00717   if ( myName.isEmpty() )
00718   {
00719     QMessageBox::information( this, tr( "QGIS Custom Projection" ),
00720                               tr( "This proj4 projection definition is not valid. Please give the projection a name before pressing save." ) );
00721     return;
00722   }
00723   if ( myParameters.isEmpty() )
00724   {
00725     QMessageBox::information( this, tr( "QGIS Custom Projection" ),
00726                               tr( "This proj4 projection definition is not valid. Please add the parameters before pressing save." ) );
00727     return;
00728   }
00729 
00730 
00731   //
00732   // Now make sure parameters have proj and ellipse
00733   //
00734 
00735   QString myProjectionAcronym  =  getProjFromParameters();
00736   QString myEllipsoidAcronym   =  getEllipseFromParameters();
00737 
00738   if ( myProjectionAcronym.isNull() )
00739   {
00740     QMessageBox::information( this, tr( "QGIS Custom Projection" ),
00741                               tr( "This proj4 projection definition is not valid. Please add a proj= clause before pressing save." ) );
00742     return;
00743   }
00744 
00753   //if ( myEllipsoidAcronym.isNull() )
00754   //{
00755   //  QMessageBox::information( this, tr("QGIS Custom Projection"),
00756   //          tr("This proj4 ellipsoid definition is not valid. Please add a ellips= clause before pressing save.") );
00757   //  return;
00758   //}
00759 
00760 
00761   //
00762   // We must check the prj def is valid!
00763   // NOTE :  the test below may be bogus as the processes abpve emsired there
00764   // is always at least a projection and ellpsoid - which proj will parse as acceptible
00765   //
00766 
00767   projPJ myProj = pj_init_plus( leParameters->text().toLocal8Bit().data() );
00768 
00769   if ( myProj == NULL )
00770   {
00771     QMessageBox::information( this, tr( "QGIS Custom Projection" ),
00772                               tr( "This proj4 projection definition is not valid. Please correct before pressing save." ) );
00773     pj_free( myProj );
00774     return;
00775 
00776   }
00777   pj_free( myProj );
00778 
00779 
00783   //CREATE TABLE tbl_srs (
00784   //srs_id integer primary key,
00785   //description varchar(255) NOT NULL,
00786   //projection_acronym varchar(20) NOT NULL default '',
00787   //ellipsoid_acronym varchar(20) NOT NULL default '',
00788   //parameters varchar(80) NOT NULL default ''
00789   //);
00790 
00791   QString mySql;
00792   //insert a record if mode is enabled
00793   if ( pbnNew->text() == tr( "Abort" ) )
00794   {
00795     //if this is the first record we need to ensure that its srs_id is 10000. For
00796     //any rec after that sqlite3 will take care of the autonumering
00797     //this was done to support sqlite 3.0 as it does not yet support
00798     //the autoinc related system tables.
00799     if ( getRecordCount() == 0 )
00800     {
00801       mySql = QString( "insert into tbl_srs (srs_id,description,projection_acronym,ellipsoid_acronym,parameters,is_geo) " )
00802               + " values (" + QString::number( USER_CRS_START_ID ) + ",'"
00803               + sqlSafeString( myName ) + "','" + myProjectionAcronym
00804               + "','" + myEllipsoidAcronym  + "','" + sqlSafeString( myParameters )
00805               + "',0)"; // <-- is_geo shamelessly hard coded for now
00806     }
00807     else
00808     {
00809       mySql = "insert into tbl_srs (description,projection_acronym,ellipsoid_acronym,parameters,is_geo) values ('"
00810               + sqlSafeString( myName ) + "','" + myProjectionAcronym
00811               + "','" + myEllipsoidAcronym  + "','" + sqlSafeString( myParameters )
00812               + "',0)"; // <-- is_geo shamelessly hard coded for now
00813     }
00814   }
00815   else //user is updating an existing record
00816   {
00817     mySql = "update tbl_srs set description='" + sqlSafeString( myName )
00818             + "',projection_acronym='" + myProjectionAcronym
00819             + "',ellipsoid_acronym='" + myEllipsoidAcronym
00820             + "',parameters='" + sqlSafeString( myParameters ) + "' "
00821             + ",is_geo=0" // <--shamelessly hard coded for now
00822             + " where srs_id='" + mCurrentRecordId + "'"
00823             ;
00824   }
00825   sqlite3      *myDatabase;
00826   const char   *myTail;
00827   sqlite3_stmt *myPreparedStatement;
00828   int           myResult;
00829   //check the db is available
00830   myResult = sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase );
00831   if ( myResult != SQLITE_OK )
00832   {
00833     QgsDebugMsg( QString( "Can't open database: %1 \n please notify  QGIS developers of this error \n %2 (file name) " ).arg( sqlite3_errmsg( myDatabase ) ).arg( QgsApplication::qgisUserDbFilePath() ) );
00834     // XXX This will likely never happen since on open, sqlite creates the
00835     //     database if it does not exist.
00836     assert( myResult == SQLITE_OK );
00837   }
00838   QgsDebugMsg( QString( "Update or insert sql \n%1" ).arg( mySql ) );
00839   myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail );
00840   sqlite3_step( myPreparedStatement );
00841   // XXX Need to free memory from the error msg if one is set
00842   if ( myResult != SQLITE_OK )
00843   {
00844     QgsDebugMsg( "Update or insert failed in custom projection dialog " );
00845   }
00846   //reinstate button if we were doing an insert
00847   else if ( pbnNew->text() == tr( "Abort" ) )
00848   {
00849     pbnNew->setText( tr( "New" ) );
00850     //get to the newly inserted record
00851     ++mRecordCountLong;
00852     mCurrentRecordLong = mRecordCountLong - 1;
00853     on_pbnLast_clicked();
00854   }
00855 
00856   sqlite3_finalize( myPreparedStatement );
00857   sqlite3_close( myDatabase );
00858   pbnDelete->setEnabled( true );
00859 }
00860 
00861 void QgsCustomProjectionDialog::on_pbnCalculate_clicked()
00862 {
00863   QgsDebugMsg( "entered." );
00864 
00865 
00866   //
00867   // We must check the prj def is valid!
00868   //
00869 
00870   projPJ myProj = pj_init_plus( leTestParameters->text().toLocal8Bit().data() );
00871 
00872   QgsDebugMsg( QString( "My proj: %1" ).arg( leTestParameters->text() ) );
00873 
00874   if ( myProj == NULL )
00875   {
00876     QMessageBox::information( this, tr( "QGIS Custom Projection" ),
00877                               tr( "This proj4 projection definition is not valid." ) );
00878     projectedX->setText( "" );
00879     projectedY->setText( "" );
00880     pj_free( myProj );
00881     return;
00882 
00883   }
00884   // Get the WGS84 coordinates
00885   bool okN, okE;
00886   double northing = northWGS84->text().toDouble( &okN ) * DEG_TO_RAD;
00887   double easthing = eastWGS84->text().toDouble( &okE )  * DEG_TO_RAD;
00888 
00889   if ( !okN || !okE )
00890   {
00891     QMessageBox::information( this, tr( "QGIS Custom Projection" ),
00892                               tr( "Northing and Easthing must be in decimal form." ) );
00893     projectedX->setText( "" );
00894     projectedY->setText( "" );
00895     pj_free( myProj );
00896     return;
00897   }
00898 
00899   projPJ wgs84Proj = pj_init_plus( GEOPROJ4.toLocal8Bit().data() ); //defined in qgis.h
00900 
00901   if ( wgs84Proj == NULL )
00902   {
00903     QMessageBox::information( this, tr( "QGIS Custom Projection" ),
00904                               tr( "Internal Error (source projection invalid?)" ) );
00905     projectedX->setText( "" );
00906     projectedY->setText( "" );
00907     pj_free( myProj );
00908     return;
00909   }
00910 
00911   double z = 0.0;
00912 
00913   int projResult = pj_transform( wgs84Proj, myProj, 1, 0, &easthing, &northing, &z );
00914   if ( projResult != 0 )
00915   {
00916     projectedX->setText( "Error" );
00917     projectedY->setText( "Error" );
00918     QgsDebugMsg( pj_strerrno( projResult ) );
00919   }
00920   else
00921   {
00922     QString tmp;
00923 
00924     tmp = tmp.setNum( northing, 'f', 4 );
00925     projectedX->setText( tmp );
00926     tmp = tmp.setNum( easthing, 'f', 4 );
00927     projectedY->setText( tmp );
00928   }
00929 
00930   //
00931   pj_free( myProj );
00932   pj_free( wgs84Proj );
00933 
00934 }
00935 
00936 
00937 /* This is deprecated - to be deleted
00938 void QgsCustomProjectionDialog::cboProjectionFamily_highlighted( const QString & theText)
00939 {
00940     QgsDebugMsg("Projection selected from combo");
00941   //search the sqlite user projections db for the projection entry
00942   //and display its parameters
00943   sqlite3      *myDatabase;
00944   const char   *myTail;
00945   sqlite3_stmt *myPreparedStatement;
00946   int           myResult;
00947   //check the db is available
00948   myResult = sqlite3_open(QgsApplication::qgisUserDbFilePath().toUtf8().data(), &myDatabase);
00949   if(myResult!=SQLITE_OK)
00950   {
00951     QgsDebugMsg(QString("Can't open database: %1").arg(sqlite3_errmsg(myDatabase)));
00952     // XXX This will likely never happen since on open, sqlite creates the
00953     //     database if it does not exist.
00954     assert(myResult == SQLITE_OK);
00955   }
00956   // Set up the query to retrieve the projection information needed to populate the CRS list
00957   QString mySql = "select parameters from tbl_projection name where name='"+theText+"'";
00958     QgsDebugMsg(QString("Query to get proj params:%1").arg(mySql));
00959   myResult = sqlite3_prepare(myDatabase, mySql.toUtf8(), mySql.length(), &myPreparedStatement, &myTail);
00960   // XXX Need to free memory from the error msg if one is set
00961   if(myResult == SQLITE_OK)
00962   {
00963     sqlite3_step(myPreparedStatement) == SQLITE_ROW;
00964     QString myParametersString = QString::fromUtf8((char *)sqlite3_column_text(myPreparedStatement,0));
00965     QgsDebugMsg(QString("Setting parameters text box to: %1").arg(myParametersString));
00966     txtExpectedParameters->setReadOnly(false);
00967     txtExpectedParameters->setText(myParametersString);
00968     txtExpectedParameters->setReadOnly(true);
00969   }
00970   sqlite3_finalize(myPreparedStatement);
00971   sqlite3_close(myDatabase);
00972 }
00973 */
00974 
00975 
00976 QString QgsCustomProjectionDialog::getProjFromParameters()
00977 {
00978   QgsLogger::debug( "QgsCustomProjectionDialog::getProjFromParameters()" );
00979   QString myProj4String = leParameters->text();
00980   QRegExp myProjRegExp( "\\+proj=[a-zA-Z]*" );
00981   int myStart = 0;
00982   myStart = myProjRegExp.indexIn( myProj4String, myStart );
00983   if ( myStart == -1 )
00984   {
00985     qDebug( "proj string supplied has no +proj argument!" );
00986     return NULL;
00987   }
00988   else
00989   {
00990     int myLength = myProjRegExp.matchedLength();
00991     QString myProjectionAcronym = myProj4String.mid( myStart + ( PROJ_PREFIX_LEN ), myLength - ( PROJ_PREFIX_LEN ) );//+1 for space
00992     return myProjectionAcronym;
00993   }
00994 }
00995 
00996 QString QgsCustomProjectionDialog::getEllipseFromParameters()
00997 {
00998   QgsLogger::debug( "QgsCustomProjectionDialog::getEllipseFromParameters()" );
00999   QString myProj4String = leParameters->text();
01000   QRegExp myEllipseRegExp( "\\+ellps=[a-zA-Z0-9\\-_]*" );
01001   int myStart = 0;
01002   myStart = myEllipseRegExp.indexIn( myProj4String, myStart );
01003   if ( myStart == -1 )
01004   {
01005     QgsDebugMsg( "proj string supplied has no +ellps!" );
01006     return NULL;
01007   }
01008   else //match was found
01009   {
01010     int myLength = myEllipseRegExp.matchedLength();
01011     QString myEllipsoidAcronym = myProj4String.mid( myStart + ( ELLPS_PREFIX_LEN ), myLength - ( ELLPS_PREFIX_LEN ) );
01012     return myEllipsoidAcronym;
01013   }
01014 }
01015 
01025 const QString QgsCustomProjectionDialog::sqlSafeString( const QString theSQL )
01026 {
01027 
01028   QString myRetval;
01029   QChar *it = ( QChar * )theSQL.unicode();
01030   for ( int i = 0; i < theSQL.length(); i++ )
01031   {
01032     if ( *it == '\"' )
01033     {
01034       myRetval += "\\\"";
01035     }
01036     else if ( *it == '\'' )
01037     {
01038       myRetval += "\\'";
01039     }
01040     else if ( *it == '\\' )
01041     {
01042       myRetval += "\\\\";
01043     }
01044     else if ( *it == '%' )
01045     {
01046       myRetval += "\\%";
01047     }
01048     else
01049     {
01050       myRetval += *it;
01051     }
01052     it++;
01053   }
01054   return myRetval;
01055 }
01056 

Generated on Tue Oct 28 16:51:26 2008 for Quantum GIS API Documentation by  doxygen 1.5.1