📄 qgspggeoprocessing.cpp
字号:
/*************************************************************************** qgspggeoprocessing.cpp Geoprocessing plugin for PostgreSQL/PostGIS layersFunctions:Buffer-------------------begin : Jan 21, 2004copyright : (C) 2004 by Gary E.Shermanemail : 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: qgspggeoprocessing.cpp 8053 2008-01-26 13:59:53Z timlinux $ */// includes#include <iostream>#include <vector>#include "qgisinterface.h"#include "qgsmaplayer.h"#include "qgsvectorlayer.h"#include "qgsvectordataprovider.h"#include "qgsfield.h"#include "qgsdatasourceuri.h"#include "qgslogger.h"#include <QMessageBox>#include <QAction>#include <QApplication>#include <QMenu>#include "qgsdlgpgbuffer.h"#include "qgspggeoprocessing.h"// xpm for creating the toolbar icon#include "icon_buffer.xpm"static const char * const ident_ = "$Id: qgspggeoprocessing.cpp 8053 2008-01-26 13:59:53Z timlinux $";static const QString name_ = QObject::tr("PostgreSQL Geoprocessing");static const QString description_ = QObject::tr("Geoprocessing functions for working with PostgreSQL/PostGIS layers");static const QString version_ = QObject::tr("Version 0.1");static const QgisPlugin::PLUGINTYPE type_ = QgisPlugin::UI;/** * Constructor for the plugin. The plugin is passed a pointer to the main app * and an interface object that provides access to exposed functions in QGIS. * @param qgis Pointer to the QGIS main window * @parma _qI Pointer to the QGIS interface object */QgsPgGeoprocessing::QgsPgGeoprocessing(QgisInterface * _qI) : QgisPlugin( name_, description_, version_, type_ ), qgisMainWindow(_qI->getMainWindow()), qI(_qI){}QgsPgGeoprocessing::~QgsPgGeoprocessing(){}/* * Initialize the GUI interface for the plugin */void QgsPgGeoprocessing::initGui(){ // Create the action for tool bufferAction = new QAction(QIcon(icon_buffer), tr("&Buffer features"), this); bufferAction->setWhatsThis(tr("Create a buffer for a PostgreSQL layer. " + tr("A new layer is created in the database with the buffered features."))); // Connect the action to the buffer slot connect(bufferAction, SIGNAL(triggered()), this, SLOT(buffer())); // Add the icon to the toolbar qI->addToolBarIcon(bufferAction); qI->addPluginMenu(tr("&Geoprocessing"), bufferAction);}// Slot called when the buffer menu item is triggeredvoid QgsPgGeoprocessing::buffer(){ // need to get a pointer to the current layer QgsMapLayer *layer = qI->activeLayer(); if (layer) { QgsVectorLayer *lyr = (QgsVectorLayer*)layer; // check the layer to see if its a postgres layer if (layer->type() != QgsMapLayer::RASTER && lyr->providerType() == "postgres") { QgsDataSourceURI uri( lyr->source() ); QgsDebugMsg("data source = " + uri.connInfo() ); // connect to the database and check the capabilities PGconn *capTest = PQconnectdb((const char *) uri.connInfo() ); if (PQstatus(capTest) == CONNECTION_OK) { postgisVersion(capTest); } PQfinish(capTest); if(geosAvailable){ // show dialog to fetch buffer distrance, new layer name, and option to // add the new layer to the map QgsDlgPgBuffer *bb = new QgsDlgPgBuffer(qI); // set the label QString lbl = tr("Buffer features in layer %1").arg( uri.table() ); bb->setBufferLabel(lbl); // set a default output table name bb->setBufferLayerName( uri.table() + "_buffer"); QString tableName = uri.quotedTablename(); // set the fields on the dialog box drop-down QgsVectorDataProvider *dp = dynamic_cast<QgsVectorDataProvider *>(lyr->getDataProvider()); QgsFieldMap flds = dp->fields(); for (QgsFieldMap::iterator it = flds.begin(); it != flds.end(); ++it) { // check the field type -- if its int we can use it if (it->typeName().find("int") > -1) { bb->addFieldItem(it->name()); } } // connect to the database PGconn *conn = PQconnectdb((const char *) uri.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( uri.username() ); 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( uri.schema() ) .arg( uri.table() ); QgsDebugMsg("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()) { QApplication::setOverrideCursor(Qt::WaitCursor); qApp->processEvents(); // 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 = "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; // set the schema search path if schema is not public if(bb->schema() != "public") { sql = QString("set search_path = '%1','public'").arg(bb->schema()); result = PQexec(conn, (const char *) sql); PQclear(result); QgsDebugMsg("SQL: " + sql); } // first create the new table sql = QString("create table %1.%2 (%3 %4 PRIMARY KEY)") .arg(bb->schema()) .arg(bb->bufferLayerName()) .arg(objId) .arg(objIdType); QgsDebugMsg("SQL: " + sql); result = PQexec(conn, (const char *) sql); QgsDebugMsg( QString("Status from create table is %1").arg( PQresultStatus(result) ) ); QgsDebugMsg( QString("Error message is %1").arg(PQresStatus(PQresultStatus(result))) ); 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','%3',%4,'%5',%6)") .arg(bb->schema()) .arg(bb->bufferLayerName()) .arg(bb->geometryColumn()) .arg(bb->srid()) .arg("POLYGON") .arg("2"); QgsDebugMsg("SQL: " + sql); PGresult *geoCol = PQexec(conn, (const char *) sql); if (PQresultStatus(geoCol) == PGRES_TUPLES_OK) { PQclear(geoCol); /* The constraint naming convention has changed in PostGIS * from $2 to enforce_geotype_shape. This change means the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -