mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-26 00:02:08 -05:00
420 lines
12 KiB
C++
420 lines
12 KiB
C++
/***************************************************************************
|
|
qgspostgresprovider.h - Data provider for PostgreSQL/PostGIS layers
|
|
-------------------
|
|
begin : Jan 2, 2004
|
|
copyright : (C) 2003 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 QGSPOSTGRESPROVIDER_H
|
|
#define QGSPOSTGRESPROVIDER_H
|
|
|
|
extern "C"
|
|
{
|
|
#include <libpq-fe.h>
|
|
}
|
|
#include "../../src/qgsvectordataprovider.h"
|
|
#include "../../src/qgsrect.h"
|
|
#include <list>
|
|
#include <fstream>
|
|
#include <qstring.h>
|
|
#include <qobject.h>
|
|
//#include <qmutex.h>
|
|
|
|
class QgsFeature;
|
|
class QgsField;
|
|
class OGRDataSource;
|
|
class OGRLayer;
|
|
#include "qgsdatasourceuri.h"
|
|
|
|
#include "qgspostgrescountthread.h"
|
|
#include "qgspostgresextentthread.h"
|
|
|
|
/**
|
|
\class QgsPostgresProvider
|
|
\brief Data provider for PostgreSQL/PostGIS layers.
|
|
|
|
This provider implements the
|
|
interface defined in the QgsDataProvider class to provide access to spatial
|
|
data residing in a PostgreSQL/PostGIS enabled database.
|
|
*/
|
|
class QgsPostgresProvider:public QgsVectorDataProvider
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
/**
|
|
* Constructor for the provider. The uri must be in the following format:
|
|
* host=localhost user=gsherman dbname=test password=xxx table=test.alaska (the_geom)
|
|
* @param uri String containing the required parameters to connect to the database
|
|
* and query the table.
|
|
*/
|
|
QgsPostgresProvider(QString uri = 0);
|
|
|
|
//! Destructor
|
|
virtual ~ QgsPostgresProvider();
|
|
|
|
/** Used to ask the layer for its projection as a WKT string. Implements
|
|
* virtual method of same name in QgsDataProvider. */
|
|
QString getProjectionWKT() {return QString("Not implemented yet");} ;
|
|
|
|
/**
|
|
* Get the first feature resutling from a select operation
|
|
* @return QgsFeature
|
|
*/
|
|
QgsFeature *getFirstFeature(bool fetchAttributes = false);
|
|
|
|
/**
|
|
* Get the next feature resulting from a select operation
|
|
* @return QgsFeature
|
|
*/
|
|
QgsFeature *getNextFeature(bool fetchAttributes = false);
|
|
bool getNextFeature(QgsFeature &feature, bool fetchAttributes=0);
|
|
|
|
/**Get the next feature resulting from a select operation.
|
|
*@param attlist a list containing the indexes of the attribute fields to copy
|
|
*@param getnotcommited flag indicating if not commited features should be returned
|
|
*/
|
|
QgsFeature* getNextFeature(std::list<int> const & attlist);
|
|
/** Get the feature type. This corresponds to
|
|
* WKBPoint,
|
|
* WKBLineString,
|
|
* WKBPolygon,
|
|
* WKBMultiPoint,
|
|
* WKBMultiLineString or
|
|
* WKBMultiPolygon
|
|
* as defined in qgis.h
|
|
*/
|
|
|
|
int geometryType() const;
|
|
|
|
/**
|
|
* Get the number of features in the layer
|
|
*/
|
|
long featureCount() const;
|
|
|
|
/**
|
|
* Get the number of fields in the layer
|
|
*/
|
|
int fieldCount() const;
|
|
|
|
/**
|
|
* Select features based on a bounding rectangle. Features can be retrieved
|
|
* with calls to getFirstFeature and getNextFeature.
|
|
* @param mbr QgsRect containing the extent to use in selecting features
|
|
*/
|
|
void select(QgsRect * mbr, bool useIntersect=false);
|
|
|
|
/**
|
|
* Get the data source URI structure used by this layer
|
|
*/
|
|
QgsDataSourceURI * getURI();
|
|
|
|
/**
|
|
* Set the data source URI used by this layer
|
|
*/
|
|
void setURI(QgsDataSourceURI &uri);
|
|
|
|
/**
|
|
* Set the data source specification. This must be a valid database
|
|
* connection string:
|
|
* host=localhost user=gsherman dbname=test password=xxx table=test.alaska (the_geom)
|
|
* @uri data source specification
|
|
*/
|
|
// TODO Deprecate this in favor of using the QgsDataSourceURI structure
|
|
void setDataSourceUri(QString uri);
|
|
|
|
/**
|
|
* Get the data source specification.
|
|
* @return data source specification as a string containing the host, user,
|
|
* dbname, password, and table
|
|
* @see setDataSourceUri
|
|
*/
|
|
// TODO Deprecate this in favor of returning the QgsDataSourceURI structure
|
|
QString getDataSourceUri();
|
|
|
|
/**
|
|
* Identify features within the search radius specified by rect
|
|
* @param rect Bounding rectangle of search radius
|
|
* @return std::vector containing QgsFeature objects that intersect rect
|
|
*/
|
|
virtual std::vector<QgsFeature>& identify(QgsRect * rect);
|
|
|
|
/**
|
|
* Return a string representation of the endian-ness for the layer
|
|
*/
|
|
QString endianString();
|
|
|
|
/**
|
|
* Changes the stored extent for this layer to the supplied extent.
|
|
* For example, this is called when the extent worker thread has a result.
|
|
*/
|
|
void setExtent( QgsRect* newExtent );
|
|
|
|
/** Return the extent for this data layer
|
|
*/
|
|
virtual QgsRect *extent();
|
|
|
|
/**
|
|
* Get the attributes associated with a feature
|
|
*/
|
|
void getFeatureAttributes(int oid, QgsFeature *f);
|
|
|
|
/**Get the attributes with indices contained in attlist*/
|
|
void getFeatureAttributes(int oid, QgsFeature *f, std::list<int> const& attlist);
|
|
|
|
/** * Get the name of the primary key for the layer
|
|
*/
|
|
QString getPrimaryKey();
|
|
/**
|
|
* Get the field information for the layer
|
|
* @return vector of QgsField objects
|
|
*/
|
|
std::vector<QgsField> const & fields() const;
|
|
|
|
/** Reset the layer - for a PostgreSQL layer, this means clearing the PQresult
|
|
* pointer and setting it to 0
|
|
*/
|
|
void reset();
|
|
|
|
/**Returns the minimum value of an attributs
|
|
@param position the number of the attribute*/
|
|
QString minValue(int position);
|
|
|
|
/**Returns the maximum value of an attributs
|
|
@param position the number of the attribute*/
|
|
QString maxValue(int position);
|
|
|
|
/**Returns true if layer is valid
|
|
*/
|
|
bool isValid();
|
|
|
|
//! get postgis version string
|
|
QString postgisVersion(PGconn *);
|
|
|
|
//! get status of GEOS capability
|
|
bool hasGEOS(PGconn *);
|
|
|
|
//! get status of GIST capability
|
|
bool hasGIST(PGconn *);
|
|
|
|
//! get status of PROJ4 capability
|
|
bool hasPROJ(PGconn *);
|
|
|
|
/**Returns the default value for attribute @c attr for feature @c f. */
|
|
QString getDefaultValue(const QString& attr, QgsFeature* f);
|
|
|
|
/**Adds a list of features
|
|
@return true in case of success and false in case of failure*/
|
|
bool addFeatures(std::list<QgsFeature*> const 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(std::list<int> const & 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(std::map<QString,QString> const & name);
|
|
|
|
/**Deletes existing attributes
|
|
@param names of the attributes to delete
|
|
@return true in case of success and false in case of failure*/
|
|
bool deleteAttributes(std::set<QString> const & 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(std::map<int,std::map<QString,QString> > const & attr_map);
|
|
|
|
//! Flag to indicate if the provider can export to shapefile
|
|
bool supportsSaveAsShapefile() const;
|
|
|
|
/** Accessor for sql where clause used to limit dataset */
|
|
QString subsetString() {return sqlWhereClause;};
|
|
|
|
//! Get the postgres connection
|
|
PGconn * pgConnection() {return connection;};
|
|
|
|
//! Get the table name associated with this provider instance
|
|
QString getTableName() {return tableName;};
|
|
|
|
/** mutator for sql where clause used to limit dataset size */
|
|
void setSubsetString(QString theSQL); //{sqlWhereClause = theSQL;};
|
|
|
|
/**Returns a bitmask containing the supported capabilities*/
|
|
int capabilities() 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:
|
|
|
|
std::vector < QgsFeature > features;
|
|
std::vector < bool > *selected;
|
|
std::vector < QgsField > attributeFields;
|
|
std::map < int, int > attributeFieldsIdMap;
|
|
|
|
QString dataSourceUri;
|
|
|
|
//! Data source URI struct for this layer
|
|
QgsDataSourceURI mUri;
|
|
|
|
|
|
//! Child thread for calculating extents.
|
|
QgsPostgresExtentThread mExtentThread;
|
|
|
|
//! Child thread for calculating count.
|
|
QgsPostgresCountThread mCountThread;
|
|
|
|
|
|
/**
|
|
* Pointer to the PostgreSQL query result object. If this pointer is 0,
|
|
* there is no current selection set. Any future getNextFeature requests
|
|
* will require execution of the select query to recreate the result set.
|
|
*/
|
|
PGresult *queryResult;
|
|
/**
|
|
* Flag indicating if the layer data source is a valid PostgreSQL layer
|
|
*/
|
|
bool valid;
|
|
/**
|
|
* Name of the table with no schema
|
|
*/
|
|
QString tableName;
|
|
/**
|
|
* Name of the table with schema included
|
|
*/
|
|
QString schemaTableName;
|
|
/**
|
|
* Name of the schema
|
|
*/
|
|
QString mSchema;
|
|
/**
|
|
* SQL statement used to limit the features retreived
|
|
*/
|
|
QString sqlWhereClause;
|
|
/**
|
|
* Primary key column for fetching features. If there is no primary key
|
|
* the oid is used to fetch features.
|
|
*/
|
|
QString primaryKey;
|
|
/**
|
|
* Index (column number) of the primary key
|
|
*/
|
|
int primaryKeyIndex;
|
|
/**
|
|
* Data type for the primary key
|
|
*/
|
|
QString primaryKeyType;
|
|
/**
|
|
* Name of the geometry column in the table
|
|
*/
|
|
QString geometryColumn;
|
|
/**
|
|
* Geometry type
|
|
*/
|
|
int geomType;
|
|
/**
|
|
* SQL to select all records in this layer
|
|
*/
|
|
QString selectSQL;
|
|
/**
|
|
* Connection pointer
|
|
*/
|
|
PGconn *connection;
|
|
/**
|
|
* Spatial reference id of the layer
|
|
*/
|
|
QString srid;
|
|
/**
|
|
* Rectangle that contains the extent (bounding box) of the layer
|
|
*/
|
|
QgsRect layerExtent;
|
|
|
|
/**
|
|
* Number of features in the layer
|
|
*/
|
|
long numberFeatures;
|
|
|
|
/**
|
|
* Flag indicating whether data from binary cursors must undergo an
|
|
* endian conversion prior to use
|
|
@note
|
|
|
|
XXX Umm, it'd be helpful to know what we're swapping from and to.
|
|
XXX Presumably this means swapping from big-endian (network) byte order
|
|
XXX to little-endian; but the inverse transaction is possible, too, and
|
|
XXX that's not reflected in this variable
|
|
*/
|
|
bool swapEndian;
|
|
|
|
bool deduceEndian();
|
|
bool getGeometryDetails();
|
|
|
|
bool ready;
|
|
std::ofstream pLog;
|
|
|
|
//! PostGIS version string
|
|
QString postgisVersionInfo;
|
|
|
|
//! GEOS capability
|
|
bool geosAvailable;
|
|
|
|
//! GIST capability
|
|
bool gistAvailable;
|
|
|
|
//! PROJ4 capability
|
|
bool projAvailable;
|
|
|
|
/**Writes a single feature*/
|
|
bool addFeature(QgsFeature* f);
|
|
|
|
/**Deletes a feature*/
|
|
bool deleteFeature(int id);
|
|
|
|
//! Get the feature count based on the where clause
|
|
long getFeatureCount();
|
|
|
|
//! Calculate the extents of the layer
|
|
void calculateExtents();
|
|
|
|
/**
|
|
* Event sink for events from threads
|
|
*/
|
|
void customEvent ( QCustomEvent * e );
|
|
|
|
};
|
|
|
|
#endif
|