Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue3243 taking crs into account with bookmarks #78

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6725,7 +6725,8 @@ void QgisApp::newBookmark()
{
// create the bookmark
QgsBookmarkItem *bmi = new QgsBookmarkItem( bookmarkName,
QgsProject::instance()->title(), mMapCanvas->extent(), -1,
QgsProject::instance()->title(), mMapCanvas->extent(),
mMapCanvas->mapRenderer()->destinationCrs().srsid(),
QgsApplication::qgisUserDbFilePath() );
bmi->store();
delete bmi;
Expand Down
276 changes: 80 additions & 196 deletions src/app/qgsbookmarks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
#include "qgsapplication.h"
#include "qgscontexthelp.h"
#include "qgsmapcanvas.h"
#include "qgsmaprenderer.h"
#include <qgscoordinatereferencesystem.h>

#include "qgslogger.h"

#include <QDir>
Expand All @@ -29,7 +32,6 @@

//standard includes
#include <cassert>
#include <sqlite3.h>
#include <fstream>

QgsBookmarks::QgsBookmarks( QWidget *parent, Qt::WFlags fl )
Expand All @@ -56,15 +58,15 @@ QgsBookmarks::QgsBookmarks( QWidget *parent, Qt::WFlags fl )
// Create the zoomto and delete buttons and add them to the
// toolbar
//
QPushButton * btnUpdate = new QPushButton( tr( "&Update" ) );
//QPushButton * btnUpdate = new QPushButton( tr( "&Update" ) );
QPushButton * btnDelete = new QPushButton( tr( "&Delete" ) );
QPushButton * btnZoomTo = new QPushButton( tr( "&Zoom to" ) );
btnZoomTo->setDefault( true );
buttonBox->addButton( btnUpdate, QDialogButtonBox::ActionRole );
//buttonBox->addButton( btnUpdate, QDialogButtonBox::ActionRole );
buttonBox->addButton( btnDelete, QDialogButtonBox::ActionRole );
buttonBox->addButton( btnZoomTo, QDialogButtonBox::ActionRole );
// connect the slot up to catch when a bookmark is updated
connect( btnUpdate, SIGNAL( clicked() ), this, SLOT( on_btnUpdate_clicked() ) );
//connect( btnUpdate, SIGNAL( clicked() ), this, SLOT( on_btnUpdate_clicked() ) );
// connect the slot up to catch when a bookmark is deleted
connect( btnDelete, SIGNAL( clicked() ), this, SLOT( on_btnDelete_clicked() ) );
// connect the slot up to catch when a bookmark is zoomed to
Expand All @@ -76,67 +78,36 @@ QgsBookmarks::QgsBookmarks( QWidget *parent, Qt::WFlags fl )
// Destructor
QgsBookmarks::~QgsBookmarks()
{
db.close();
QSqlDatabase::removeDatabase(CRSDB);
saveWindowLocation();
}

void QgsBookmarks::refreshBookmarks()
{
lstBookmarks->clear();
initialise();
}
// Initialise the bookmark tree from the database
void QgsBookmarks::initialise()
{
int rc = connectDb();
if ( rc == SQLITE_OK )
{
// prepare the sql statement
const char *pzTail;
sqlite3_stmt *ppStmt;
QString sql = "select * from tbl_bookmarks";

rc = sqlite3_prepare( db, sql.toUtf8(), sql.toUtf8().length(), &ppStmt, &pzTail );
// XXX Need to free memory from the error msg if one is set
if ( rc == SQLITE_OK )
{
// get the first row of the result set
while ( sqlite3_step( ppStmt ) == SQLITE_ROW )
{
QTreeWidgetItem *item = new QTreeWidgetItem( lstBookmarks );
QString name = QString::fromUtf8(( const char * )sqlite3_column_text( ppStmt, 1 ) );
// sqlite3_bind_parameter_index(ppStmt, "name"));
//QgsDebugMsg("Bookmark name: " + name.toLocal8Bit().data());
item->setText( 0, name );
// set the project name
item->setText( 1, QString::fromUtf8(( const char * )sqlite3_column_text( ppStmt, 2 ) ) );
// get the extents
QString xMin = QString::fromUtf8(( const char * )sqlite3_column_text( ppStmt, 3 ) );
QString yMin = QString::fromUtf8(( const char * )sqlite3_column_text( ppStmt, 4 ) );
QString xMax = QString::fromUtf8(( const char * )sqlite3_column_text( ppStmt, 5 ) );
QString yMax = QString::fromUtf8(( const char * )sqlite3_column_text( ppStmt, 6 ) );
// set the extents
item->setText( 2, xMin + ", " + yMin + " : " + xMax + ", " + yMax ); // use colon to separate ll from ur corners listed (be consistent with other displays of extent)
// set the id
item->setText( 3, QString::fromUtf8(( const char * )sqlite3_column_text( ppStmt, 0 ) ) );
}
for ( int col = 0; col < 4; col++ )
{
lstBookmarks->resizeColumnToContents( col );
}
lstBookmarks->sortByColumn( 0, Qt::AscendingOrder );
}
else
{
// XXX query failed -- warn the user some how
QgsDebugMsg( QString( "Failed to get bookmarks: %1" ).arg( sqlite3_errmsg( db ) ) );
}
// close the statement
sqlite3_finalize( ppStmt );
// close the database
sqlite3_close( db );
// return the srs wkt

}
this->connectDb();
QSqlTableModel *model = new QSqlTableModel(0, db);
model->setTable( "tbl_bookmarks" );
model->select();
lstBookmarks->setModel( model );
// set better headers then column names from table
lstBookmarks->model()->setHeaderData(1, Qt::Horizontal, QObject::tr("Name"));
lstBookmarks->model()->setHeaderData(2, Qt::Horizontal, QObject::tr("Project"));
lstBookmarks->model()->setHeaderData(3, Qt::Horizontal, QObject::tr("xMin"));
lstBookmarks->model()->setHeaderData(4, Qt::Horizontal, QObject::tr("yMin"));
lstBookmarks->model()->setHeaderData(5, Qt::Horizontal, QObject::tr("xMax"));
lstBookmarks->model()->setHeaderData(6, Qt::Horizontal, QObject::tr("yMax"));
// hide id column
lstBookmarks->setColumnHidden(0, true);
// hide srid column
lstBookmarks->setColumnHidden(7, true);

lstBookmarks->setEditTriggers(QAbstractItemView::EditKeyPressed);
}

void QgsBookmarks::restorePosition()
Expand All @@ -151,172 +122,85 @@ void QgsBookmarks::saveWindowLocation()
settings.setValue( "/Windows/Bookmarks/geometry", saveGeometry() );
}

void QgsBookmarks::on_btnUpdate_clicked()
void QgsBookmarks::on_btnDelete_clicked()
{
// get the current item
QTreeWidgetItem *item = lstBookmarks->currentItem();
if ( item )
QModelIndex index = lstBookmarks->currentIndex();
if ( index.isValid() )
{
// make sure the user really wants to update this bookmark
if ( QMessageBox::Ok == QMessageBox::information( this, tr( "Really Update?" ),
tr( "Are you sure you want to update the %1 bookmark?" ).arg( item->text( 0 ) ),
QMessageBox::Ok | QMessageBox::Cancel ) )
{
// retrieve the current map extent
QgsRectangle viewExtent = QgisApp::instance()->mapCanvas()->extent();

int rc;
QgsDebugMsg( QString( "Opening user database: %1" ).arg( QgsApplication::qgisUserDbFilePath() ) );
rc = connectDb();
if ( SQLITE_OK == rc )
{
// prepare the sql statement
QString sql;
QTextStream sqlStream( &sql );
// use '17 g' format; SmartNotation is default
sqlStream.setRealNumberPrecision( 17 );
sqlStream << "update tbl_bookmarks set " <<
"xmin=" << viewExtent.xMinimum() << "," <<
"ymin=" << viewExtent.yMinimum() << "," <<
"xmax=" << viewExtent.xMaximum() << "," <<
"ymax=" << viewExtent.yMaximum() << " " <<
"where bookmark_id=" << item->text( 3 );
QgsDebugMsg( QString( "Storing bookmark using: %1" ).arg( sql ) );

char * errmsg;
rc = sqlite3_exec( db, sql.toUtf8(), NULL, NULL, &errmsg );
if ( rc != SQLITE_OK )
{
// XXX Provide popup message on failure?
QMessageBox::warning( this, tr( "Error updating bookmark" ),
tr( "Failed to update the %1 bookmark. The database said:\n%2" )
.arg( item->text( 0 ) ).arg( errmsg ) );
sqlite3_free( errmsg );
}
// close the database
sqlite3_close( db );

refreshBookmarks();

}
else
// make sure the user really wants to delete this bookmark
if ( QMessageBox::Ok == QMessageBox::information( this, tr( "Really Delete?" ),
tr( "Are you sure you want to delete the '%1' bookmark?" ).arg(
index.sibling(index.row(), 1).data().toString() ),
QMessageBox::Ok | QMessageBox::Cancel ) )
{
QgsDebugMsg( QString( "Can't open database: %1" ).arg( sqlite3_errmsg( db ) ) );

// XXX This will likely never happen since on open, sqlite creates the
// database if it does not exist.
assert( rc == 0 );
lstBookmarks->model()->removeRow(index.row());
}
}
}
}

void QgsBookmarks::on_btnDelete_clicked()
/*void QgsBookmarks::on_lstBookmarks_clicked(const QModelIndex & index)
{
// get the current item
QTreeWidgetItem *item = lstBookmarks->currentItem();
if ( item )
{
// make sure the user really wants to delete this bookmark
if ( QMessageBox::Ok == QMessageBox::information( this, tr( "Really Delete?" ),
tr( "Are you sure you want to delete the %1 bookmark?" ).arg( item->text( 0 ) ),
QMessageBox::Ok | QMessageBox::Cancel ) )
{
// remove it from the listview
item = lstBookmarks->takeTopLevelItem( lstBookmarks->indexOfTopLevelItem( item ) );
// delete it from the database
int rc = connectDb();
if ( rc == SQLITE_OK )
{
char *errmsg;
// build the sql statement
QString sql = "delete from tbl_bookmarks where bookmark_id = " + item->text( 3 );
rc = sqlite3_exec( db, sql.toUtf8(), NULL, NULL, &errmsg );
if ( rc != SQLITE_OK )
{
// XXX Provide popup message on failure?
QMessageBox::warning( this, tr( "Error deleting bookmark" ),
tr( "Failed to delete the %1 bookmark from the database. The database said:\n%2" )
.arg( item->text( 0 ) ).arg( errmsg ) );
sqlite3_free( errmsg );
}
// close the database
sqlite3_close( db );
}
delete item;
}
}
}
Q_UNUSED( index );
zoomToBookmark();
}*/

void QgsBookmarks::on_btnZoomTo_clicked()
void QgsBookmarks::on_lstBookmarks_doubleClicked(const QModelIndex & index)
{
Q_UNUSED( index );
zoomToBookmark();
}

void QgsBookmarks::on_lstBookmarks_itemDoubleClicked( QTreeWidgetItem *lvi )
void QgsBookmarks::on_btnZoomTo_clicked()
{
Q_UNUSED( lvi );
zoomToBookmark();
}

void QgsBookmarks::zoomToBookmark()
{
// Need to fetch the extent for the selected bookmark and then redraw
// the map
// get the current item
QTreeWidgetItem *item = lstBookmarks->currentItem();
if ( !item )
{
return;
}
// get the extent from the database
int rc = connectDb();
if ( rc == SQLITE_OK )
{
sqlite3_stmt *ppStmt;
const char *pzTail;
// build the sql statement
QString sql = "select xmin, ymin, xmax, ymax from tbl_bookmarks where bookmark_id = " + item->text( 3 );
rc = sqlite3_prepare( db, sql.toUtf8(), sql.toUtf8().length(), &ppStmt, &pzTail );
if ( rc == SQLITE_OK )
QModelIndex index = lstBookmarks->currentIndex();
if ( index.isValid() )
{
if ( sqlite3_step( ppStmt ) == SQLITE_ROW )
{
// get the extents from the resultset
QString xmin = QString::fromUtf8(( const char * )sqlite3_column_text( ppStmt, 0 ) );
QString ymin = QString::fromUtf8(( const char * )sqlite3_column_text( ppStmt, 1 ) );
QString xmax = QString::fromUtf8(( const char * )sqlite3_column_text( ppStmt, 2 ) );
QString ymax = QString::fromUtf8(( const char * )sqlite3_column_text( ppStmt, 3 ) );
double xmin = index.sibling( index.row(), 3).data().toDouble();
double ymin = index.sibling( index.row(), 4).data().toDouble();
double xmax = index.sibling( index.row(), 5).data().toDouble();
double ymax = index.sibling( index.row(), 6).data().toDouble();
int srid = index.sibling( index.row(), 7).data().toInt();

QgsRectangle rect = QgsRectangle( xmin, ymin, xmax, ymax );
if (srid > 0) // backwards compatibility, older version had -1 in the srid column
{
// we could also check if those are the same ... but..
QgsCoordinateReferenceSystem srcMapcanvas = QgisApp::instance()->mapCanvas()->mapRenderer()->destinationCrs();
QgsCoordinateReferenceSystem srsSource;
//srsSource.createFromId( srid ); // gebruikt 2517 en wordt dan gauss
srsSource.createFromSrsId( srid);
QgsCoordinateTransform * coordTransform = new QgsCoordinateTransform( srsSource, srcMapcanvas );
rect = coordTransform->transform( rect );
delete coordTransform;
}

// set the extent to the bookmark
QgisApp::instance()->setExtent( QgsRectangle( xmin.toDouble(),
ymin.toDouble(),
xmax.toDouble(),
ymax.toDouble() ) );
QgisApp::instance()->setExtent( rect );
// redraw the map
QgisApp::instance()->mapCanvas()->refresh();
}
QgisApp::instance()->mapCanvas()->refresh();\
}

// close the statement
sqlite3_finalize( ppStmt );
// close the database
sqlite3_close( db );
}

}

int QgsBookmarks::connectDb()
{

int rc;
rc = sqlite3_open( QgsApplication::qgisUserDbFilePath().toUtf8().data(), &db );
if ( rc != SQLITE_OK )
{
QgsDebugMsg( QString( "Can't open database: %1" ).arg( sqlite3_errmsg( db ) ) );

// XXX This will likely never happen since on open, sqlite creates the
// database if it does not exist.
assert( rc == 0 );
}
return rc;
if ( QSqlDatabase::contains( CRSDB ) && db.open()){
QgsDebugMsg( QString( "Successfully returned open database: %1" ).arg( QgsApplication::qgisUserDbFilePath().toUtf8().data() ) );
}
else {
db = QSqlDatabase::addDatabase("QSQLITE", CRSDB);
db.setDatabaseName( QgsApplication::qgisUserDbFilePath().toUtf8().data() );
if (db.open()) {
QgsDebugMsg( QString( "Successfully opened database: %1" ).arg( QgsApplication::qgisUserDbFilePath().toUtf8().data() ) );
}
else {
QgsDebugMsg( QString( "Can't open database: %1" ).arg( QgsApplication::qgisUserDbFilePath().toUtf8().data() ) );
return 0;
}
}
return 1;
}
Loading