First fully functional version of the buffer (geoprocessing) plugin

git-svn-id: http://svn.osgeo.org/qgis/trunk@570 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
gsherman 2004-01-24 16:44:01 +00:00
parent efeeb353d1
commit f026017255
5 changed files with 300 additions and 171 deletions

View File

@ -9,7 +9,7 @@
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# $Id$
if POSTGRESDB
lib_LTLIBRARIES = libpggeoprocessingplugin.la
%.moc.cpp: %.h
$(MOC) -o $@ $<
@ -48,3 +48,4 @@ BUILT_SOURCES = $(pggeoprocessing_MOC) $(pggeoprocessing_UI)
AM_CXXFLAGS := $(CXXFLAGS) $(EXTRA_CXXFLAGS) $(QT_CXXFLAGS) $(PGDB) -I$(PG_INC)
libpggeoprocessingplugin_la_LIBADD = $(QT_LDADD) $(PG_LIB)
endif

View File

@ -1,53 +1,98 @@
/***************************************************************************
qgsdlgbuffer.cpp
Buffer dialog - Subclasses qgsdlgbufferbase
Part of the Geoprocessing plugin for PostgreSQL/PostGIS layers
-------------------
begin : Jan 21, 2004
copyright : (C) 2004 by Gary E.Sherman
email : sherman at mrcc.com
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
/* $Id$ */
#include <qlineedit.h>
#include <qlabel.h>
#include <qcheckbox.h>
#include <qcombobox.h>
#include "qgsdlgpgbuffer.h"
QgsDlgPgBuffer::QgsDlgPgBuffer(QWidget *parent, const char *name)
:QgsDlgPgBufferBase(parent,name){
}
QgsDlgPgBuffer::~QgsDlgPgBuffer(){
}
void QgsDlgPgBuffer::setBufferLabel(QString &lbl){
lblBufferInfo->setText(lbl);
}
QString QgsDlgPgBuffer::bufferDistance(){
return txtBufferDistance->text();
}
QString QgsDlgPgBuffer::bufferLayerName(){
return txtBufferedLayerName->text();
}
bool QgsDlgPgBuffer::addLayerToMap(){
return chkAddToMap->isChecked();
}
QString QgsDlgPgBuffer::geometryColumn(){
return txtGeometryColumn->text();
}
QString QgsDlgPgBuffer::srid(){
return txtSrid->text();
}
QString QgsDlgPgBuffer::objectIdColumn(){
return cmbFields->currentText();
}
QString QgsDlgPgBuffer::schema(){
return cmbSchema->currentText();
}
void QgsDlgPgBuffer::addFieldItem(QString field){
cmbFields->insertItem(field);
}
void QgsDlgPgBuffer::addSchema(QString schema){
cmbSchema->insertItem(schema);
}
void QgsDlgPgBuffer::setSrid(QString srid){
txtSrid->setText(srid);
}
void QgsDlgPgBuffer::setBufferLayerName(QString name){
txtBufferedLayerName->setText(name);
}
void QgsDlgPgBuffer::setGeometryColumn(QString name){
txtGeometryColumn->setText(name);
QgsDlgPgBuffer::QgsDlgPgBuffer(QWidget * parent, const char *name)
:QgsDlgPgBufferBase(parent, name)
{
}
QgsDlgPgBuffer::~QgsDlgPgBuffer()
{
}
void QgsDlgPgBuffer::setBufferLabel(QString & lbl)
{
lblBufferInfo->setText(lbl);
}
QString QgsDlgPgBuffer::bufferDistance()
{
return txtBufferDistance->text();
}
QString QgsDlgPgBuffer::bufferLayerName()
{
return txtBufferedLayerName->text();
}
bool QgsDlgPgBuffer::addLayerToMap()
{
return chkAddToMap->isChecked();
}
QString QgsDlgPgBuffer::geometryColumn()
{
return txtGeometryColumn->text();
}
QString QgsDlgPgBuffer::srid()
{
return txtSrid->text();
}
QString QgsDlgPgBuffer::objectIdColumn()
{
return cmbFields->currentText();
}
QString QgsDlgPgBuffer::schema()
{
return cmbSchema->currentText();
}
void QgsDlgPgBuffer::addFieldItem(QString field)
{
cmbFields->insertItem(field);
}
void QgsDlgPgBuffer::addSchema(QString schema)
{
cmbSchema->insertItem(schema);
}
void QgsDlgPgBuffer::setSrid(QString srid)
{
txtSrid->setText(srid);
}
void QgsDlgPgBuffer::setBufferLayerName(QString name)
{
txtBufferedLayerName->setText(name);
}
void QgsDlgPgBuffer::setGeometryColumn(QString name)
{
txtGeometryColumn->setText(name);
}

View File

@ -1,24 +1,58 @@
/***************************************************************************
qgsdlgbuffer.h
Buffer dialog - Subclasses qgsdlgbufferbase
Part of the Geoprocessing plugin for PostgreSQL/PostGIS layers
-------------------
begin : Jan 21, 2004
copyright : (C) 2004 by Gary E.Sherman
email : sherman at mrcc.com
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
/* $Id$ */
#ifndef QGSDLGPGBUFFER_H
#define QGSDLGPGBUFFER_H
#include "qgsdlgpgbufferbase.h"
class QgsDlgPgBuffer : public QgsDlgPgBufferBase
class QgsDlgPgBuffer:public QgsDlgPgBufferBase
{
Q_OBJECT
public:
QgsDlgPgBuffer(QWidget *parent=0, const char *name=0);
QgsDlgPgBuffer::~QgsDlgPgBuffer();
void setBufferLabel(QString &lbl);
QString bufferDistance();
QString bufferLayerName();
QString objectIdColumn();
QString geometryColumn();
QString srid();
QString schema();
bool addLayerToMap();
void addFieldItem(QString field);
void addSchema(QString schema);
void setSrid(QString srid);
void setBufferLayerName(QString name);
void setGeometryColumn(QString name);
};
Q_OBJECT public:
//! Constructor
QgsDlgPgBuffer(QWidget * parent = 0, const char *name = 0);
//! Destructor
QgsDlgPgBuffer::~QgsDlgPgBuffer();
//! Set the information label in the dialog
void setBufferLabel(QString & lbl);
//! Get the buffer distance
QString bufferDistance();
//! Get the name of the buffered layer to be created
QString bufferLayerName();
//! Get the name of the column to be used as the object id (unique key)
QString objectIdColumn();
//! Get the name to use for the geometry column in the buffered layer
QString geometryColumn();
//! Get the srid to use when creating the buffered layer
QString srid();
//! Get the schema name for the new layer
QString schema();
//! Flag to indicate if the layer should be added to the map
bool addLayerToMap();
//! Add a field name to the list of fields available for use as the object id
void addFieldItem(QString field);
//! Add a schema name to the list of available schemas
void addSchema(QString schema);
//! Set the srid value on the dialog
void setSrid(QString srid);
//! Set the bufferd layer name on the dialog
void setBufferLayerName(QString name);
//! Set the geometry column on the dialog
void setGeometryColumn(QString name);
};
#endif // QGSDLGPGBUFFER_H

View File

@ -117,7 +117,7 @@ void QgsPgGeoprocessing::buffer()
// create the connection string
QString connInfo = dataSource.left(dataSource.find("table="));
QMessageBox::information(0, "Data source", QString("Datasource:%1\n\nConnectionInfo:%2").arg(dataSource).arg(connInfo));
std::cerr << "Data source = " << QString("Datasource:%1\n\nConnectionInfo:%2").arg(dataSource).arg(connInfo) << std::endl;
// get the table name
QStringList connStrings = QStringList::split(" ", dataSource);
QStringList tables = connStrings.grep("table=");
@ -133,113 +133,162 @@ void QgsPgGeoprocessing::buffer()
QStringList userNames = connStrings.grep("user=");
QString user = userNames[0];
user = user.mid(user.find("=") + 1);
// show dialog to fetch buffer distrance, new layer name, and option to
QgsDlgPgBuffer *bb = new QgsDlgPgBuffer();
// set the label
QString lbl = tr("Buffer features in layer %1").arg(tableName);
bb->setBufferLabel(lbl);
// set a default output table name
bb->setBufferLayerName(tableName.mid(tableName.find(".")+1) + "_buffer");
bb->setBufferLayerName(tableName.mid(tableName.find(".") + 1) + "_buffer");
// set the fields on the dialog box drop-down
QgsDataProvider *dp = lyr->getDataProvider();
std::vector<QgsField> flds = dp->fields();
for(int i=0; i < flds.size(); i++){
// check the field type -- if its int we can use it
if(flds[i].getType().find("int") > -1){
bb->addFieldItem(flds[i].getName());
}
std::vector < QgsField > flds = dp->fields();
for (int i = 0; i < flds.size(); i++) {
// check the field type -- if its int we can use it
if (flds[i].getType().find("int") > -1) {
bb->addFieldItem(flds[i].getName());
}
}
// connect to the database
PGconn *conn = PQconnectdb((const char *) connInfo);
if (PQstatus(conn) == CONNECTION_OK) {
// populate the schema drop-down
QString schemaSql = QString("select nspname from pg_namespace,pg_user where nspowner = usesysid and usename = '%1'").arg(user);
PGresult *schemas = PQexec(conn, (const char *) schemaSql);
if(PQresultStatus(schemas) == PGRES_TUPLES_OK){
// add the schemas to the drop-down, otherwise just public (the
// default) will show up
for(int i=0; i < PQntuples(schemas); i++){
bb->addSchema(PQgetvalue(schemas,i,0));
}
}
PQclear(schemas);
// query the geometry_columns table to get the srid and use it as default
QString sridSql = QString("select srid,f_geometry_column from geometry_columns where f_table_schema='%1' and f_table_name='%2'")
.arg(schema)
.arg(tableName.mid(tableName.find(".")+1));
QMessageBox::information(0,"SRID SQL",sridSql);
QString geometryCol;
PGresult *sridq = PQexec(conn,(const char *)sridSql);
if(PQresultStatus(sridq) == PGRES_TUPLES_OK){
bb->setSrid(PQgetvalue(sridq,0,0));
geometryCol = PQgetvalue(sridq,0,1);
bb->setGeometryColumn(geometryCol);
}else{
bb->setSrid("-1");
}
PQclear(sridq);
// exec the dialog and process if user selects ok
if (bb->exec()) {
// connect to the database
PGconn *conn = PQconnectdb((const char *) connInfo);
if (PQstatus(conn) == CONNECTION_OK) {
// populate the schema drop-down
QString schemaSql =
QString("select nspname from pg_namespace,pg_user where nspowner = usesysid and usename = '%1'").arg(user);
PGresult *schemas = PQexec(conn, (const char *) schemaSql);
if (PQresultStatus(schemas) == PGRES_TUPLES_OK) {
// add the schemas to the drop-down, otherwise just public (the
// default) will show up
for (int i = 0; i < PQntuples(schemas); i++) {
bb->addSchema(PQgetvalue(schemas, i, 0));
}
}
PQclear(schemas);
// query the geometry_columns table to get the srid and use it as default
QString sridSql =
QString("select srid,f_geometry_column from geometry_columns where f_table_schema='%1' and f_table_name='%2'")
.arg(schema)
.arg(tableName.mid(tableName.find(".") + 1));
std::cerr << "SRID SQL" << sridSql << std::endl;
QString geometryCol;
PGresult *sridq = PQexec(conn, (const char *) sridSql);
if (PQresultStatus(sridq) == PGRES_TUPLES_OK) {
bb->setSrid(PQgetvalue(sridq, 0, 0));
geometryCol = PQgetvalue(sridq, 0, 1);
bb->setGeometryColumn(geometryCol);
} else {
bb->setSrid("-1");
}
PQclear(sridq);
// exec the dialog and process if user selects ok
if (bb->exec()) {
// determine what column to use as the obj id
QString objId = bb->objectIdColumn();
QString objIdType = "int";
QString objIdValue;
if(objId == "Create unique object id"){
objId = "objectid";
objIdType = "serial";
objIdValue = "0";
}else{
objIdValue = objId;
if (objId == "Create unique object id") {
objId = "objectid";
objIdType = "serial";
objIdValue = "DEFAULT";
} else {
objIdValue = objId;
}
// set the schema path (need public to find the postgis
// functions)
PGresult *result = PQexec(conn, "begin work");
PQclear(result);
QString sql = QString("set search_path = '%1','public'").arg(bb->schema());
result = PQexec(conn, (const char *) sql);
PQclear(result);
std::cerr << sql << std::endl;
// first create the new table
QString sql = QString("create table %1.%2 (%3 %4)")
sql = QString("create table %1.%2 (%3 %4)")
.arg(bb->schema())
.arg(bb->bufferLayerName())
.arg(objId)
.arg(objIdType);
PGresult *result = PQexec(conn, (const char *) sql);
std::cerr << sql << std::endl;
result = PQexec(conn, (const char *) sql);
std::cerr << "Status from create table is " << PQresultStatus(result) << std::endl;
if (PQresultStatus(result) == PGRES_COMMAND_OK) {
PQclear(result);
// add the geometry column
//<db_name>, <table_name>, <column_name>, <srid>, <type>, <dimension>
sql = QString("select addgeometrycolumn('%1','%2.%4','%4',%5,'%6',%7)")
sql = QString("select addgeometrycolumn('%1','%2','%3',%4,'%5',%6)")
.arg(dbname)
.arg(bb->schema())
.arg(bb->bufferLayerName())
.arg(bb->geometryColumn())
.arg(bb->srid())
.arg("POLYGON")
.arg("2");
QMessageBox::information(0,"AddGeomCol",sql);
PGresult *geoCol = PQexec(conn, (const char *)sql);
if(PQresultStatus(geoCol) == PGRES_COMMAND_OK) {
// do the buffer and insert the features
std::cerr << sql << std::endl;
PGresult *geoCol = PQexec(conn, (const char *) sql);
PQclear(geoCol);
// drop the check constraint based on geometry type
sql = QString("alter table %1.%2 drop constraint \"$2\"")
.arg(bb->schema())
.arg(bb->bufferLayerName());
std::cerr << sql << std::endl;
result = PQexec(conn, (const char *) sql);
PQclear(result);
// if(PQresultStatus(geoCol) == PGRES_COMMAND_OK) {
// do the buffer and insert the features
if (objId == "objectid") {
sql = QString("insert into %1 (%2) select buffer(%3,%4) from %5")
.arg(bb->bufferLayerName())
.arg(bb->geometryColumn())
.arg(geometryCol)
.arg(bb->bufferDistance().toDouble())
.arg(tableName);
} else {
sql = QString("insert into %1 select %2, buffer(%3,%4) from %5")
.arg(bb->bufferLayerName())
.arg(objIdValue)
.arg(geometryCol)
.arg(bb->bufferDistance().toDouble())
.arg(tableName);
PQexec(conn, (const char *)sql);
}
// add new layer to the map
if(bb->addLayerToMap()){
// create the connection string
QString conn = "dbname=%1 host";
}
std::cerr << sql << std::endl;
}
result = PQexec(conn, (const char *) sql);
PQclear(result);
// }
std::cerr << sql << std::endl;
result = PQexec(conn, "end work");
PQclear(result);
result = PQexec(conn, "commit;vacuum");
PQclear(result);
PQfinish(conn);
QMessageBox::information(0, "Add to Map?", "Do you want to add the layer to the map?");
// add new layer to the map
if (bb->addLayerToMap()) {
// create the connection string
QString newLayerSource = dataSource.left(dataSource.find("table="));
std::cerr << "newLayerSource: " << newLayerSource << std::endl;
// add the schema.table and geometry column
/* newLayerSource += "table=" + bb->schema() + "." + bb->bufferLayerName()
+ " (" + bb->geometryColumn() + ")"; */
std::cerr << "newLayerSource: " << newLayerSource << std::endl;
std::cerr << "Adding new layer using\n\t" << newLayerSource << std::endl;
// host=localhost dbname=gis_data user=gsherman password= table=public.alaska (the_geom)
qI->addVectorLayer(newLayerSource, bb->schema() + "." + bb->bufferLayerName()
+ " (" + bb->geometryColumn() + ")", "postgres");
}
} else {
QMessageBox::critical(0, "Unable to create table",
QString("Failed to create the output table %1").arg(bb->bufferLayerName()));
}
}
} else {
// connection error
QString err = tr("Error connecting to the database");
QMessageBox::critical(0, err, PQerrorMessage(conn));
}
delete bb;
} else {
// connection error
QString err = tr("Error connecting to the database");
QMessageBox::critical(0, err, PQerrorMessage(conn));
}
} else {
QMessageBox::critical(0, "Not a PostgreSQL/PosGIS Layer",
QString

View File

@ -37,61 +37,61 @@ class QPopupMenu;
* \brief PostgreSQL/PostGIS plugin for QGIS
*
*/
class QgsPgGeoprocessing : public QObject, public QgisPlugin{
Q_OBJECT
public:
class QgsPgGeoprocessing:public QObject, public QgisPlugin
{
Q_OBJECT public:
/**
* Constructor for a plugin. The QgisApp and QgisIface pointers are passed by
* QGIS when it attempts to instantiate the plugin.
* @param qgis Pointer to the QgisApp object
* @param qI Pointer to the QgisIface object.
*/
QgsPgGeoprocessing(QgisApp *qgis, QgisIface *qI);
/**
QgsPgGeoprocessing(QgisApp * qgis, QgisIface * qI);
/**
* Virtual function to return the name of the plugin. The name will be used when presenting a list
* of installable plugins to the user
*/
virtual QString name();
/**
virtual QString name();
/**
* Virtual function to return the version of the plugin.
*/
virtual QString version();
/**
virtual QString version();
/**
* Virtual function to return a description of the plugins functions
*/
virtual QString description();
/**
virtual QString description();
/**
* Return the plugin type
*/
virtual int type();
//! init the gui
virtual void initGui();
//! Destructor
virtual ~QgsPgGeoprocessing();
public slots:
//! buffer features in a layer
void buffer();
//! unload the plugin
void unload();
private:
virtual int type();
//! init the gui
virtual void initGui();
//! Destructor
virtual ~ QgsPgGeoprocessing();
public slots:
//! buffer features in a layer
void buffer();
//! unload the plugin
void unload();
private:
//! Name of the plugin
QString pName;
//! Version
QString pVersion;
//! Descrption of the plugin
QString pDescription;
//! Plugin type as defined in QgisPlugin::PLUGINTYPE
int ptype;
//! Id of the plugin's menu. Used for unloading
int menuId;
//! Pointer to our toolbar
QToolBar *toolBar;
//! Pointer to our menu
QMenuBar *menu;
//! Pionter to QGIS main application object
QgisApp *qgisMainWindow;
//! Pointer to the QGIS interface object
QgisIface *qI;
QString pName;
//! Version
QString pVersion;
//! Descrption of the plugin
QString pDescription;
//! Plugin type as defined in QgisPlugin::PLUGINTYPE
int ptype;
//! Id of the plugin's menu. Used for unloading
int menuId;
//! Pointer to our toolbar
QToolBar *toolBar;
//! Pointer to our menu
QMenuBar *menu;
//! Pionter to QGIS main application object
QgisApp *qgisMainWindow;
//! Pointer to the QGIS interface object
QgisIface *qI;
};
#endif