mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
supporting the SpatiaLite Data Provider
2009-04-24 Sandro Furieri <a.furieri@lqt.it> git-svn-id: http://svn.osgeo.org/qgis/trunk@10414 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
caa6177059
commit
38f81229f0
@ -50,6 +50,12 @@ IF (WITH_POSTGRESQL)
|
||||
SET (POSTGRESQL_PREFIX "" CACHE PATH "Path to POSTGRESQL base directory")
|
||||
ENDIF (WITH_POSTGRESQL)
|
||||
|
||||
# try to configure and build SPATIALITE support
|
||||
SET (WITH_SPATIALITE TRUE CACHE BOOL "Determines whether SPATIALITE support should be built")
|
||||
IF (WITH_SPATIALITE)
|
||||
SET (SPATIALITE_PREFIX "" CACHE PATH "Path to SPATIALITE base directory")
|
||||
ENDIF (WITH_SPATIALITE)
|
||||
|
||||
# try to configure and build python bindings by default
|
||||
SET (WITH_BINDINGS TRUE CACHE BOOL "Determines whether python bindings should be built")
|
||||
IF (WITH_BINDINGS)
|
||||
@ -118,6 +124,9 @@ FIND_PACKAGE(GSL) # Georeferencer
|
||||
IF (WITH_GRASS)
|
||||
FIND_PACKAGE(GRASS) # GRASS plugin
|
||||
ENDIF (WITH_GRASS)
|
||||
IF (WITH_SPATIALITE)
|
||||
FIND_PACKAGE(SPATIALITE) # SPATIALITE provider
|
||||
ENDIF (WITH_SPATIALITE)
|
||||
|
||||
IF (WITH_BINDINGS)
|
||||
# python support:
|
||||
@ -136,6 +145,10 @@ IF (POSTGRES_FOUND)
|
||||
SET (HAVE_POSTGRESQL TRUE)
|
||||
ENDIF (POSTGRES_FOUND)
|
||||
|
||||
IF (SPATIALITE_FOUND)
|
||||
# following variable is used in qgsconfig.h
|
||||
SET (HAVE_SPATIALITE TRUE)
|
||||
ENDIF (SPATIALITE_FOUND)
|
||||
|
||||
#############################################################
|
||||
# search for Qt4
|
||||
|
50
cmake/FindSPATIALITE.cmake
Normal file
50
cmake/FindSPATIALITE.cmake
Normal file
@ -0,0 +1,50 @@
|
||||
|
||||
# CMake module to search for SpatiaLite library
|
||||
#
|
||||
# If it's found it sets SPATIALITE_FOUND to TRUE
|
||||
# and following variables are set:
|
||||
# SPATIALITE_INCLUDE_DIR
|
||||
# SPATIALITE_LIBRARY
|
||||
|
||||
|
||||
# FIND_PATH and FIND_LIBRARY normally search standard locations
|
||||
# before the specified paths. To search non-standard paths first,
|
||||
# FIND_* is invoked first with specified paths and NO_DEFAULT_PATH
|
||||
# and then again with no specified paths to search the default
|
||||
# locations. When an earlier FIND_* succeeds, subsequent FIND_*s
|
||||
# searching for the same item do nothing.
|
||||
FIND_PATH(SPATIALITE_INCLUDE_DIR spatialite.h
|
||||
"$ENV{LIB_DIR}/include"
|
||||
"$ENV{LIB_DIR}/include/spatialite"
|
||||
#mingw
|
||||
c:/msys/local/include
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
FIND_PATH(SPATIALITE_INCLUDE_DIR spatialite.h)
|
||||
|
||||
FIND_LIBRARY(SPATIALITE_LIBRARY NAMES spatialite PATHS
|
||||
"$ENV{LIB_DIR}/lib"
|
||||
#mingw
|
||||
c:/msys/local/lib
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
FIND_LIBRARY(SPATIALITE_LIBRARY NAMES spatialite)
|
||||
|
||||
IF (SPATIALITE_INCLUDE_DIR AND SPATIALITE_LIBRARY)
|
||||
SET(SPATIALITE_FOUND TRUE)
|
||||
ENDIF (SPATIALITE_INCLUDE_DIR AND SPATIALITE_LIBRARY)
|
||||
|
||||
|
||||
IF (SPATIALITE_FOUND)
|
||||
|
||||
IF (NOT SPATIALITE_FIND_QUIETLY)
|
||||
MESSAGE(STATUS "Found SpatiaLite: ${SPATIALITE_LIBRARY}")
|
||||
ENDIF (NOT SPATIALITE_FIND_QUIETLY)
|
||||
|
||||
ELSE (SPATIALITE_FOUND)
|
||||
|
||||
IF (SPATIALITE_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find SpatiaLite")
|
||||
ENDIF (SPATIALITE_FIND_REQUIRED)
|
||||
|
||||
ENDIF (SPATIALITE_FOUND)
|
@ -25,6 +25,8 @@
|
||||
|
||||
#cmakedefine HAVE_POSTGRESQL
|
||||
|
||||
#cmakedefine HAVE_SPATIALITE
|
||||
|
||||
#cmakedefine HAVE_PYTHON
|
||||
|
||||
#endif
|
||||
|
BIN
images/themes/default/mActionAddSpatiaLiteLayer.png
Normal file
BIN
images/themes/default/mActionAddSpatiaLiteLayer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
@ -15,6 +15,8 @@ SET(QGIS_APP_SRCS
|
||||
qgscustomprojectiondialog.cpp
|
||||
qgsdbfilterproxymodel.cpp
|
||||
qgsdbtablemodel.cpp
|
||||
qgsspatialitefilterproxymodel.cpp
|
||||
qgsspatialitetablemodel.cpp
|
||||
qgsdelattrdialog.cpp
|
||||
qgsgeomtypedialog.cpp
|
||||
qgsgraduatedsymboldialog.cpp
|
||||
@ -135,6 +137,7 @@ SET (QGIS_APP_MOC_HDRS
|
||||
qgsuniquevaluedialog.h
|
||||
qgsvectorlayerproperties.h
|
||||
qgsdbtablemodel.h
|
||||
qgsspatialitetablemodel.h
|
||||
|
||||
composer/qgscomposer.h
|
||||
composer/qgscomposeritemwidget.h
|
||||
@ -175,6 +178,15 @@ IF (POSTGRES_FOUND)
|
||||
)
|
||||
ENDIF (POSTGRES_FOUND)
|
||||
|
||||
IF (SPATIALITE_FOUND)
|
||||
SET (QGIS_APP_SRCS ${QGIS_APP_SRCS}
|
||||
qgsspatialitesourceselect.cpp
|
||||
)
|
||||
SET (QGIS_APP_MOC_HDRS ${QGIS_APP_MOC_HDRS}
|
||||
qgsspatialitesourceselect.h
|
||||
)
|
||||
ENDIF (SPATIALITE_FOUND)
|
||||
|
||||
|
||||
QT4_WRAP_CPP(QGIS_APP_MOC_SRCS ${QGIS_APP_MOC_HDRS})
|
||||
|
||||
@ -227,6 +239,10 @@ IF (POSTGRES_FOUND)
|
||||
INCLUDE_DIRECTORIES(${POSTGRES_INCLUDE_DIR})
|
||||
ENDIF (POSTGRES_FOUND)
|
||||
|
||||
IF (SPATIALITE_FOUND)
|
||||
INCLUDE_DIRECTORIES(${SPATIALITE_INCLUDE_DIR})
|
||||
ENDIF (SPATIALITE_FOUND)
|
||||
|
||||
#############
|
||||
|
||||
IF (WIN32)
|
||||
@ -269,6 +285,10 @@ IF (POSTGRES_FOUND)
|
||||
TARGET_LINK_LIBRARIES (qgis ${POSTGRES_LIBRARY})
|
||||
ENDIF (POSTGRES_FOUND)
|
||||
|
||||
IF (SPATIALITE_FOUND)
|
||||
TARGET_LINK_LIBRARIES (qgis ${SPATIALITE_LIBRARY})
|
||||
ENDIF (SPATIALITE_FOUND)
|
||||
|
||||
IF (APPLE)
|
||||
# For Mac OS X, the executable must be at the root of the bundle's executable folder
|
||||
INSTALL(TARGETS qgis RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
|
@ -175,6 +175,9 @@
|
||||
#ifdef HAVE_POSTGRESQL
|
||||
#include "qgsdbsourceselect.h"
|
||||
#endif
|
||||
#ifdef HAVE_SPATIALITE
|
||||
#include "qgsspatialitesourceselect.h"
|
||||
#endif
|
||||
|
||||
#include "qgspythondialog.h"
|
||||
#include "qgspythonutils.h"
|
||||
@ -776,6 +779,18 @@ void QgisApp::createActions()
|
||||
//#endif
|
||||
connect( mActionAddPgLayer, SIGNAL( triggered() ), this, SLOT( addDatabaseLayer() ) );
|
||||
|
||||
mActionAddSpatiaLiteLayer = new QAction( getThemeIcon( "mActionAddSpatiaLiteLayer.png" ), tr( "Add SpatiaLite Layer..." ), this );
|
||||
mActionAddSpatiaLiteLayer->setShortcut( tr( "L", "Add a SpatiaLite Layer" ) );
|
||||
mActionAddSpatiaLiteLayer->setStatusTip( tr( "Add a SpatiaLite Layer" ) );
|
||||
connect( mActionAddSpatiaLiteLayer, SIGNAL( triggered() ), this, SLOT( addSpatiaLiteLayer() ) );
|
||||
//#ifdef HAVE_SPATIALITE
|
||||
// QgsDebugMsg("HAVE_SPATIALITE is defined");
|
||||
// assert(0);
|
||||
//#else
|
||||
// QgsDebugMsg("HAVE_SPATIALITE not defined");
|
||||
// assert(0);
|
||||
//#endif
|
||||
|
||||
mActionAddWmsLayer = new QAction( getThemeIcon( "mActionAddWmsLayer.png" ), tr( "Add WMS Layer..." ), this );
|
||||
mActionAddWmsLayer->setShortcut( tr( "W", "Add a Web Mapping Server Layer" ) );
|
||||
mActionAddWmsLayer->setStatusTip( tr( "Add a Web Mapping Server Layer" ) );
|
||||
@ -1109,6 +1124,9 @@ void QgisApp::createMenus()
|
||||
mLayerMenu->addAction( mActionAddRasterLayer );
|
||||
#ifdef HAVE_POSTGRESQL
|
||||
mLayerMenu->addAction( mActionAddPgLayer );
|
||||
#endif
|
||||
#ifdef HAVE_SPATIALITE
|
||||
mLayerMenu->addAction( mActionAddSpatiaLiteLayer );
|
||||
#endif
|
||||
mLayerMenu->addAction( mActionAddWmsLayer );
|
||||
mActionLayerSeparator1 = mLayerMenu->addSeparator();
|
||||
@ -1207,6 +1225,9 @@ void QgisApp::createToolBars()
|
||||
mFileToolBar->addAction( mActionAddRasterLayer );
|
||||
#ifdef HAVE_POSTGRESQL
|
||||
mFileToolBar->addAction( mActionAddPgLayer );
|
||||
#endif
|
||||
#ifdef HAVE_SPATIALITE
|
||||
mFileToolBar->addAction( mActionAddSpatiaLiteLayer );
|
||||
#endif
|
||||
mFileToolBar->addAction( mActionAddWmsLayer );
|
||||
mToolbarMenu->addAction( mFileToolBar->toggleViewAction() );
|
||||
@ -1432,6 +1453,7 @@ void QgisApp::setTheme( QString theThemeName )
|
||||
mActionAddOgrLayer->setIcon( getThemeIcon( "/mActionAddOgrLayer.png" ) );
|
||||
mActionAddRasterLayer->setIcon( getThemeIcon( "/mActionAddRasterLayer.png" ) );
|
||||
mActionAddPgLayer->setIcon( getThemeIcon( "/mActionAddLayer.png" ) );
|
||||
mActionAddSpatiaLiteLayer->setIcon( getThemeIcon( "/mActionAddSpatiaLiteLayer.png" ) );
|
||||
mActionRemoveLayer->setIcon( getThemeIcon( "/mActionRemoveLayer.png" ) );
|
||||
mActionNewVectorLayer->setIcon( getThemeIcon( "/mActionNewVectorLayer.png" ) );
|
||||
mActionAddAllToOverview->setIcon( getThemeIcon( "/mActionAddAllToOverview.png" ) );
|
||||
@ -1794,6 +1816,13 @@ void QgisApp::about()
|
||||
#else
|
||||
|
||||
versionString += tr( " This copy of QGIS has been built without PostgreSQL support." );
|
||||
#endif
|
||||
#ifdef HAVE_SPATIALITE
|
||||
|
||||
versionString += tr( "\nThis copy of QGIS has been built with SpatiaLite support." );
|
||||
#else
|
||||
|
||||
versionString += tr( "\nThis copy of QGIS has been built without SpatiaLite support." );
|
||||
#endif
|
||||
versionString += tr( "\nThis binary was compiled against Qt %1,"
|
||||
"and is currently running against Qt %2" )
|
||||
@ -2384,6 +2413,87 @@ void QgisApp::addDatabaseLayer()
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_SPATIALITE
|
||||
void QgisApp::addSpatiaLiteLayer() {}
|
||||
#else
|
||||
void QgisApp::addSpatiaLiteLayer()
|
||||
{
|
||||
if(mMapCanvas && mMapCanvas->isDrawing())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// show the SpatiaLite dialog
|
||||
|
||||
QgsSpatiaLiteSourceSelect *dbs = new QgsSpatiaLiteSourceSelect( this );
|
||||
|
||||
mMapCanvas->freeze();
|
||||
|
||||
if (dbs->exec())
|
||||
{
|
||||
// Let render() do its own cursor management
|
||||
// QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
||||
|
||||
// repaint the canvas if it was covered by the dialog
|
||||
|
||||
// add files to the map canvas
|
||||
QStringList tables = dbs->selectedTables();
|
||||
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
||||
QString connectionInfo = dbs->connectionInfo();
|
||||
// for each selected table, connect to the database and build a canvasitem for it
|
||||
QStringList::Iterator it = tables.begin();
|
||||
while (it != tables.end())
|
||||
{
|
||||
|
||||
// normalizing the layer name
|
||||
QString layername = *it;
|
||||
layername = layername.mid(1);
|
||||
int idx = layername.indexOf( "\" (" );
|
||||
if (idx > 0)
|
||||
layername.truncate(idx);
|
||||
|
||||
// create the layer
|
||||
//qWarning("creating layer");
|
||||
QgsVectorLayer *layer = new QgsVectorLayer( "dbname='" + connectionInfo + "' table=" + *it + ")", layername, "spatialite" );
|
||||
if ( layer->isValid() )
|
||||
{
|
||||
// register this layer with the central layers registry
|
||||
QgsMapLayerRegistry::instance()->addMapLayer( layer );
|
||||
// notify the project we've made a change
|
||||
QgsProject::instance()->dirty( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsDebugMsg( (*it) + " is an invalid layer - not loaded" );
|
||||
QMessageBox::critical( this, tr( "Invalid Layer" ), tr( "%1 is an invalid layer and cannot be loaded." ).arg( *it ) );
|
||||
delete layer;
|
||||
}
|
||||
//qWarning("incrementing iterator");
|
||||
++it;
|
||||
}
|
||||
|
||||
QApplication::restoreOverrideCursor();
|
||||
|
||||
statusBar()->showMessage( mMapCanvas->extent().toString( 2 ) );
|
||||
}
|
||||
delete dbs;
|
||||
|
||||
// update UI
|
||||
qApp->processEvents();
|
||||
|
||||
// draw the map
|
||||
mMapCanvas->freeze( false );
|
||||
mMapCanvas->refresh();
|
||||
|
||||
// Let render() do its own cursor management
|
||||
// QApplication::restoreOverrideCursor();
|
||||
|
||||
} // QgisApp::addSpatiaLiteLayer()
|
||||
#endif
|
||||
|
||||
void QgisApp::addWmsLayer()
|
||||
{
|
||||
if ( mMapCanvas && mMapCanvas->isDrawing() )
|
||||
|
@ -246,6 +246,7 @@ class QgisApp : public QMainWindow
|
||||
QAction *actionAddOgrLayer() { return mActionAddOgrLayer; }
|
||||
QAction *actionAddRasterLayer() { return mActionAddRasterLayer; }
|
||||
QAction *actionAddPgLayer() { return mActionAddPgLayer; }
|
||||
QAction *actionAddSpatiaLiteLayer() { return mActionAddSpatiaLiteLayer; };
|
||||
QAction *actionAddWmsLayer() { return mActionAddWmsLayer; }
|
||||
QAction *actionLayerSeparator1() { return mActionLayerSeparator1; }
|
||||
QAction *actionOpenTable() { return mActionOpenTable; }
|
||||
@ -369,6 +370,10 @@ class QgisApp : public QMainWindow
|
||||
//#ifdef HAVE_POSTGRESQL
|
||||
//! Add a databaselayer to the map
|
||||
void addDatabaseLayer();
|
||||
//#endif
|
||||
//#ifdef HAVE_SPATIALITE
|
||||
//! Add a SpatiaLite layer to the map
|
||||
void addSpatiaLiteLayer();
|
||||
//#endif
|
||||
/** toggles whether the current selected layer is in overview or not */
|
||||
void isInOverview();
|
||||
@ -717,6 +722,7 @@ class QgisApp : public QMainWindow
|
||||
QAction *mActionAddOgrLayer;
|
||||
QAction *mActionAddRasterLayer;
|
||||
QAction *mActionAddPgLayer;
|
||||
QAction *mActionAddSpatiaLiteLayer;
|
||||
QAction *mActionAddWmsLayer;
|
||||
QAction *mActionLayerSeparator1;
|
||||
QAction *mActionOpenTable;
|
||||
|
52
src/app/qgsspatialitefilterproxymodel.cpp
Normal file
52
src/app/qgsspatialitefilterproxymodel.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
/***************************************************************************
|
||||
qgsspatialitefilterproxymodel.cpp - description
|
||||
-------------------------
|
||||
begin : Dec 2008
|
||||
copyright : (C) 2008 by Sandro Furieri
|
||||
email : a.furieri@lqt.it
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsspatialitefilterproxymodel.h"
|
||||
|
||||
QgsSpatiaLiteFilterProxyModel::QgsSpatiaLiteFilterProxyModel(QObject * parent):QSortFilterProxyModel(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QgsSpatiaLiteFilterProxyModel::~QgsSpatiaLiteFilterProxyModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool QgsSpatiaLiteFilterProxyModel::filterAcceptsRow(int row, const QModelIndex & source_parent) const
|
||||
{
|
||||
//if parent is valid, we have a toplevel item that should be always shown
|
||||
if (!source_parent.isValid())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
//else we have a row that describes a table and that
|
||||
//should be tested using the given wildcard/regexp
|
||||
return QSortFilterProxyModel::filterAcceptsRow(row, source_parent);
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteFilterProxyModel::_setFilterWildcard(const QString & pattern)
|
||||
{
|
||||
QSortFilterProxyModel::setFilterWildcard(pattern);
|
||||
emit layoutChanged();
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteFilterProxyModel::_setFilterRegExp(const QString & pattern)
|
||||
{
|
||||
QSortFilterProxyModel::setFilterRegExp(pattern);
|
||||
emit layoutChanged();
|
||||
}
|
39
src/app/qgsspatialitefilterproxymodel.h
Normal file
39
src/app/qgsspatialitefilterproxymodel.h
Normal file
@ -0,0 +1,39 @@
|
||||
/***************************************************************************
|
||||
qgsspatialitefilterproxymodel.h - description
|
||||
-----------------------
|
||||
begin : Dec 2008
|
||||
copyright : (C) 2008 by Sandro Furieri
|
||||
email : a.furieri@lqt.it
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSSPATIALITEFILTERPROXYMODEL_H
|
||||
#define QGSSPATIALITEFILTERPROXYMODEL_H
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
/**A class that implements a custom filter and can be used
|
||||
as a proxy for QgsSpatiaLiteTableModel*/
|
||||
class QgsSpatiaLiteFilterProxyModel:public QSortFilterProxyModel
|
||||
{
|
||||
public:
|
||||
QgsSpatiaLiteFilterProxyModel(QObject * parent = 0);
|
||||
~QgsSpatiaLiteFilterProxyModel();
|
||||
/**Calls QSortFilterProxyModel::setFilterWildcard and triggers update*/
|
||||
void _setFilterWildcard(const QString & pattern);
|
||||
/**Calls QSortFilterProxyModel::setFilterRegExp and triggers update*/
|
||||
void _setFilterRegExp(const QString & pattern);
|
||||
|
||||
protected:
|
||||
virtual bool filterAcceptsRow(int row, const QModelIndex & source_parent) const;
|
||||
};
|
||||
|
||||
#endif
|
622
src/app/qgsspatialitesourceselect.cpp
Normal file
622
src/app/qgsspatialitesourceselect.cpp
Normal file
@ -0,0 +1,622 @@
|
||||
/***************************************************************************
|
||||
qgsspatialitesourceselect.cpp
|
||||
Dialog to select SpatiaLite layer(s) and add it to the map canvas
|
||||
-------------------
|
||||
begin : Dec 2008
|
||||
copyright : (C) 2008 bySandro Furieri
|
||||
email : a.furieri@lqt.it
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsspatialitesourceselect.h"
|
||||
|
||||
#include "qgisapp.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgscontexthelp.h"
|
||||
|
||||
#include <QInputDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QSettings>
|
||||
#include <QTextStream>
|
||||
#include <QTableWidgetItem>
|
||||
#include <QHeaderView>
|
||||
#include <QStringList>
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
QgsSpatiaLiteSourceSelect::QgsSpatiaLiteSourceSelect(QgisApp * app, Qt::WFlags fl):
|
||||
QDialog(app, fl), qgisApp(app)
|
||||
{
|
||||
setupUi(this);
|
||||
btnAdd->setEnabled(false);
|
||||
populateConnectionList();
|
||||
|
||||
mSearchModeComboBox->addItem(tr("Wildcard"));
|
||||
mSearchModeComboBox->addItem(tr("RegExp"));
|
||||
|
||||
mSearchColumnComboBox->addItem(tr("All"));
|
||||
mSearchColumnComboBox->addItem(tr("Table"));
|
||||
mSearchColumnComboBox->addItem(tr("Type"));
|
||||
mSearchColumnComboBox->addItem(tr("Geometry column"));
|
||||
|
||||
mProxyModel.setParent(this);
|
||||
mProxyModel.setFilterKeyColumn(-1);
|
||||
mProxyModel.setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
mProxyModel.setDynamicSortFilter(true);
|
||||
mProxyModel.setSourceModel(&mTableModel);
|
||||
mTablesTreeView->setModel(&mProxyModel);
|
||||
mTablesTreeView->setSortingEnabled(true);
|
||||
|
||||
mSearchGroupBox->hide();
|
||||
|
||||
//for Qt < 4.3.2, passing -1 to include all model columns
|
||||
//in search does not seem to work
|
||||
mSearchColumnComboBox->setCurrentIndex(1);
|
||||
}
|
||||
|
||||
/** Autoconnected SLOTS **/
|
||||
// Slot for adding a new connection
|
||||
void QgsSpatiaLiteSourceSelect::on_btnNew_clicked()
|
||||
{
|
||||
addNewConnection();
|
||||
}
|
||||
|
||||
// Slot for deleting an existing connection
|
||||
void QgsSpatiaLiteSourceSelect::on_btnDelete_clicked()
|
||||
{
|
||||
deleteConnection();
|
||||
}
|
||||
|
||||
// Slot for performing action when the Add button is clicked
|
||||
void QgsSpatiaLiteSourceSelect::on_btnAdd_clicked()
|
||||
{
|
||||
addTables();
|
||||
}
|
||||
|
||||
// Slot for showing help
|
||||
void QgsSpatiaLiteSourceSelect::on_btnHelp_clicked()
|
||||
{
|
||||
showHelp();
|
||||
}
|
||||
|
||||
/** End Autoconnected SLOTS **/
|
||||
|
||||
// Remember which database is selected
|
||||
void QgsSpatiaLiteSourceSelect::on_cmbConnections_activated(int)
|
||||
{
|
||||
dbChanged();
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteSourceSelect::on_mSearchOptionsButton_clicked()
|
||||
{
|
||||
if (mSearchGroupBox->isVisible())
|
||||
{
|
||||
mSearchGroupBox->hide();
|
||||
} else
|
||||
{
|
||||
mSearchGroupBox->show();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteSourceSelect::on_mSearchTableEdit_textChanged(const QString & text)
|
||||
{
|
||||
if (mSearchModeComboBox->currentText() == tr("Wildcard"))
|
||||
{
|
||||
mProxyModel._setFilterWildcard(text);
|
||||
} else if (mSearchModeComboBox->currentText() == tr("RegExp"))
|
||||
{
|
||||
mProxyModel._setFilterRegExp(text);
|
||||
}
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteSourceSelect::on_mSearchColumnComboBox_currentIndexChanged(const QString & text)
|
||||
{
|
||||
if (text == tr("All"))
|
||||
{
|
||||
mProxyModel.setFilterKeyColumn(-1);
|
||||
} else if (text == tr("Table"))
|
||||
{
|
||||
mProxyModel.setFilterKeyColumn(0);
|
||||
} else if (text == tr("Type"))
|
||||
{
|
||||
mProxyModel.setFilterKeyColumn(1);
|
||||
} else if (text == tr("Geometry column"))
|
||||
{
|
||||
mProxyModel.setFilterKeyColumn(2);
|
||||
}
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteSourceSelect::on_mSearchModeComboBox_currentIndexChanged(const QString & text)
|
||||
{
|
||||
on_mSearchTableEdit_textChanged(mSearchTableEdit->text());
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteSourceSelect::setLayerType(QString table, QString column, QString type)
|
||||
{
|
||||
mTableModel.setGeometryTypesForTable(table, column, type);
|
||||
mTablesTreeView->sortByColumn(0, Qt::AscendingOrder);
|
||||
}
|
||||
|
||||
sqlite3 *QgsSpatiaLiteSourceSelect::openSpatiaLiteDb(const char *path)
|
||||
{
|
||||
sqlite3 *handle = NULL;
|
||||
bool gcSpatiaLite = false;
|
||||
bool rsSpatiaLite = false;
|
||||
bool tableName = false;
|
||||
bool geomColumn = false;
|
||||
bool coordDims = false;
|
||||
bool gcSrid = false;
|
||||
bool type = false;
|
||||
bool spatialIndex = false;
|
||||
bool srsSrid = false;
|
||||
bool authName = false;
|
||||
bool authSrid = false;
|
||||
bool refSysName = false;
|
||||
bool proj4text = false;
|
||||
int ret;
|
||||
const char *name;
|
||||
int i;
|
||||
char **results;
|
||||
int rows;
|
||||
int columns;
|
||||
char *errMsg = NULL;
|
||||
QString errCause;
|
||||
|
||||
// trying to open the SQLite DB
|
||||
mSqlitePath = path;
|
||||
|
||||
ret = sqlite3_open_v2(path, &handle, SQLITE_OPEN_READWRITE, NULL);
|
||||
if (ret)
|
||||
{
|
||||
// failure
|
||||
errCause = sqlite3_errmsg(handle);
|
||||
QMessageBox::critical(this, tr("SpatiaLite DB Open Error"),
|
||||
tr("Failure while connecting to: %1\n\n%2").arg(mSqlitePath).arg(errCause));
|
||||
mSqlitePath = "";
|
||||
return NULL;
|
||||
}
|
||||
// checking if table GEOMETRY_COLUMNS exists and has the expected layout
|
||||
ret = sqlite3_get_table(handle, "PRAGMA table_info(geometry_columns)", &results, &rows, &columns, &errMsg);
|
||||
if (ret != SQLITE_OK)
|
||||
goto error;
|
||||
if (rows < 1)
|
||||
;
|
||||
else
|
||||
{
|
||||
for (i = 1; i <= rows; i++)
|
||||
{
|
||||
name = results[(i * columns) + 1];
|
||||
if (strcasecmp(name, "f_table_name") == 0)
|
||||
tableName = true;
|
||||
if (strcasecmp(name, "f_geometry_column") == 0)
|
||||
geomColumn = true;
|
||||
if (strcasecmp(name, "coord_dimension") == 0)
|
||||
coordDims = true;
|
||||
if (strcasecmp(name, "srid") == 0)
|
||||
gcSrid = true;
|
||||
if (strcasecmp(name, "type") == 0)
|
||||
type = true;
|
||||
if (strcasecmp(name, "spatial_index_enabled") == 0)
|
||||
spatialIndex = true;
|
||||
}
|
||||
}
|
||||
sqlite3_free_table(results);
|
||||
if (tableName == true && geomColumn == true && type == true && coordDims == true && gcSrid == true && spatialIndex == true)
|
||||
gcSpatiaLite = true;
|
||||
|
||||
// checking if table SPATIAL_REF_SYS exists and has the expected layout
|
||||
ret = sqlite3_get_table(handle, "PRAGMA table_info(spatial_ref_sys)", &results, &rows, &columns, &errMsg);
|
||||
if (ret != SQLITE_OK)
|
||||
goto error;
|
||||
if (rows < 1)
|
||||
;
|
||||
else
|
||||
{
|
||||
for (i = 1; i <= rows; i++)
|
||||
{
|
||||
name = results[(i * columns) + 1];
|
||||
if (strcasecmp(name, "srid") == 0)
|
||||
srsSrid = true;
|
||||
if (strcasecmp(name, "auth_name") == 0)
|
||||
authName = true;
|
||||
if (strcasecmp(name, "auth_srid") == 0)
|
||||
authSrid = true;
|
||||
if (strcasecmp(name, "ref_sys_name") == 0)
|
||||
refSysName = true;
|
||||
if (strcasecmp(name, "proj4text") == 0)
|
||||
proj4text = true;
|
||||
}
|
||||
}
|
||||
sqlite3_free_table(results);
|
||||
if (srsSrid == true && authName == true && authSrid == true && refSysName == true && proj4text == true)
|
||||
rsSpatiaLite = true;
|
||||
|
||||
// OK, this one seems to be a valid SpatiaLite DB
|
||||
if (gcSpatiaLite == true && rsSpatiaLite == true)
|
||||
return handle;
|
||||
|
||||
// this one cannot be a valid SpatiaLite DB - no Spatial MetaData where found
|
||||
closeSpatiaLiteDb(handle);
|
||||
errCause = tr("seems to be a valid SQLite DB, but not a SpatiaLite's one ...");
|
||||
QMessageBox::critical(this, tr("SpatiaLite DB Open Error"),
|
||||
tr("Failure while connecting to: %1\n\n%2").arg(mSqlitePath).arg(errCause));
|
||||
mSqlitePath = "";
|
||||
return NULL;
|
||||
|
||||
error:
|
||||
// unexpected IO error
|
||||
closeSpatiaLiteDb(handle);
|
||||
errCause = tr("unknown error cause");
|
||||
if (errMsg != NULL)
|
||||
{
|
||||
errCause = errMsg;
|
||||
sqlite3_free(errMsg);
|
||||
}
|
||||
QMessageBox::critical(this, tr("SpatiaLite DB Open Error"),
|
||||
tr("Failure while connecting to: %1\n\n%2").arg(mSqlitePath).arg(errCause));
|
||||
mSqlitePath = "";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteSourceSelect::closeSpatiaLiteDb(sqlite3 * handle)
|
||||
{
|
||||
if (handle)
|
||||
sqlite3_close(handle);
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteSourceSelect::populateConnectionList()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.beginGroup("/SpatiaLite/connections");
|
||||
QStringList keys = settings.childGroups();
|
||||
QStringList::Iterator it = keys.begin();
|
||||
cmbConnections->clear();
|
||||
while (it != keys.end())
|
||||
{
|
||||
// retrieving the SQLite DB name and full path
|
||||
QString text = *it + tr(" @ ");
|
||||
text += settings.value(*it + tr("/sqlitepath"), "###unknown###").toString();
|
||||
|
||||
cmbConnections->addItem(text);
|
||||
++it;
|
||||
}
|
||||
settings.endGroup();
|
||||
setConnectionListPosition();
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteSourceSelect::addNewConnection()
|
||||
{
|
||||
// Retrieve last used project dir from persistent settings
|
||||
sqlite3 *handle;
|
||||
char *path = NULL;
|
||||
int sz;
|
||||
QSettings settings;
|
||||
QString fullPath;
|
||||
QString lastUsedDir = settings.value("/UI/lastSpatiaLiteDir", ".").toString();
|
||||
|
||||
QFileDialog *openFileDialog = new QFileDialog(this,
|
||||
tr("Choose a SpatiaLite/SQLite DB to open"),
|
||||
lastUsedDir, QObject::tr("SQLite DB (*.sqlite);;All files (*.*)"));
|
||||
openFileDialog->setFileMode(QFileDialog::ExistingFile);
|
||||
|
||||
if (openFileDialog->exec() == QDialog::Accepted)
|
||||
{
|
||||
fullPath = openFileDialog->selectedFiles().first();
|
||||
QFileInfo myFI(fullPath);
|
||||
QString myPath = myFI.path();
|
||||
QString myName = myFI.fileName();
|
||||
|
||||
// transforming full path as char *
|
||||
QByteArray utf8 = fullPath.toUtf8();
|
||||
sz = utf8.size();
|
||||
path = new char[sz + 1];
|
||||
memcpy(path, utf8.data(), sz);
|
||||
path[sz] = '\0';
|
||||
handle = openSpatiaLiteDb(path);
|
||||
if (handle)
|
||||
{
|
||||
// OK, this one is a valid SpatiaLite DB
|
||||
closeSpatiaLiteDb(handle);
|
||||
|
||||
// Persist last used SpatiaLite dir
|
||||
settings.setValue("/UI/lastSpatiaLiteDir", myPath);
|
||||
// inserting this SQLite DB path
|
||||
QString baseKey = "/SpatiaLite/connections/";
|
||||
settings.setValue(baseKey + "selected", myName);
|
||||
baseKey += myName;
|
||||
settings.setValue(baseKey + "/sqlitepath", fullPath);
|
||||
}
|
||||
} else
|
||||
{
|
||||
// if they didn't select anything, just return
|
||||
delete openFileDialog;
|
||||
return;
|
||||
}
|
||||
|
||||
delete openFileDialog;
|
||||
if (path != NULL)
|
||||
delete path;
|
||||
populateConnectionList();
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteSourceSelect::deleteConnection()
|
||||
{
|
||||
QSettings settings;
|
||||
QString subKey = cmbConnections->currentText();
|
||||
int idx = subKey.indexOf(" @ ");
|
||||
if (idx > 0)
|
||||
subKey.truncate(idx);
|
||||
|
||||
QString key = "/SpatiaLite/connections/" + subKey;
|
||||
QString msg = tr("Are you sure you want to remove the ") + subKey + tr(" connection and all associated settings?");
|
||||
QMessageBox::StandardButton result =
|
||||
QMessageBox::information(this, tr("Confirm Delete"), msg, QMessageBox::Ok | QMessageBox::Cancel);
|
||||
if (result == QMessageBox::Ok)
|
||||
{
|
||||
settings.remove(key + "/sqlitepath");
|
||||
settings.remove(key);
|
||||
//if(!success){
|
||||
// QMessageBox::information(this,"Unable to Remove","Unable to remove the connection " + cmbConnections->currentText());
|
||||
//}
|
||||
cmbConnections->removeItem(cmbConnections->currentIndex()); // populateConnectionList();
|
||||
setConnectionListPosition();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteSourceSelect::addTables()
|
||||
{
|
||||
m_selectedTables.clear();
|
||||
|
||||
typedef QMap < int, QVector < QString > >schemaInfo;
|
||||
QMap < QString, schemaInfo > dbInfo;
|
||||
|
||||
QItemSelection selection = mTablesTreeView->selectionModel()->selection();
|
||||
QModelIndexList selectedIndices = selection.indexes();
|
||||
QStandardItem *currentItem = 0;
|
||||
|
||||
QModelIndexList::const_iterator selected_it = selectedIndices.constBegin();
|
||||
for (; selected_it != selectedIndices.constEnd(); ++selected_it)
|
||||
{
|
||||
if (!selected_it->parent().isValid())
|
||||
{
|
||||
//top level items only contain the schema names
|
||||
continue;
|
||||
}
|
||||
currentItem = mTableModel.itemFromIndex(mProxyModel.mapToSource(*selected_it));
|
||||
if (!currentItem)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QString currentSchemaName = currentItem->parent()->text();
|
||||
|
||||
int currentRow = currentItem->row();
|
||||
int currentColumn = currentItem->column();
|
||||
|
||||
if (dbInfo[currentSchemaName][currentRow].size() == 0)
|
||||
{
|
||||
dbInfo[currentSchemaName][currentRow].resize(5);
|
||||
}
|
||||
|
||||
dbInfo[currentSchemaName][currentRow][currentColumn] = currentItem->text();
|
||||
}
|
||||
|
||||
//now traverse all the schemas and table infos
|
||||
QString tableName, geomColumnName;
|
||||
QString query;
|
||||
|
||||
QMap < QString, schemaInfo >::const_iterator schema_it = dbInfo.constBegin();
|
||||
for (; schema_it != dbInfo.constEnd(); ++schema_it)
|
||||
{
|
||||
schemaInfo scheme = schema_it.value();
|
||||
schemaInfo::const_iterator entry_it = scheme.constBegin();
|
||||
for (; entry_it != scheme.constEnd(); ++entry_it)
|
||||
{
|
||||
tableName = entry_it->at(0);
|
||||
geomColumnName = entry_it->at(2);
|
||||
|
||||
query = "\"" + tableName + "\" (" + geomColumnName;
|
||||
m_selectedTables.push_back(query);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_selectedTables.empty())
|
||||
{
|
||||
QMessageBox::information(this, tr("Select Table"), tr("You must select a table in order to add a Layer."));
|
||||
} else
|
||||
{
|
||||
accept();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteSourceSelect::on_btnConnect_clicked()
|
||||
{
|
||||
sqlite3 *handle;
|
||||
char *path = NULL;
|
||||
int sz;
|
||||
|
||||
QSettings settings;
|
||||
QString subKey = cmbConnections->currentText();
|
||||
int idx = subKey.indexOf(" @ ");
|
||||
if (idx > 0)
|
||||
subKey.truncate(idx);
|
||||
|
||||
QString key = "/SpatiaLite/connections/" + subKey;
|
||||
|
||||
QString fullPath = settings.value(key + "/sqlitepath").toString();
|
||||
|
||||
// transforming full path as char *
|
||||
QByteArray utf8 = fullPath.toUtf8();
|
||||
sz = utf8.size();
|
||||
path = new char[sz + 1];
|
||||
memcpy(path, utf8.data(), sz);
|
||||
path[sz] = '\0';
|
||||
|
||||
// trying to connect to SpatiaLite DB
|
||||
handle = openSpatiaLiteDb(path);
|
||||
if (handle == NULL)
|
||||
{
|
||||
// unexpected error; invalid SpatiaLite DB
|
||||
delete path;
|
||||
return;
|
||||
}
|
||||
delete path;
|
||||
|
||||
QModelIndex rootItemIndex = mTableModel.indexFromItem(mTableModel.invisibleRootItem());
|
||||
mTableModel.removeRows(0, mTableModel.rowCount(rootItemIndex), rootItemIndex);
|
||||
|
||||
// populate the table list
|
||||
// get the list of suitable tables and columns and populate the UI
|
||||
geomCol details;
|
||||
|
||||
if (getTableInfo(handle) == true)
|
||||
;
|
||||
else
|
||||
{
|
||||
qDebug("Unable to get list of spatially enabled tables from the database");
|
||||
qDebug(sqlite3_errmsg(handle));
|
||||
}
|
||||
closeSpatiaLiteDb(handle);
|
||||
|
||||
// BEGIN CHANGES ECOS
|
||||
if (cmbConnections->count() > 0)
|
||||
btnAdd->setEnabled(true);
|
||||
// END CHANGES ECOS
|
||||
|
||||
mTablesTreeView->sortByColumn(0, Qt::AscendingOrder);
|
||||
mTablesTreeView->header()->resizeSection(1, 140);
|
||||
mTablesTreeView->resizeColumnToContents(0);
|
||||
|
||||
//expand all the toplevel items
|
||||
int numTopLevelItems = mTableModel.invisibleRootItem()->rowCount();
|
||||
for (int i = 0; i < numTopLevelItems; ++i)
|
||||
{
|
||||
mTablesTreeView->expand(mProxyModel.mapFromSource(mTableModel.indexFromItem(mTableModel.invisibleRootItem()->child(i))));
|
||||
}
|
||||
}
|
||||
|
||||
QStringList QgsSpatiaLiteSourceSelect::selectedTables()
|
||||
{
|
||||
return m_selectedTables;
|
||||
}
|
||||
|
||||
QString QgsSpatiaLiteSourceSelect::connectionInfo()
|
||||
{
|
||||
return mSqlitePath;
|
||||
}
|
||||
|
||||
bool QgsSpatiaLiteSourceSelect::getTableInfo(sqlite3 * handle)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
char **results;
|
||||
int rows;
|
||||
int columns;
|
||||
char *errMsg = NULL;
|
||||
bool ok = false;
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
||||
// setting the SQLite DB name
|
||||
QFileInfo myFI(mSqlitePath);
|
||||
QString myName = myFI.fileName();
|
||||
mTableModel.setSqliteDb(myName);
|
||||
|
||||
// the following query return the tables containing a Geometry column
|
||||
ret = sqlite3_get_table(handle,
|
||||
"SELECT f_table_name, f_geometry_column, type FROM geometry_columns", &results, &rows, &columns, &errMsg);
|
||||
if (ret != SQLITE_OK)
|
||||
goto error;
|
||||
if (rows < 1)
|
||||
;
|
||||
else
|
||||
{
|
||||
for (i = 1; i <= rows; i++)
|
||||
{
|
||||
QString tableName = results[(i * columns) + 0];
|
||||
QString column = results[(i * columns) + 1];
|
||||
QString type = results[(i * columns) + 2];
|
||||
|
||||
mTableModel.addTableEntry(type, tableName, column);
|
||||
}
|
||||
ok = true;
|
||||
}
|
||||
sqlite3_free_table(results);
|
||||
|
||||
QApplication::restoreOverrideCursor();
|
||||
return ok;
|
||||
|
||||
error:
|
||||
// unexpected IO error
|
||||
QString errCause = tr("unknown error cause");
|
||||
if (errMsg != NULL)
|
||||
{
|
||||
errCause = errMsg;
|
||||
sqlite3_free(errMsg);
|
||||
}
|
||||
QMessageBox::critical(this, tr("SpatiaLite getTableInfo Error"),
|
||||
tr("Failure exploring tables from: %1\n\n%2").arg(mSqlitePath).arg(errCause));
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteSourceSelect::showHelp()
|
||||
{
|
||||
QgsContextHelp::run(context_id);
|
||||
}
|
||||
|
||||
QString QgsSpatiaLiteSourceSelect::fullDescription(QString table, QString column, QString type)
|
||||
{
|
||||
QString full_desc = "";
|
||||
full_desc += table + "\" (" + column + ") " + type;
|
||||
return full_desc;
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteSourceSelect::dbChanged()
|
||||
{
|
||||
// Remember which database was selected.
|
||||
QSettings settings;
|
||||
settings.setValue("/SpatiaLite/connections/selected", cmbConnections->currentText());
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteSourceSelect::setConnectionListPosition()
|
||||
{
|
||||
QSettings settings;
|
||||
// If possible, set the item currently displayed database
|
||||
QString toSelect = settings.value("/SpatiaLite/connections/selected").toString();
|
||||
// Does toSelect exist in cmbConnections?
|
||||
bool set = false;
|
||||
for (int i = 0; i < cmbConnections->count(); ++i)
|
||||
if (cmbConnections->itemText(i) == toSelect)
|
||||
{
|
||||
cmbConnections->setCurrentIndex(i);
|
||||
set = true;
|
||||
break;
|
||||
}
|
||||
// If we couldn't find the stored item, but there are some,
|
||||
// default to the last item (this makes some sense when deleting
|
||||
// items as it allows the user to repeatidly click on delete to
|
||||
// remove a whole lot of items).
|
||||
if (!set && cmbConnections->count() > 0)
|
||||
{
|
||||
// If toSelect is null, then the selected connection wasn't found
|
||||
// by QSettings, which probably means that this is the first time
|
||||
// the user has used qgis with database connections, so default to
|
||||
// the first in the list of connetions. Otherwise default to the last.
|
||||
if (toSelect.isNull())
|
||||
cmbConnections->setCurrentIndex(0);
|
||||
else
|
||||
cmbConnections->setCurrentIndex(cmbConnections->count() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteSourceSelect::setSearchExpression(const QString & regexp)
|
||||
{
|
||||
}
|
137
src/app/qgsspatialitesourceselect.h
Normal file
137
src/app/qgsspatialitesourceselect.h
Normal file
@ -0,0 +1,137 @@
|
||||
/***************************************************************************
|
||||
qgspatialitesourceselect.h - description
|
||||
-------------------
|
||||
begin : Dec 2008
|
||||
copyright : (C) 2008 by Sandro Furieri
|
||||
email : a.furieri@lqt.it
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGSSPATIALITESOURCESELECT_H
|
||||
#define QGSSPATIALITESOURCESELECT_H
|
||||
#include "ui_qgsspatialitesourceselectbase.h"
|
||||
|
||||
#include "qgisgui.h"
|
||||
#include "qgsspatialitefilterproxymodel.h"
|
||||
#include "qgsspatialitetablemodel.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <spatialite/sqlite3.h>
|
||||
}
|
||||
|
||||
#include <QThread>
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <utility>
|
||||
|
||||
#include <QMap>
|
||||
#include <QPair>
|
||||
#include <QIcon>
|
||||
#include <QFileDialog>
|
||||
|
||||
class QStringList;
|
||||
class QTableWidgetItem;
|
||||
class QgisApp;
|
||||
|
||||
/*! \class QgsSpatiaLiteSourceSelect
|
||||
* \brief Dialog to create connections and add tables from SpatiaLite.
|
||||
*
|
||||
* This dialog allows the user to define and save connection information
|
||||
* for SpatiaLite/SQLite databases. The user can then connect and add
|
||||
* tables from the database to the map canvas.
|
||||
*/
|
||||
class QgsSpatiaLiteSourceSelect:public QDialog, private Ui::QgsSpatiaLiteSourceSelectBase
|
||||
{
|
||||
Q_OBJECT public:
|
||||
|
||||
//! Constructor
|
||||
QgsSpatiaLiteSourceSelect(QgisApp * app, Qt::WFlags fl = QgisGui::ModalDialogFlags);
|
||||
//! Destructor
|
||||
~QgsSpatiaLiteSourceSelect()
|
||||
{
|
||||
;
|
||||
}
|
||||
//! Opens the create connection dialog to build a new connection
|
||||
void addNewConnection();
|
||||
//! Deletes the selected connection
|
||||
void deleteConnection();
|
||||
//! Populate the connection list combo box
|
||||
void populateConnectionList();
|
||||
//! Determines the tables the user selected and closes the dialog
|
||||
void addTables();
|
||||
//! String list containing the selected tables
|
||||
QStringList selectedTables();
|
||||
//! Connection info (DB-path)
|
||||
QString connectionInfo();
|
||||
// Store the selected database
|
||||
void dbChanged();
|
||||
|
||||
public slots:
|
||||
/*! Connects to the database using the stored connection parameters.
|
||||
* Once connected, available layers are displayed.
|
||||
*/
|
||||
void on_btnConnect_clicked();
|
||||
void on_btnAdd_clicked();
|
||||
void on_btnNew_clicked();
|
||||
void on_btnDelete_clicked();
|
||||
void on_mSearchOptionsButton_clicked();
|
||||
void on_mSearchTableEdit_textChanged(const QString & text);
|
||||
void on_mSearchColumnComboBox_currentIndexChanged(const QString & text);
|
||||
void on_mSearchModeComboBox_currentIndexChanged(const QString & text);
|
||||
void on_btnHelp_clicked();
|
||||
void on_cmbConnections_activated(int);
|
||||
void setLayerType(QString table, QString column, QString type);
|
||||
//!Sets a new regular expression to the model
|
||||
void setSearchExpression(const QString & regexp);
|
||||
|
||||
private:
|
||||
enum columns
|
||||
{
|
||||
dbssType = 0,
|
||||
dbssDetail,
|
||||
dbssSql,
|
||||
dbssColumns,
|
||||
};
|
||||
|
||||
typedef std::pair < QString, QString > geomPair;
|
||||
typedef std::list < geomPair > geomCol;
|
||||
|
||||
/**Inserts information about the spatial tables into mTableModel*/
|
||||
bool getTableInfo(sqlite3 * handle);
|
||||
|
||||
// SpatiaLite DB open / close
|
||||
sqlite3 *openSpatiaLiteDb(const char *path);
|
||||
void closeSpatiaLiteDb(sqlite3 * handle);
|
||||
|
||||
// Set the position of the database connection list to the last
|
||||
// used one.
|
||||
void setConnectionListPosition();
|
||||
// Show the context help for the dialog
|
||||
void showHelp();
|
||||
// Combine the table and column data into a single string
|
||||
// useful for display to the user
|
||||
QString fullDescription(QString table, QString column, QString type);
|
||||
// The column labels
|
||||
QStringList mColumnLabels;
|
||||
QString mSqlitePath;
|
||||
QStringList m_selectedTables;
|
||||
// Storage for the range of layer type icons
|
||||
QMap < QString, QPair < QString, QIcon > >mLayerIcons;
|
||||
//! Pointer to the qgis application mainwindow
|
||||
QgisApp *qgisApp;
|
||||
static const int context_id = 250632828;
|
||||
//! Model that acts as datasource for mTableTreeWidget
|
||||
QgsSpatiaLiteTableModel mTableModel;
|
||||
QgsSpatiaLiteFilterProxyModel mProxyModel;
|
||||
};
|
||||
|
||||
#endif // QGSSPATIALITESOURCESELECT_H
|
204
src/app/qgsspatialitetablemodel.cpp
Normal file
204
src/app/qgsspatialitetablemodel.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
/***************************************************************************
|
||||
qgsspatialitetablemodel.cpp - description
|
||||
-------------------
|
||||
begin : Dec 2008
|
||||
copyright : (C) 2008 by Sandro Furieri
|
||||
email : a.furieri@lqt.it
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsspatialitetablemodel.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgisapp.h"
|
||||
|
||||
QgsSpatiaLiteTableModel::QgsSpatiaLiteTableModel():QStandardItemModel(), mTableCount(0)
|
||||
{
|
||||
QStringList headerLabels;
|
||||
headerLabels << tr("Table");
|
||||
headerLabels << tr("Type");
|
||||
headerLabels << tr("Geometry column");
|
||||
setHorizontalHeaderLabels(headerLabels);
|
||||
}
|
||||
|
||||
QgsSpatiaLiteTableModel::~QgsSpatiaLiteTableModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteTableModel::addTableEntry(QString type, QString tableName, QString geometryColName)
|
||||
{
|
||||
//is there already a root item ?
|
||||
QStandardItem *dbItem;
|
||||
QList < QStandardItem * >dbItems = findItems(mSqliteDb, Qt::MatchExactly, 0);
|
||||
|
||||
//there is already an item
|
||||
if (dbItems.size() > 0)
|
||||
{
|
||||
dbItem = dbItems.at(0);
|
||||
} else //create a new toplevel item
|
||||
{
|
||||
dbItem = new QStandardItem(mSqliteDb);
|
||||
dbItem->setFlags(Qt::ItemIsEnabled);
|
||||
invisibleRootItem()->setChild(invisibleRootItem()->rowCount(), dbItem);
|
||||
}
|
||||
|
||||
//path to icon for specified type
|
||||
QString typeName;
|
||||
|
||||
QGis::WkbType wkbType = qgisTypeFromDbType(type);
|
||||
QIcon iconFile = iconForType(wkbType);
|
||||
|
||||
QList < QStandardItem * >childItemList;
|
||||
QStandardItem *typeItem = new QStandardItem(QIcon(iconFile), type);
|
||||
typeItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
|
||||
QStandardItem *tableItem = new QStandardItem(tableName);
|
||||
tableItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
|
||||
QStandardItem *geomItem = new QStandardItem(geometryColName);
|
||||
geomItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
|
||||
|
||||
|
||||
childItemList.push_back(tableItem);
|
||||
childItemList.push_back(typeItem);
|
||||
childItemList.push_back(geomItem);
|
||||
|
||||
dbItem->appendRow(childItemList);
|
||||
++mTableCount;
|
||||
}
|
||||
|
||||
void QgsSpatiaLiteTableModel::setGeometryTypesForTable(const QString & table, const QString & attribute, const QString & type)
|
||||
{
|
||||
bool typeIsEmpty = type.isEmpty(); //true means the table has no valid geometry entry and the item for this table should be removed
|
||||
QStringList typeList = type.split(",");
|
||||
|
||||
//find schema item and table item
|
||||
QStandardItem *dbItem;
|
||||
QList < QStandardItem * >dbItems = findItems(mSqliteDb, Qt::MatchExactly, 0);
|
||||
|
||||
if (dbItems.size() < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
dbItem = dbItems.at(0);
|
||||
int numChildren = dbItem->rowCount();
|
||||
|
||||
QModelIndex currentChildIndex;
|
||||
QModelIndex currentTableIndex;
|
||||
QModelIndex currentTypeIndex;
|
||||
QModelIndex currentGeomColumnIndex;
|
||||
|
||||
for (int i = 0; i < numChildren; ++i)
|
||||
{
|
||||
currentChildIndex = indexFromItem(dbItem->child(i, 0));
|
||||
if (!currentChildIndex.isValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
currentTableIndex = currentChildIndex.sibling(i, 1);
|
||||
currentTypeIndex = currentChildIndex.sibling(i, 2);
|
||||
currentGeomColumnIndex = currentChildIndex.sibling(i, 3);
|
||||
QString geomColText = itemFromIndex(currentGeomColumnIndex)->text();
|
||||
|
||||
if (!currentTypeIndex.isValid() || !currentTableIndex.isValid() || !currentGeomColumnIndex.isValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (itemFromIndex(currentTableIndex)->text() == table &&
|
||||
(geomColText == attribute || geomColText.startsWith(attribute + " AS ")))
|
||||
{
|
||||
if (typeIsEmpty)
|
||||
{
|
||||
removeRow(i, indexFromItem(dbItem));
|
||||
return;
|
||||
}
|
||||
|
||||
QGis::WkbType wkbType = qgisTypeFromDbType(typeList.at(0));
|
||||
QIcon myIcon = iconForType(wkbType);
|
||||
itemFromIndex(currentTypeIndex)->setText(typeList.at(0)); //todo: add other rows
|
||||
itemFromIndex(currentTypeIndex)->setIcon(myIcon);
|
||||
if (!geomColText.contains(" AS "))
|
||||
{
|
||||
itemFromIndex(currentGeomColumnIndex)->setText(geomColText + " AS " + typeList.at(0));
|
||||
}
|
||||
|
||||
for (int j = 1; j < typeList.size(); ++j)
|
||||
{
|
||||
//todo: add correct type
|
||||
addTableEntry(typeList.at(j), table, geomColText + " AS " + typeList.at(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QIcon QgsSpatiaLiteTableModel::iconForType(QGis::WkbType type) const
|
||||
{
|
||||
if (type == QGis::WKBPoint || type == QGis::WKBPoint25D || type == QGis::WKBMultiPoint || type == QGis::WKBMultiPoint25D)
|
||||
{
|
||||
return QgisApp::getThemeIcon("/mIconPointLayer.png");
|
||||
} else if (type == QGis::WKBLineString || type == QGis::WKBLineString25D || type == QGis::WKBMultiLineString
|
||||
|| type == QGis::WKBMultiLineString25D)
|
||||
{
|
||||
return QgisApp::getThemeIcon("/mIconLineLayer.png");
|
||||
} else if (type == QGis::WKBPolygon || type == QGis::WKBPolygon25D || type == QGis::WKBMultiPolygon
|
||||
|| type == QGis::WKBMultiPolygon25D)
|
||||
{
|
||||
return QgisApp::getThemeIcon("/mIconPolygonLayer.png");
|
||||
} else
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
QString QgsSpatiaLiteTableModel::displayStringForType(QGis::WkbType type) const
|
||||
{
|
||||
if (type == QGis::WKBPoint || type == QGis::WKBPoint25D)
|
||||
{
|
||||
return tr("Point");
|
||||
} else if (type == QGis::WKBMultiPoint || type == QGis::WKBMultiPoint25D)
|
||||
{
|
||||
return tr("Multipoint");
|
||||
} else if (type == QGis::WKBLineString || type == QGis::WKBLineString25D)
|
||||
{
|
||||
return tr("Line");
|
||||
} else if (type == QGis::WKBMultiLineString || type == QGis::WKBMultiLineString25D)
|
||||
{
|
||||
return tr("Multiline");
|
||||
} else if (type == QGis::WKBPolygon || type == QGis::WKBPolygon25D)
|
||||
{
|
||||
return tr("Polygon");
|
||||
} else if (type == QGis::WKBMultiPolygon || type == QGis::WKBMultiPolygon25D)
|
||||
{
|
||||
return tr("Multipolygon");
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
QGis::WkbType QgsSpatiaLiteTableModel::qgisTypeFromDbType(const QString & dbType) const
|
||||
{
|
||||
if (dbType == "POINT")
|
||||
{
|
||||
return QGis::WKBPoint;
|
||||
} else if (dbType == "MULTIPOINT")
|
||||
{
|
||||
return QGis::WKBMultiPoint;
|
||||
} else if (dbType == "LINESTRING")
|
||||
{
|
||||
return QGis::WKBLineString;
|
||||
} else if (dbType == "MULTILINESTRING")
|
||||
{
|
||||
return QGis::WKBMultiLineString;
|
||||
} else if (dbType == "POLYGON")
|
||||
{
|
||||
return QGis::WKBPolygon;
|
||||
} else if (dbType == "MULTIPOLYGON")
|
||||
{
|
||||
return QGis::WKBMultiPolygon;
|
||||
}
|
||||
return QGis::WKBUnknown;
|
||||
}
|
56
src/app/qgsspatialitetablemodel.h
Normal file
56
src/app/qgsspatialitetablemodel.h
Normal file
@ -0,0 +1,56 @@
|
||||
/***************************************************************************
|
||||
qgsspatialitetablemodel.h - description
|
||||
-------------------
|
||||
begin : Dec 2008
|
||||
copyright : (C) 2008 by Sandro Furieri
|
||||
email : a.furieri@lqt.it
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QStandardItemModel>
|
||||
class QIcon;
|
||||
#include "qgis.h"
|
||||
|
||||
/**A model that holds the tables of a database in a hierarchy where the
|
||||
SQLite DB is the root elements that contain the individual tables as children.
|
||||
The tables have the following columns: Type, Tablename, Geometry Column*/
|
||||
class QgsSpatiaLiteTableModel:public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT public:
|
||||
|
||||
QgsSpatiaLiteTableModel();
|
||||
~QgsSpatiaLiteTableModel();
|
||||
/**Adds entry for one database table to the model*/
|
||||
void addTableEntry(QString type, QString tableName, QString geometryColName);
|
||||
/**Sets one or more geometry types to a row. In case of several types, additional rows are inserted.
|
||||
This is for tables where the type is dectected later by thread*/
|
||||
void setGeometryTypesForTable(const QString & table, const QString & attribute, const QString & type);
|
||||
/**Returns the number of tables in the model*/
|
||||
int tableCount() const
|
||||
{
|
||||
return mTableCount;
|
||||
}
|
||||
/** Sets the SQLite DB full path*/
|
||||
void setSqliteDb(const QString & dbName)
|
||||
{
|
||||
mSqliteDb = dbName;
|
||||
}
|
||||
|
||||
private:
|
||||
/**Number of tables in the model*/
|
||||
int mTableCount;
|
||||
QString mSqliteDb;
|
||||
|
||||
QIcon iconForType(QGis::WkbType type) const;
|
||||
QString displayStringForType(QGis::WkbType type) const;
|
||||
/**Returns qgis wkbtype from database typename*/
|
||||
QGis::WkbType qgisTypeFromDbType(const QString & dbType) const;
|
||||
};
|
@ -5,6 +5,10 @@ IF (POSTGRES_FOUND)
|
||||
SUBDIRS (postgres)
|
||||
ENDIF (POSTGRES_FOUND)
|
||||
|
||||
IF (SPATIALITE_FOUND)
|
||||
SUBDIRS (spatialite)
|
||||
ENDIF (SPATIALITE_FOUND)
|
||||
|
||||
IF (EXPAT_FOUND)
|
||||
SUBDIRS (gpx wfs)
|
||||
ENDIF (EXPAT_FOUND)
|
||||
|
36
src/providers/spatialite/CMakeLists.txt
Normal file
36
src/providers/spatialite/CMakeLists.txt
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
########################################################
|
||||
# Files
|
||||
|
||||
SET(SPATIALITE_SRCS qgsspatialiteprovider.cpp)
|
||||
|
||||
SET(SPATIALITE_MOC_HDRS qgsspatialiteprovider.h)
|
||||
|
||||
|
||||
########################################################
|
||||
# Build
|
||||
|
||||
QT4_WRAP_CPP(SPATIALITE_MOC_SRCS ${SPATIALITE_MOC_HDRS})
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
../../core
|
||||
${SPATIALITE_INCLUDE_DIR}
|
||||
${SPATIALITE_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
ADD_LIBRARY (spatialiteprovider MODULE ${SPATIALITE_SRCS} ${SPATIALITE_MOC_SRCS})
|
||||
|
||||
TARGET_LINK_LIBRARIES(spatialiteprovider
|
||||
${QT_QTCORE_LIBRARY}
|
||||
${QT_QTXML_LIBRARY}
|
||||
${SPATIALITE_LIBRARY}
|
||||
qgis_core
|
||||
)
|
||||
|
||||
|
||||
########################################################
|
||||
# Install
|
||||
|
||||
INSTALL(TARGETS spatialiteprovider
|
||||
RUNTIME DESTINATION ${QGIS_PLUGIN_DIR}
|
||||
LIBRARY DESTINATION ${QGIS_PLUGIN_DIR})
|
1564
src/providers/spatialite/qgsspatialiteprovider.cpp
Normal file
1564
src/providers/spatialite/qgsspatialiteprovider.cpp
Normal file
File diff suppressed because it is too large
Load Diff
364
src/providers/spatialite/qgsspatialiteprovider.h
Normal file
364
src/providers/spatialite/qgsspatialiteprovider.h
Normal file
@ -0,0 +1,364 @@
|
||||
/***************************************************************************
|
||||
qgsspatialiteprovider.h Data provider for SpatiaLite DBMS
|
||||
begin : Dec 2008
|
||||
copyright : (C) 2008 Sandro Furieri
|
||||
email : a.furieri@lqt.it
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <spatialite/sqlite3.h>
|
||||
#include <spatialite/gaiageo.h>
|
||||
#include <spatialite.h>
|
||||
}
|
||||
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsrectangle.h"
|
||||
#include <list>
|
||||
#include <queue>
|
||||
#include <fstream>
|
||||
#include <set>
|
||||
|
||||
class QgsFeature;
|
||||
class QgsField;
|
||||
|
||||
#include "qgsdatasourceuri.h"
|
||||
|
||||
/**
|
||||
\class QgsSpatiaLiteProvider
|
||||
\brief Data provider for SQLite/SpatiaLite layers.
|
||||
|
||||
This provider implements the
|
||||
interface defined in the QgsDataProvider class to provide access to spatial
|
||||
data residing in a SQLite/SpatiaLite enabled database.
|
||||
*/
|
||||
class QgsSpatiaLiteProvider:public QgsVectorDataProvider
|
||||
{
|
||||
Q_OBJECT public:
|
||||
/**
|
||||
* Constructor of the vector provider
|
||||
* @param uri uniform resource locator (URI) for a dataset
|
||||
*/
|
||||
QgsSpatiaLiteProvider(QString const &uri = "");
|
||||
|
||||
//! Destructor
|
||||
virtual ~ QgsSpatiaLiteProvider();
|
||||
|
||||
/**
|
||||
* Returns the permanent storage type for this layer as a friendly name.
|
||||
*/
|
||||
virtual QString storageType() const;
|
||||
|
||||
/*! Get the QgsCoordinateReferenceSystem for this layer
|
||||
* @note Must be reimplemented by each provider.
|
||||
* If the provider isn't capable of returning
|
||||
* its projection an empty srs will be return, ti will return 0
|
||||
*/
|
||||
virtual QgsCoordinateReferenceSystem crs();
|
||||
|
||||
/** Select features based on a bounding rectangle. Features can be retrieved with calls to nextFeature.
|
||||
* @param fetchAttributes list of attributes which should be fetched
|
||||
* @param rect spatial filter
|
||||
* @param fetchGeometry true if the feature geometry should be fetched
|
||||
* @param useIntersect true if an accurate intersection test should be used,
|
||||
* false if a test based on bounding box is sufficient
|
||||
*/
|
||||
virtual bool featureAtId(int featureId,
|
||||
QgsFeature & feature, bool fetchGeometry = true, QgsAttributeList fetchAttributes = QgsAttributeList());
|
||||
/** Select features based on a bounding rectangle. Features can be retrieved with calls to nextFeature.
|
||||
* @param fetchAttributes list of attributes which should be fetched
|
||||
* @param rect spatial filter
|
||||
* @param fetchGeometry true if the feature geometry should be fetched
|
||||
* @param useIntersect true if an accurate intersection test should be used,
|
||||
* false if a test based on bounding box is sufficient
|
||||
*/
|
||||
virtual void select(QgsAttributeList fetchAttributes = QgsAttributeList(),
|
||||
QgsRectangle rect = QgsRectangle(), bool fetchGeometry = true, bool useIntersect = false);
|
||||
|
||||
/**
|
||||
* Get the next feature resulting from a select operation.
|
||||
* @param feature feature which will receive data from the provider
|
||||
* @return true when there was a feature to fetch, false when end was hit
|
||||
*/
|
||||
virtual bool nextFeature(QgsFeature & feature);
|
||||
|
||||
/** Get the feature type. This corresponds to
|
||||
* WKBPoint,
|
||||
* WKBLineString,
|
||||
* WKBPolygon,
|
||||
* WKBMultiPoint,
|
||||
* WKBMultiLineString or
|
||||
* WKBMultiPolygon
|
||||
* as defined in qgis.h
|
||||
*/
|
||||
QGis::WkbType geometryType() const;
|
||||
|
||||
/** return the number of layers for the current data source
|
||||
|
||||
@note
|
||||
|
||||
Should this be subLayerCount() instead?
|
||||
*/
|
||||
size_t layerCount() const;
|
||||
|
||||
/**
|
||||
* Get the number of features in the layer
|
||||
*/
|
||||
long featureCount() const;
|
||||
|
||||
/**
|
||||
* Get the number of fields in the layer
|
||||
*/
|
||||
uint fieldCount() const;
|
||||
|
||||
/** Return the extent for this data layer
|
||||
*/
|
||||
virtual QgsRectangle extent();
|
||||
|
||||
/** * Get the name of the primary key for the layer
|
||||
*/
|
||||
QString getPrimaryKey();
|
||||
|
||||
/**
|
||||
* Get the field information for the layer
|
||||
* @return vector of QgsField objects
|
||||
*/
|
||||
const QgsFieldMap & fields() const;
|
||||
|
||||
/** Reset the layer - for a PostgreSQL layer, this means clearing the PQresult
|
||||
* pointer, setting it to 0 and reloading the field list
|
||||
*/
|
||||
void rewind();
|
||||
|
||||
/** Returns the minimum value of an attribute
|
||||
* @param index the index of the attribute */
|
||||
QVariant minimumValue(int index);
|
||||
|
||||
/** Returns the maximum value of an attribute
|
||||
* @param index the index of the attribute */
|
||||
QVariant maximumValue(int index);
|
||||
|
||||
/** Return the unique values of an attribute
|
||||
* @param index the index of the attribute
|
||||
* @param values reference to the list of unique values */
|
||||
virtual void uniqueValues(int index, QList < QVariant > &uniqueValues);
|
||||
|
||||
/**Returns true if layer is valid
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
/**Adds a list of features
|
||||
@return true in case of success and false in case of failure*/
|
||||
bool addFeatures(QgsFeatureList & flist);
|
||||
|
||||
/**Deletes a list of features
|
||||
@param id list of feature ids
|
||||
@return true in case of success and false in case of failure*/
|
||||
bool deleteFeatures(const QgsFeatureIds & id);
|
||||
|
||||
/**Adds new attributes
|
||||
@param name map with attribute name as key and type as value
|
||||
@return true in case of success and false in case of failure*/
|
||||
bool addAttributes(const QgsNewAttributesMap & name);
|
||||
|
||||
/**Changes attribute values of existing features
|
||||
@param attr_map a map containing the new attributes. The integer is the feature id,
|
||||
the first QString is the attribute name and the second one is the new attribute value
|
||||
@return true in case of success and false in case of failure*/
|
||||
bool changeAttributeValues(const QgsChangedAttributesMap & attr_map);
|
||||
|
||||
/**
|
||||
Changes geometries of existing features
|
||||
@param geometry_map A std::map containing the feature IDs to change the geometries of.
|
||||
the second map parameter being the new geometries themselves
|
||||
@return true in case of success and false in case of failure
|
||||
*/
|
||||
bool changeGeometryValues(QgsGeometryMap & geometry_map);
|
||||
|
||||
/**Returns a bitmask containing the supported capabilities*/
|
||||
int capabilities() const;
|
||||
|
||||
/** The SpatiaLite provider does its own transforms so we return
|
||||
* true for the following three functions to indicate that transforms
|
||||
* should not be handled by the QgsCoordinateTransform object. See the
|
||||
* documentation on QgsVectorDataProvider for details on these functions.
|
||||
*/
|
||||
// XXX For now we have disabled native transforms in the SpatiaLite
|
||||
// (following the PostgreSQL provider example)
|
||||
bool supportsNativeTransform()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/** return a provider name
|
||||
|
||||
Essentially just returns the provider key. Should be used to build file
|
||||
dialogs so that providers can be shown with their supported types. Thus
|
||||
if more than one provider supports a given format, the user is able to
|
||||
select a specific provider to open that file.
|
||||
|
||||
@note
|
||||
|
||||
Instead of being pure virtual, might be better to generalize this
|
||||
behavior and presume that none of the sub-classes are going to do
|
||||
anything strange with regards to their name or description?
|
||||
|
||||
*/
|
||||
QString name() const;
|
||||
|
||||
/** return description
|
||||
|
||||
Return a terse string describing what the provider is.
|
||||
|
||||
@note
|
||||
|
||||
Instead of being pure virtual, might be better to generalize this
|
||||
behavior and presume that none of the sub-classes are going to do
|
||||
anything strange with regards to their name or description?
|
||||
|
||||
*/
|
||||
QString description() const;
|
||||
|
||||
signals:
|
||||
/**
|
||||
* This is emitted whenever the worker thread has fully calculated the
|
||||
* PostGIS extents for this layer, and its event has been received by this
|
||||
* provider.
|
||||
*/
|
||||
void fullExtentCalculated();
|
||||
|
||||
/**
|
||||
* This is emitted when this provider is satisfied that all objects
|
||||
* have had a chance to adjust themselves after they'd been notified that
|
||||
* the full extent is available.
|
||||
*
|
||||
* \note It currently isn't being emitted because we don't have an easy way
|
||||
* for the overview canvas to only be repainted. In the meantime
|
||||
* we are satisfied for the overview to reflect the new extent
|
||||
* when the user adjusts the extent of the main map canvas.
|
||||
*/
|
||||
void repaintRequested();
|
||||
|
||||
private:
|
||||
/** loads fields from input file to member attributeFields */
|
||||
void loadFields();
|
||||
|
||||
QgsFieldMap attributeFields;
|
||||
/**
|
||||
* Flag indicating if the layer data source is a valid SpatiaLite layer
|
||||
*/
|
||||
bool valid;
|
||||
/**
|
||||
* DB full path
|
||||
*/
|
||||
QString mSqlitePath;
|
||||
/**
|
||||
* Name of the table with no schema
|
||||
*/
|
||||
QString mTableName;
|
||||
/**
|
||||
* Name of the primary key column in the table
|
||||
*/
|
||||
QString primaryKey;
|
||||
/**
|
||||
* Name of the geometry column in the table
|
||||
*/
|
||||
QString geometryColumn;
|
||||
/**
|
||||
* Geometry type
|
||||
*/
|
||||
QGis::WkbType geomType;
|
||||
/**
|
||||
* SQLite handle
|
||||
*/
|
||||
sqlite3 *sqliteHandle;
|
||||
/**
|
||||
* SQLite statement handle
|
||||
*/
|
||||
sqlite3_stmt *sqliteStatement;
|
||||
/**
|
||||
* Spatial reference id of the layer
|
||||
*/
|
||||
int mSrid;
|
||||
/**
|
||||
* proj4text
|
||||
*/
|
||||
QString mProj4text;
|
||||
/**
|
||||
* Rectangle that contains the extent (bounding box) of the layer
|
||||
*/
|
||||
QgsRectangle layerExtent;
|
||||
|
||||
/**
|
||||
* Number of features in the layer
|
||||
*/
|
||||
long numberFeatures;
|
||||
/**
|
||||
* this Geometry is supported by an R*Tree spatial index
|
||||
*/
|
||||
bool spatialIndexRTree;
|
||||
/**
|
||||
* this Geometry is supported by an MBR cache spatial index
|
||||
*/
|
||||
bool spatialIndexMbrCache;
|
||||
|
||||
int enabledCapabilities;
|
||||
|
||||
const QgsField & field(int index) const;
|
||||
|
||||
/**
|
||||
* internal utility functions used to handle common SQLite tasks
|
||||
*/
|
||||
//void sqliteOpen();
|
||||
void closeDb();
|
||||
QString quotedValue(QString value) const;
|
||||
bool getGeometryDetails();
|
||||
bool getTableSummary();
|
||||
|
||||
public:
|
||||
class SqliteHandles
|
||||
{
|
||||
//
|
||||
// a class allowing to reuse the same sqlite handle for more layers
|
||||
//
|
||||
public:
|
||||
SqliteHandles(sqlite3 * handle):
|
||||
ref(1), sqlite_handle(handle)
|
||||
{
|
||||
}
|
||||
|
||||
sqlite3 *handle()
|
||||
{
|
||||
return sqlite_handle;
|
||||
}
|
||||
|
||||
//
|
||||
// libsqlite3 wrapper
|
||||
//
|
||||
void sqliteClose();
|
||||
|
||||
static SqliteHandles *openDb(const QString & dbPath);
|
||||
static void closeDb(SqliteHandles * &handle);
|
||||
static void closeDb(QMap < QString, SqliteHandles * >&handlesRO, SqliteHandles * &handle);
|
||||
|
||||
private:
|
||||
int ref;
|
||||
sqlite3 *sqlite_handle;
|
||||
|
||||
static QMap < QString, SqliteHandles * >handles;
|
||||
};
|
||||
|
||||
/**
|
||||
* sqlite3 handles pointer
|
||||
*/
|
||||
SqliteHandles *handle;
|
||||
};
|
244
src/ui/qgsspatialitesourceselectbase.ui
Normal file
244
src/ui/qgsspatialitesourceselectbase.ui
Normal file
@ -0,0 +1,244 @@
|
||||
<ui version="4.0" >
|
||||
<class>QgsSpatiaLiteSourceSelectBase</class>
|
||||
<widget class="QDialog" name="QgsSpatiaLiteSourceSelectBase" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>472</width>
|
||||
<height>687</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>Add SpatiaLite Table(s)</string>
|
||||
</property>
|
||||
<property name="windowIcon" >
|
||||
<iconset/>
|
||||
</property>
|
||||
<property name="sizeGripEnabled" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="modal" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="2" column="0" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>271</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2" >
|
||||
<widget class="QTreeView" name="mTablesTreeView" >
|
||||
<property name="selectionMode" >
|
||||
<enum>QAbstractItemView::MultiSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2" >
|
||||
<widget class="QGroupBox" name="groupBox" >
|
||||
<property name="title" >
|
||||
<string>SpatiaLite DBs</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="1" column="2" >
|
||||
<widget class="QPushButton" name="btnDelete" >
|
||||
<property name="text" >
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<widget class="QPushButton" name="btnNew" >
|
||||
<property name="text" >
|
||||
<string>New</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QPushButton" name="btnConnect" >
|
||||
<property name="text" >
|
||||
<string>Connect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3" >
|
||||
<widget class="QComboBox" name="cmbConnections" />
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2" >
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnHelp" >
|
||||
<property name="enabled" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Help</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<string>F1</string>
|
||||
</property>
|
||||
<property name="autoDefault" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>141</width>
|
||||
<height>21</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnAdd" >
|
||||
<property name="text" >
|
||||
<string>Add</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<string/>
|
||||
</property>
|
||||
<property name="autoDefault" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="default" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnCancel" >
|
||||
<property name="text" >
|
||||
<string>Close</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<string/>
|
||||
</property>
|
||||
<property name="autoDefault" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2" >
|
||||
<widget class="QGroupBox" name="mSearchGroupBox" >
|
||||
<property name="title" >
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="mSearchLabel" >
|
||||
<property name="text" >
|
||||
<string>Search:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2" >
|
||||
<widget class="QLabel" name="mSearchModeLabel" >
|
||||
<property name="text" >
|
||||
<string>Search mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" >
|
||||
<widget class="QComboBox" name="mSearchModeComboBox" />
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2" >
|
||||
<widget class="QLabel" name="mSearchColumnsLabel" >
|
||||
<property name="text" >
|
||||
<string>Search in columns:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" >
|
||||
<widget class="QComboBox" name="mSearchColumnComboBox" />
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2" >
|
||||
<widget class="QLineEdit" name="mSearchTableEdit" />
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" >
|
||||
<widget class="QPushButton" name="mSearchOptionsButton" >
|
||||
<property name="text" >
|
||||
<string>Search options...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11" />
|
||||
<tabstops>
|
||||
<tabstop>cmbConnections</tabstop>
|
||||
<tabstop>btnConnect</tabstop>
|
||||
<tabstop>btnNew</tabstop>
|
||||
<tabstop>btnDelete</tabstop>
|
||||
<tabstop>btnHelp</tabstop>
|
||||
<tabstop>btnAdd</tabstop>
|
||||
<tabstop>btnCancel</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>btnCancel</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>QgsSpatiaLiteSourceSelectBase</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>404</x>
|
||||
<y>446</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>229</x>
|
||||
<y>236</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
Loading…
x
Reference in New Issue
Block a user