From 8c3e5fc65bfb0f35ced7599ab20463f84369f8c1 Mon Sep 17 00:00:00 2001 From: gsherman Date: Fri, 23 Jan 2004 07:37:32 +0000 Subject: [PATCH] more progress towards a buffer function git-svn-id: http://svn.osgeo.org/qgis/trunk@565 c8812cc2-4d05-0410-92ff-de0c093fc19c --- plugins/geoprocessing/Makefile.am | 4 +- plugins/geoprocessing/qgsdlgpgbuffer.cpp | 26 +++ plugins/geoprocessing/qgsdlgpgbuffer.h | 8 + plugins/geoprocessing/qgsdlgpgbufferbase.ui | 161 +++++++++++-------- plugins/geoprocessing/qgspggeoprocessing.cpp | 104 ++++++++++-- 5 files changed, 223 insertions(+), 80 deletions(-) diff --git a/plugins/geoprocessing/Makefile.am b/plugins/geoprocessing/Makefile.am index 46b2f3aafcc..dec2208101e 100644 --- a/plugins/geoprocessing/Makefile.am +++ b/plugins/geoprocessing/Makefile.am @@ -7,7 +7,9 @@ # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# $Id +# +# $Id$ + lib_LTLIBRARIES = libpggeoprocessingplugin.la %.moc.cpp: %.h $(MOC) -o $@ $< diff --git a/plugins/geoprocessing/qgsdlgpgbuffer.cpp b/plugins/geoprocessing/qgsdlgpgbuffer.cpp index 8c2feaec8dd..e8ee0418255 100644 --- a/plugins/geoprocessing/qgsdlgpgbuffer.cpp +++ b/plugins/geoprocessing/qgsdlgpgbuffer.cpp @@ -22,6 +22,32 @@ QString QgsDlgPgBuffer::bufferLayerName(){ 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); +} + + diff --git a/plugins/geoprocessing/qgsdlgpgbuffer.h b/plugins/geoprocessing/qgsdlgpgbuffer.h index 828532a5ea8..e9244ebce35 100644 --- a/plugins/geoprocessing/qgsdlgpgbuffer.h +++ b/plugins/geoprocessing/qgsdlgpgbuffer.h @@ -10,7 +10,15 @@ public: 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); }; #endif // QGSDLGPGBUFFER_H diff --git a/plugins/geoprocessing/qgsdlgpgbufferbase.ui b/plugins/geoprocessing/qgsdlgpgbufferbase.ui index f74cc4c3dcf..92a14f71dab 100644 --- a/plugins/geoprocessing/qgsdlgpgbufferbase.ui +++ b/plugins/geoprocessing/qgsdlgpgbufferbase.ui @@ -8,8 +8,8 @@ 0 0 - 516 - 275 + 520 + 294 @@ -22,7 +22,7 @@ unnamed - + lblBufferInfo @@ -30,33 +30,7 @@ Buffer the features in layer - - - textLabel3 - - - Table name for the buffered layer - - - - - txtBufferDistance - - - - - textLabel2 - - - Buffer distance in map units - - - - - txtBufferedLayerName - - - + spacer2 @@ -73,15 +47,28 @@ - + - textLabel1 - - - Use the following field as feature id (must be unique) + txtBufferDistance - + + + textLabel2 + + + Buffer distance in map units + + + + + chkAddToMap + + + Add the buffered layer to the map + + + Layout1 @@ -159,15 +146,55 @@ - + - chkAddToMap + spacer5 - - Add the buffered layer to the map + + Horizontal + + + Expanding + + + + 43 + 28 + + + + + + txtBufferedLayerName - + + + textLabel3 + + + Table name for the buffered layer + + + + + + public + + + + cmbSchema + + + + + textLabel1_2 + + + Schema + + + Create unique object id @@ -177,40 +204,40 @@ cmbFields - + - spacer4 + textLabel1 - - Horizontal + + Unique field to use as feature id - - Fixed - - - - 258 - 24 - - - - + + - spacer3 + txtSrid - - Horizontal + + + + textLabel2_2 - - Fixed + + Spatial Ref. Id - - - 44 - 19 - + + + + textLabel2_2_2 - + + Geometry column + + + + + txtGeometryColumn + + diff --git a/plugins/geoprocessing/qgspggeoprocessing.cpp b/plugins/geoprocessing/qgspggeoprocessing.cpp index 3ca0168cb34..2dfc4483e7a 100644 --- a/plugins/geoprocessing/qgspggeoprocessing.cpp +++ b/plugins/geoprocessing/qgspggeoprocessing.cpp @@ -123,43 +123,123 @@ void QgsPgGeoprocessing::buffer() QStringList tables = connStrings.grep("table="); QString table = tables[0]; QString tableName = table.mid(table.find("=") + 1); + // get the schema + QString schema = tableName.left(tableName.find(".")); + // get the database name QStringList dbnames = connStrings.grep("dbname="); QString dbname = dbnames[0]; dbname = dbname.mid(dbname.find("=") + 1); + // get the user name + 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 the fields + // set a default output table name + bb->setBufferLayerName(tableName.mid(tableName.find(".")+1) + "_buffer"); + // set the fields on the dialog box drop-down QgsDataProvider *dp = lyr->getDataProvider(); std::vector flds = dp->fields(); for(int i=0; i < flds.size(); i++){ - bb->addFieldItem(flds[i].getName()); + // check the field type -- if its int we can use it + if(flds[i].getType().find("int") > -1){ + bb->addFieldItem(flds[i].getName()); + } } - if (bb->exec()) { - // connect to the database + // connect to the database PGconn *conn = PQconnectdb((const char *) connInfo); if (PQstatus(conn) == CONNECTION_OK) { - // get some info from the source layer so we can duplicate it in the new layer - QString sql = "select * from geometry_columns"; + // 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()) { + // 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; + } // first create the new table - sql = QString("create table %1 (objectid int)").arg(bb->bufferLayerName()); + + QString 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); if (PQresultStatus(result) == PGRES_COMMAND_OK) { // add the geometry column - sql = "select addgeometrycolumn(%1,%2,%3,%4,%5"; - // add new layer to the map + //, , , , , + sql = QString("select addgeometrycolumn('%1','%2.%4','%4',%5,'%6',%7)") + .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 + 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"; + } } else { QMessageBox::critical(0, "Unable to create table", QString("Failed to create the output table %1").arg(bb->bufferLayerName())); } - } else { + + } + } 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