mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-26 00:02:08 -05:00
Brendan Morley's postgis threaded extents patch
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@2935 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
59bffa930a
commit
ffbf03c76f
@ -1,17 +1,39 @@
|
|||||||
INCLUDES = -I../../src
|
INCLUDES = -I../../src
|
||||||
|
|
||||||
|
%.moc.cpp: %.h
|
||||||
|
$(MOC) -o $@ $<
|
||||||
|
|
||||||
plugindir = ${pkglibdir}
|
plugindir = ${pkglibdir}
|
||||||
plugin_LTLIBRARIES = postgresprovider.la
|
plugin_LTLIBRARIES = postgresprovider.la
|
||||||
|
|
||||||
|
|
||||||
postgresprovider_la_SOURCES = qgspostgresprovider.cpp \
|
## non-uic files generated from MOC
|
||||||
qgspostgresprovider.h \
|
|
||||||
../../src/qgsfeature.cpp \
|
|
||||||
../../src/qgsfeatureattribute.cpp \
|
|
||||||
../../src/qgsrect.cpp \
|
|
||||||
../../src/qgspoint.cpp \
|
|
||||||
../../src/qgsfield.cpp
|
|
||||||
|
|
||||||
|
postgresprovider_MOC = qgspostgresprovider.moc.cpp
|
||||||
|
|
||||||
|
|
||||||
|
postgresprovider_la_SOURCES = \
|
||||||
|
qgspostgresprovider.cpp \
|
||||||
|
qgspostgresprovider.moc.cpp \
|
||||||
|
qgspostgresprovider.h \
|
||||||
|
../../src/qgsfeature.cpp \
|
||||||
|
../../src/qgsfeatureattribute.cpp \
|
||||||
|
../../src/qgsrect.cpp \
|
||||||
|
../../src/qgspoint.cpp \
|
||||||
|
../../src/qgsfield.cpp \
|
||||||
|
qgspostgisbox2d.cpp \
|
||||||
|
qgspostgisbox2d.h \
|
||||||
|
qgspostgisbox3d.cpp \
|
||||||
|
qgspostgisbox3d.h \
|
||||||
|
qgspostgrescountthread.cpp \
|
||||||
|
qgspostgrescountthread.h \
|
||||||
|
qgspostgresextentthread.cpp \
|
||||||
|
qgspostgresextentthread.h
|
||||||
|
|
||||||
|
BUILT_SOURCES = $(postgresprovider_MOC)
|
||||||
|
|
||||||
postgresprovider_la_LIBADD = $(QT_LDADD) $(PG_LIB) $(GEOS_LDADD)
|
postgresprovider_la_LIBADD = $(QT_LDADD) $(PG_LIB) $(GEOS_LDADD)
|
||||||
postgresprovider_la_LDFLAGS = -avoid-version -module
|
postgresprovider_la_LDFLAGS = -avoid-version -module
|
||||||
postgresprovider_la_CXXFLAGS = $(EXTRA_CXXFLAGS) $(QT_CXXFLAGS) -I$(PG_INC) $(DEBUG_QGIS) $(GEOS_CFLAGS)
|
postgresprovider_la_CXXFLAGS = $(EXTRA_CXXFLAGS) $(QT_CXXFLAGS) -I$(PG_INC) $(DEBUG_QGIS) $(GEOS_CFLAGS)
|
||||||
|
|
||||||
|
CLEANFILES = $(BUILT_SOURCES)
|
||||||
|
@ -39,7 +39,16 @@
|
|||||||
#include "../../src/qgsfield.h"
|
#include "../../src/qgsfield.h"
|
||||||
#include "../../src/qgsrect.h"
|
#include "../../src/qgsrect.h"
|
||||||
|
|
||||||
|
#include "../../src/qgsprovidercountcalcevent.h"
|
||||||
|
#include "../../src/qgsproviderextentcalcevent.h"
|
||||||
|
|
||||||
#include "qgspostgresprovider.h"
|
#include "qgspostgresprovider.h"
|
||||||
|
|
||||||
|
#include "qgspostgrescountthread.h"
|
||||||
|
#include "qgspostgresextentthread.h"
|
||||||
|
|
||||||
|
#include "qgspostgisbox3d.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#define QGISEXTERN extern "C" __declspec( dllexport )
|
#define QGISEXTERN extern "C" __declspec( dllexport )
|
||||||
#else
|
#else
|
||||||
@ -230,6 +239,29 @@ QgsPostgresProvider::QgsPostgresProvider(QString uri):dataSourceUri(uri)
|
|||||||
getPrimaryKey();
|
getPrimaryKey();
|
||||||
selectSQL += " from " + tableName;
|
selectSQL += " from " + tableName;
|
||||||
//--std::cout << "selectSQL: " << (const char *)selectSQL << std::endl;
|
//--std::cout << "selectSQL: " << (const char *)selectSQL << std::endl;
|
||||||
|
|
||||||
|
// Kick off the long running threads
|
||||||
|
|
||||||
|
std::cout << "QgsPostgresProvider: About to touch mExtentThread" << std::endl;
|
||||||
|
mExtentThread.setConnInfo( connInfo );
|
||||||
|
mExtentThread.setTableName( tableName );
|
||||||
|
mExtentThread.setSqlWhereClause( sqlWhereClause );
|
||||||
|
mExtentThread.setGeometryColumn( geometryColumn );
|
||||||
|
mExtentThread.setCallback( this );
|
||||||
|
std::cout << "QgsPostgresProvider: About to start mExtentThread" << std::endl;
|
||||||
|
mExtentThread.start();
|
||||||
|
std::cout << "QgsPostgresProvider: Main thread just dispatched mExtentThread" << std::endl;
|
||||||
|
|
||||||
|
std::cout << "QgsPostgresProvider: About to touch mCountThread" << std::endl;
|
||||||
|
mCountThread.setConnInfo( connInfo );
|
||||||
|
mCountThread.setTableName( tableName );
|
||||||
|
mCountThread.setSqlWhereClause( sqlWhereClause );
|
||||||
|
mCountThread.setGeometryColumn( geometryColumn );
|
||||||
|
mCountThread.setCallback( this );
|
||||||
|
std::cout << "QgsPostgresProvider: About to start mCountThread" << std::endl;
|
||||||
|
mCountThread.start();
|
||||||
|
std::cout << "QgsPostgresProvider: Main thread just dispatched mCountThread" << std::endl;
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// the table is not a geometry table
|
// the table is not a geometry table
|
||||||
@ -270,7 +302,27 @@ QgsPostgresProvider::QgsPostgresProvider(QString uri):dataSourceUri(uri)
|
|||||||
|
|
||||||
QgsPostgresProvider::~QgsPostgresProvider()
|
QgsPostgresProvider::~QgsPostgresProvider()
|
||||||
{
|
{
|
||||||
|
std::cout << "QgsPostgresProvider: About to wait for mExtentThread" << std::endl;
|
||||||
|
|
||||||
|
mExtentThread.wait();
|
||||||
|
|
||||||
|
std::cout << "QgsPostgresProvider: Finished waiting for mExtentThread" << std::endl;
|
||||||
|
|
||||||
|
std::cout << "QgsPostgresProvider: About to wait for mCountThread" << std::endl;
|
||||||
|
|
||||||
|
mCountThread.wait();
|
||||||
|
|
||||||
|
std::cout << "QgsPostgresProvider: Finished waiting for mCountThread" << std::endl;
|
||||||
|
|
||||||
|
// Make sure all events from threads have been processed
|
||||||
|
// (otherwise they will get destroyed prematurely)
|
||||||
|
QApplication::sendPostedEvents(this, QGis::ProviderExtentCalcEvent);
|
||||||
|
QApplication::sendPostedEvents(this, QGis::ProviderCountCalcEvent);
|
||||||
|
|
||||||
PQfinish(connection);
|
PQfinish(connection);
|
||||||
|
|
||||||
|
std::cout << "QgsPostgresProvider: deconstructing." << std::endl;
|
||||||
|
|
||||||
//pLog.flush();
|
//pLog.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,7 +485,7 @@ QgsFeature* QgsPostgresProvider::getNextFeature(std::list<int> const & attlist)
|
|||||||
{
|
{
|
||||||
// XXX I'm assuming swapping from big-endian, or network, byte order to little endian
|
// XXX I'm assuming swapping from big-endian, or network, byte order to little endian
|
||||||
#ifdef QGISDEBUG
|
#ifdef QGISDEBUG
|
||||||
qWarning("swapping endian for oid");
|
//XXX TOO MUCH OUTPUT!!! qWarning("swapping endian for oid");
|
||||||
#endif
|
#endif
|
||||||
// convert oid to opposite endian
|
// convert oid to opposite endian
|
||||||
// XXX "Opposite?" Umm, that's not enough information.
|
// XXX "Opposite?" Umm, that's not enough information.
|
||||||
@ -499,8 +551,21 @@ void QgsPostgresProvider::select(QgsRect * rect, bool useIntersect)
|
|||||||
std::cout << "Binary cursor: " << declare << std::endl;
|
std::cout << "Binary cursor: " << declare << std::endl;
|
||||||
#endif
|
#endif
|
||||||
if(useIntersect){
|
if(useIntersect){
|
||||||
declare += " where intersects(" + geometryColumn;
|
// declare += " where intersects(" + geometryColumn;
|
||||||
declare += ", setsrid('BOX3D(" + rect->stringRep();
|
// declare += ", GeometryFromText('BOX3D(" + rect->stringRep();
|
||||||
|
// declare += ")'::box3d,";
|
||||||
|
// declare += srid;
|
||||||
|
// declare += "))";
|
||||||
|
|
||||||
|
// Contributed by #qgis irc "creeping"
|
||||||
|
// This version actually invokes PostGIS's use of spatial indexes
|
||||||
|
declare += " where " + geometryColumn;
|
||||||
|
declare += " && GeometryFromText('BOX3D(" + rect->stringRep();
|
||||||
|
declare += ")'::box3d,";
|
||||||
|
declare += srid;
|
||||||
|
declare += ")";
|
||||||
|
declare += " and intersects(" + geometryColumn;
|
||||||
|
declare += ", GeometryFromText('BOX3D(" + rect->stringRep();
|
||||||
declare += ")'::box3d,";
|
declare += ")'::box3d,";
|
||||||
declare += srid;
|
declare += srid;
|
||||||
declare += "))";
|
declare += "))";
|
||||||
@ -576,6 +641,13 @@ return gPtr;
|
|||||||
|
|
||||||
} */
|
} */
|
||||||
|
|
||||||
|
void QgsPostgresProvider::setExtent( QgsRect* newExtent )
|
||||||
|
{
|
||||||
|
layerExtent.setXmax( newExtent->xMax() );
|
||||||
|
layerExtent.setXmin( newExtent->xMin() );
|
||||||
|
layerExtent.setYmax( newExtent->yMax() );
|
||||||
|
layerExtent.setYmin( newExtent->yMin() );
|
||||||
|
}
|
||||||
|
|
||||||
// TODO - make this function return the real extent_
|
// TODO - make this function return the real extent_
|
||||||
QgsRect *QgsPostgresProvider::extent()
|
QgsRect *QgsPostgresProvider::extent()
|
||||||
@ -1190,35 +1262,62 @@ void QgsPostgresProvider::setSubsetString(QString theSQL)
|
|||||||
calculateExtents();
|
calculateExtents();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long QgsPostgresProvider::getFeatureCount()
|
long QgsPostgresProvider::getFeatureCount()
|
||||||
{
|
{
|
||||||
// get total number of features
|
// get total number of features
|
||||||
QString sql = "select count(*) from " + tableName;
|
|
||||||
if(sqlWhereClause.length() > 0)
|
// First get an approximate count; then delegate to
|
||||||
{
|
// a thread the task of getting the full count.
|
||||||
sql += " where " + sqlWhereClause;
|
|
||||||
}
|
QString sql = "select reltuples from pg_catalog.pg_class where relname = '" +
|
||||||
|
tableName + "'";
|
||||||
|
|
||||||
|
std::cerr << "QgsPostgresProvider: Running SQL: " <<
|
||||||
|
sql << std::endl;
|
||||||
|
|
||||||
|
//QString sql = "select count(*) from " + tableName;
|
||||||
|
|
||||||
|
//if(sqlWhereClause.length() > 0)
|
||||||
|
//{
|
||||||
|
// sql += " where " + sqlWhereClause;
|
||||||
|
//}
|
||||||
|
|
||||||
PGresult *result = PQexec(connection, (const char *) sql);
|
PGresult *result = PQexec(connection, (const char *) sql);
|
||||||
|
|
||||||
|
#ifdef QGISDEBUG
|
||||||
|
std::cerr << "QgsPostgresProvider: Approximate Number of features as text: " <<
|
||||||
|
PQgetvalue(result, 0, 0) << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
numberFeatures = QString(PQgetvalue(result, 0, 0)).toLong();
|
numberFeatures = QString(PQgetvalue(result, 0, 0)).toLong();
|
||||||
PQclear(result);
|
PQclear(result);
|
||||||
|
|
||||||
#ifdef QGISDEBUG
|
#ifdef QGISDEBUG
|
||||||
std::cerr << "Number of features: " << numberFeatures << std::endl;
|
std::cerr << "QgsPostgresProvider: Approximate Number of features: " <<
|
||||||
|
numberFeatures << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return numberFeatures;
|
return numberFeatures;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: use the estimateExtents procedure of PostGIS and PostgreSQL 8
|
||||||
|
// This tip thanks to #qgis irc nick "creeping"
|
||||||
void QgsPostgresProvider::calculateExtents()
|
void QgsPostgresProvider::calculateExtents()
|
||||||
{
|
{
|
||||||
// get the extents
|
// get the approximate extent by retreiving the bounding box
|
||||||
|
// of the first few items with a geometry
|
||||||
|
|
||||||
QString sql = "select extent(" + geometryColumn + ") from " + tableName;
|
QString sql = "select box3d(" + geometryColumn + ") from " + tableName +
|
||||||
|
" where ";
|
||||||
|
|
||||||
if(sqlWhereClause.length() > 0)
|
if(sqlWhereClause.length() > 0)
|
||||||
{
|
{
|
||||||
sql += " where " + sqlWhereClause;
|
sql += "(" + sqlWhereClause + ") and ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sql += "not IsEmpty(" + geometryColumn + ") limit 5";
|
||||||
|
|
||||||
#if WASTE_TIME
|
#if WASTE_TIME
|
||||||
sql = "select xmax(extent(" + geometryColumn + ")) as xmax,"
|
sql = "select xmax(extent(" + geometryColumn + ")) as xmax,"
|
||||||
"xmin(extent(" + geometryColumn + ")) as xmin,"
|
"xmin(extent(" + geometryColumn + ")) as xmin,"
|
||||||
@ -1226,50 +1325,108 @@ void QgsPostgresProvider::calculateExtents()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef QGISDEBUG
|
#ifdef QGISDEBUG
|
||||||
qDebug("+++++++++QgsPostgresProvider::calculateExtents - Getting extents using schema.table: " + sql);
|
qDebug("QgsPostgresProvider::calculateExtents - Getting approximate extent using: '" + sql + "'");
|
||||||
#endif
|
#endif
|
||||||
PGresult *result = PQexec(connection, (const char *) sql);
|
PGresult *result = PQexec(connection, (const char *) sql);
|
||||||
std::string box3d = PQgetvalue(result, 0, 0);
|
|
||||||
|
// TODO: Guard against the result having no rows
|
||||||
if (box3d != "")
|
|
||||||
|
for (int i = 0; i < PQntuples(result); i++)
|
||||||
{
|
{
|
||||||
std::string s;
|
std::string box3d = PQgetvalue(result, i, 0);
|
||||||
|
|
||||||
box3d = box3d.substr(box3d.find_first_of("(")+1);
|
if (0 == i)
|
||||||
box3d = box3d.substr(box3d.find_first_not_of(" "));
|
{
|
||||||
s = box3d.substr(0, box3d.find_first_of(" "));
|
// create the initial extent
|
||||||
double minx = strtod(s.c_str(), NULL);
|
layerExtent = QgsPostGisBox3d(box3d);
|
||||||
|
}
|
||||||
box3d = box3d.substr(box3d.find_first_of(" ")+1);
|
else
|
||||||
s = box3d.substr(0, box3d.find_first_of(" "));
|
{
|
||||||
double miny = strtod(s.c_str(), NULL);
|
// extend the initial extent
|
||||||
|
QgsPostGisBox3d b = QgsPostGisBox3d(box3d);
|
||||||
box3d = box3d.substr(box3d.find_first_of(",")+1);
|
|
||||||
box3d = box3d.substr(box3d.find_first_not_of(" "));
|
layerExtent.combineExtentWith( &b );
|
||||||
s = box3d.substr(0, box3d.find_first_of(" "));
|
}
|
||||||
double maxx = strtod(s.c_str(), NULL);
|
|
||||||
|
std::cout << "QgsPostgresProvider: After row " << i << ", extent is: "
|
||||||
box3d = box3d.substr(box3d.find_first_of(" ")+1);
|
<< layerExtent.xMin() << ", " << layerExtent.yMin() <<
|
||||||
s = box3d.substr(0, box3d.find_first_of(" "));
|
" " << layerExtent.xMax() << ", " << layerExtent.yMax() << std::endl;
|
||||||
double maxy = strtod(s.c_str(), NULL);
|
|
||||||
|
|
||||||
layerExtent.setXmax(maxx);
|
|
||||||
layerExtent.setXmin(minx);
|
|
||||||
layerExtent.setYmax(maxy);
|
|
||||||
layerExtent.setYmin(miny);
|
|
||||||
#ifdef QGISDEBUG
|
|
||||||
QString xMsg;
|
|
||||||
QTextOStream(&xMsg).precision(18);
|
|
||||||
QTextOStream(&xMsg).width(18);
|
|
||||||
QTextOStream(&xMsg) << "Set extents to: " << layerExtent.
|
|
||||||
xMin() << ", " << layerExtent.yMin() << " " << layerExtent.xMax() << ", " << layerExtent.yMax();
|
|
||||||
std::cerr << xMsg << std::endl;
|
|
||||||
#endif
|
|
||||||
// clear query result
|
|
||||||
PQclear(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef QGISDEBUG
|
||||||
|
QString xMsg;
|
||||||
|
QTextOStream(&xMsg).precision(18);
|
||||||
|
QTextOStream(&xMsg).width(18);
|
||||||
|
QTextOStream(&xMsg) << "QgsPostgresProvider: Set extents to: " << layerExtent.
|
||||||
|
xMin() << ", " << layerExtent.yMin() << " " << layerExtent.xMax() << ", " << layerExtent.yMax();
|
||||||
|
std::cerr << xMsg << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::cout << "QgsPostgresProvider: Set limit 5 extents to: "
|
||||||
|
<< layerExtent.xMin() << ", " << layerExtent.yMin() <<
|
||||||
|
" " << layerExtent.xMax() << ", " << layerExtent.yMax() << std::endl;
|
||||||
|
|
||||||
|
// clear query result
|
||||||
|
PQclear(result);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event sink for events from threads
|
||||||
|
*/
|
||||||
|
void QgsPostgresProvider::customEvent( QCustomEvent * e )
|
||||||
|
{
|
||||||
|
std::cout << "QgsPostgresProvider: received a custom event " << e->type() << std::endl;
|
||||||
|
|
||||||
|
switch ( e->type() )
|
||||||
|
{
|
||||||
|
case (QEvent::Type) QGis::ProviderExtentCalcEvent:
|
||||||
|
|
||||||
|
std::cout << "QgsPostgresProvider: extent has been calculated" << std::endl;
|
||||||
|
|
||||||
|
// Collect the new extent from the event and set this layer's
|
||||||
|
// extent with it.
|
||||||
|
|
||||||
|
setExtent( (QgsRect*) e->data() );
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << "QgsPostgresProvider: new extent has been saved" << std::endl;
|
||||||
|
|
||||||
|
std::cout << "QgsPostgresProvider: Set extent to: "
|
||||||
|
<< layerExtent.xMin() << ", " << layerExtent.yMin() <<
|
||||||
|
" " << layerExtent.xMax() << ", " << layerExtent.yMax() << std::endl;
|
||||||
|
|
||||||
|
std::cout << "QgsPostgresProvider: emitting fullExtentCalculated()" << std::endl;
|
||||||
|
|
||||||
|
emit fullExtentCalculated();
|
||||||
|
|
||||||
|
// TODO: Only uncomment this when the overview map canvas has been subclassed
|
||||||
|
// from the QgsMapCanvas
|
||||||
|
|
||||||
|
// std::cout << "QgsPostgresProvider: emitting repaintRequested()" << std::endl;
|
||||||
|
// emit repaintRequested();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (QEvent::Type) QGis::ProviderCountCalcEvent:
|
||||||
|
|
||||||
|
std::cout << "QgsPostgresProvider: count has been calculated" << std::endl;
|
||||||
|
|
||||||
|
QgsProviderCountCalcEvent* e1 = (QgsProviderCountCalcEvent*) e;
|
||||||
|
|
||||||
|
long numberFeatures = e1->numberFeatures();
|
||||||
|
|
||||||
|
std::cout << "QgsPostgresProvider: count is " << numberFeatures << std::endl;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "QgsPostgresProvider: Finished processing custom event " << e->type() << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool QgsPostgresProvider::deduceEndian()
|
bool QgsPostgresProvider::deduceEndian()
|
||||||
{
|
{
|
||||||
// need to store the PostgreSQL endian format used in binary cursors
|
// need to store the PostgreSQL endian format used in binary cursors
|
||||||
@ -1391,7 +1548,9 @@ bool QgsPostgresProvider::getGeometryDetails()
|
|||||||
#endif
|
#endif
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class factory to return a pointer to a newly created
|
* Class factory to return a pointer to a newly created
|
||||||
* QgsPostgresProvider object
|
* QgsPostgresProvider object
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
qgspostgresprovider.h - Data provider for PostgrSQL/PostGIS layers
|
qgspostgresprovider.h - Data provider for PostgreSQL/PostGIS layers
|
||||||
-------------------
|
-------------------
|
||||||
begin : Jan 2, 2004
|
begin : Jan 2, 2004
|
||||||
copyright : (C) 2003 by Gary E.Sherman
|
copyright : (C) 2003 by Gary E.Sherman
|
||||||
@ -15,13 +15,21 @@
|
|||||||
* *
|
* *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
|
#ifndef QGSPOSTGRESPROVIDER_H
|
||||||
|
#define QGSPOSTGRESPROVIDER_H
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include <libpq-fe.h>
|
#include <libpq-fe.h>
|
||||||
}
|
}
|
||||||
#include "../../src/qgsvectordataprovider.h"
|
#include "../../src/qgsvectordataprovider.h"
|
||||||
|
#include "../../src/qgsrect.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
#include<qstring.h>
|
#include <fstream>
|
||||||
|
#include <qstring.h>
|
||||||
|
#include <qobject.h>
|
||||||
|
//#include <qmutex.h>
|
||||||
|
|
||||||
class QgsFeature;
|
class QgsFeature;
|
||||||
class QgsField;
|
class QgsField;
|
||||||
@ -29,9 +37,12 @@ class OGRDataSource;
|
|||||||
class OGRLayer;
|
class OGRLayer;
|
||||||
#include "qgsdatasourceuri.h"
|
#include "qgsdatasourceuri.h"
|
||||||
|
|
||||||
|
#include "qgspostgrescountthread.h"
|
||||||
|
#include "qgspostgresextentthread.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\class QgsPostgresProvider
|
\class QgsPostgresProvider
|
||||||
\brief Data provider for PostgrSQL/PostGIS layers.
|
\brief Data provider for PostgreSQL/PostGIS layers.
|
||||||
|
|
||||||
This provider implements the
|
This provider implements the
|
||||||
interface defined in the QgsDataProvider class to provide access to spatial
|
interface defined in the QgsDataProvider class to provide access to spatial
|
||||||
@ -39,6 +50,9 @@ data residing in a PostgreSQL/PostGIS enabled database.
|
|||||||
*/
|
*/
|
||||||
class QgsPostgresProvider:public QgsVectorDataProvider
|
class QgsPostgresProvider:public QgsVectorDataProvider
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor for the provider. The uri must be in the following format:
|
* Constructor for the provider. The uri must be in the following format:
|
||||||
@ -142,6 +156,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
QString endianString();
|
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
|
/** Return the extent for this data layer
|
||||||
*/
|
*/
|
||||||
virtual QgsRect *extent();
|
virtual QgsRect *extent();
|
||||||
@ -237,6 +257,26 @@ public:
|
|||||||
|
|
||||||
/**Returns a bitmask containing the supported capabilities*/
|
/**Returns a bitmask containing the supported capabilities*/
|
||||||
int capabilities() const;
|
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:
|
private:
|
||||||
|
|
||||||
@ -250,6 +290,14 @@ private:
|
|||||||
//! Data source URI struct for this layer
|
//! Data source URI struct for this layer
|
||||||
QgsDataSourceURI mUri;
|
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,
|
* Pointer to the PostgreSQL query result object. If this pointer is 0,
|
||||||
* there is no current selection set. Any future getNextFeature requests
|
* there is no current selection set. Any future getNextFeature requests
|
||||||
@ -361,4 +409,11 @@ private:
|
|||||||
//! Calculate the extents of the layer
|
//! Calculate the extents of the layer
|
||||||
void calculateExtents();
|
void calculateExtents();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event sink for events from threads
|
||||||
|
*/
|
||||||
|
void customEvent ( QCustomEvent * e );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user