[QGIS Commit] r9083 - trunk/qgis/src/providers/wfs
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Wed Aug 20 05:03:14 EDT 2008
Author: jef
Date: 2008-08-20 05:03:14 -0400 (Wed, 20 Aug 2008)
New Revision: 9083
Modified:
trunk/qgis/src/providers/wfs/CMakeLists.txt
trunk/qgis/src/providers/wfs/qgswfsdata.cpp
trunk/qgis/src/providers/wfs/qgswfsdata.h
trunk/qgis/src/providers/wfs/qgswfsprovider.cpp
trunk/qgis/src/providers/wfs/qgswfsprovider.h
Log:
port wfs provider to QgsSpatialIndex
Modified: trunk/qgis/src/providers/wfs/CMakeLists.txt
===================================================================
--- trunk/qgis/src/providers/wfs/CMakeLists.txt 2008-08-20 08:52:05 UTC (rev 9082)
+++ trunk/qgis/src/providers/wfs/CMakeLists.txt 2008-08-20 09:03:14 UTC (rev 9083)
@@ -22,6 +22,7 @@
INCLUDE_DIRECTORIES (
../../core
+ ../../core/spatialindex
${GEOS_INCLUDE_DIR}
${GEOS_INCLUDE_DIR}/geos
${EXPAT_INCLUDE_DIR}
Modified: trunk/qgis/src/providers/wfs/qgswfsdata.cpp
===================================================================
--- trunk/qgis/src/providers/wfs/qgswfsdata.cpp 2008-08-20 08:52:05 UTC (rev 9082)
+++ trunk/qgis/src/providers/wfs/qgswfsdata.cpp 2008-08-20 09:03:14 UTC (rev 9083)
@@ -17,6 +17,8 @@
#include "qgsspatialrefsys.h"
#include <QBuffer>
#include <QUrl>
+#include <QList>
+#include <QSet>
//just for a test
//#include <QProgressDialog>
@@ -24,7 +26,23 @@
const char NS_SEPARATOR = '?';
const QString GML_NAMESPACE = "http://www.opengis.net/gml";
-QgsWFSData::QgsWFSData(const QString& uri, QgsRect* extent, QgsSpatialRefSys* srs, std::list<QgsFeature*>* features, const QString& geometryAttribute, const std::set<QString>& thematicAttributes, QGis::WKBTYPE* wkbType): QObject(), mUri(uri), mExtent(extent), mSrs(srs), mFeatures(features), mGeometryAttribute(geometryAttribute), mThematicAttributes(thematicAttributes), mWkbType(wkbType), mFinished(false), mFeatureCount(0)
+QgsWFSData::QgsWFSData(
+ const QString& uri, QgsRect* extent,
+ QgsSpatialRefSys* srs,
+ QList<QgsFeature*> &features,
+ const QString& geometryAttribute,
+ const QSet<QString>& thematicAttributes,
+ QGis::WKBTYPE* wkbType)
+: QObject(),
+ mUri(uri),
+ mExtent(extent),
+ mSrs(srs),
+ mFeatures(features),
+ mGeometryAttribute(geometryAttribute),
+ mThematicAttributes(thematicAttributes),
+ mWkbType(wkbType),
+ mFinished(false),
+ mFeatureCount(0)
{
//qWarning("Name of the geometry attribute is:");
//qWarning(mGeometryAttribute.toLocal8Bit().data());
@@ -51,11 +69,6 @@
}
-QgsWFSData::QgsWFSData()
-{
-
-}
-
int QgsWFSData::getWFSData()
{
XML_Parser p = XML_ParserCreateNS(NULL, NS_SEPARATOR);
@@ -237,7 +250,7 @@
else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "featureMember")
{
mCurrentFeature->setGeometryAndOwnership(mCurrentWKB, mCurrentWKBSize);
- mFeatures->push_back(mCurrentFeature);
+ mFeatures << mCurrentFeature;
++mFeatureCount;
//qWarning("Removing featureMember from stack");
mParseModeStack.pop();
Modified: trunk/qgis/src/providers/wfs/qgswfsdata.h
===================================================================
--- trunk/qgis/src/providers/wfs/qgswfsdata.h 2008-08-20 08:52:05 UTC (rev 9082)
+++ trunk/qgis/src/providers/wfs/qgswfsdata.h 2008-08-20 09:03:14 UTC (rev 9083)
@@ -34,7 +34,14 @@
{
Q_OBJECT
public:
- QgsWFSData(const QString& uri, QgsRect* extent, QgsSpatialRefSys* srs, std::list<QgsFeature*>* features, const QString& geometryAttribute, const std::set<QString>& thematicAttributes, QGis::WKBTYPE* wkbType);
+ QgsWFSData(
+ const QString& uri,
+ QgsRect* extent,
+ QgsSpatialRefSys* srs,
+ QList<QgsFeature*> &features,
+ const QString& geometryAttribute,
+ const QSet<QString>& thematicAttributes,
+ QGis::WKBTYPE* wkbType);
~QgsWFSData();
/**Does the Http GET request to the wfs server
@@ -74,17 +81,17 @@
void endElement(const XML_Char* el);
void characters(const XML_Char* chars, int len);
static void start(void* data, const XML_Char* el, const XML_Char** attr)
- {
- static_cast<QgsWFSData*>(data)->startElement(el, attr);
- }
+ {
+ static_cast<QgsWFSData*>(data)->startElement(el, attr);
+ }
static void end(void* data, const XML_Char* el)
- {
- static_cast<QgsWFSData*>(data)->endElement(el);
- }
+ {
+ static_cast<QgsWFSData*>(data)->endElement(el);
+ }
static void chars(void* data, const XML_Char* chars, int len)
- {
- static_cast<QgsWFSData*>(data)->characters(chars, len);
- }
+ {
+ static_cast<QgsWFSData*>(data)->characters(chars, len);
+ }
//helper routines
/**Reads attribute srsName="EPSG:..."
@@ -126,10 +133,10 @@
/**Source srs of the layer*/
QgsSpatialRefSys* mSrs;
/**The features of the layer*/
- std::list<QgsFeature*>* mFeatures;
+ QList<QgsFeature*> &mFeatures;
/**Name of geometry attribute*/
QString mGeometryAttribute;
- std::set<QString> mThematicAttributes;
+ const QSet<QString> &mThematicAttributes;
QGis::WKBTYPE* mWkbType;
/**True if the request is finished*/
bool mFinished;
Modified: trunk/qgis/src/providers/wfs/qgswfsprovider.cpp
===================================================================
--- trunk/qgis/src/providers/wfs/qgswfsprovider.cpp 2008-08-20 08:52:05 UTC (rev 9082)
+++ trunk/qgis/src/providers/wfs/qgswfsprovider.cpp 2008-08-20 09:03:14 UTC (rev 9083)
@@ -23,6 +23,7 @@
#include "qgsspatialrefsys.h"
#include "qgswfsdata.h"
#include "qgswfsprovider.h"
+#include "qgsspatialindex.h"
#include "qgslogger.h"
#include <QDomDocument>
#include <QDomNodeList>
@@ -37,8 +38,9 @@
static const QString GML_NAMESPACE = "http://www.opengis.net/gml";
QgsWFSProvider::QgsWFSProvider(const QString& uri)
- : QgsVectorDataProvider(uri), mUseIntersect(false), mSelectedFeatures(0), mSourceSRS(0), mFeatureCount(0), mValid(true)
+ : QgsVectorDataProvider(uri), mUseIntersect(false), mSourceSRS(0), mFeatureCount(0), mValid(true)
{
+ mSpatialIndex = new QgsSpatialIndex;
if(getFeature(uri) == 0)
{
mValid = true;
@@ -54,58 +56,56 @@
QgsWFSProvider::~QgsWFSProvider()
{
- delete mSelectedFeatures;
- for(std::list<std::pair<GEOS_GEOM::Envelope*, QgsFeature*> >::iterator it = mEnvelopesAndFeatures.begin();\
- it != mEnvelopesAndFeatures.end(); ++it)
- {
- delete it->first;
- delete it->second;
- }
+ mSelectedFeatures.clear();
+ for(int i=0; i<mFeatures.size(); i++)
+ delete mFeatures[i];
+ mFeatures.clear();
+ delete mSpatialIndex;
}
bool QgsWFSProvider::getNextFeature(QgsFeature& feature)
{
while(true) //go through the loop until we find a feature in the filter
+ {
+ if(mSelectedFeatures.size()==0 || mFeatureIterator==mSelectedFeatures.end())
{
- if(!mSelectedFeatures || mFeatureIterator == mSelectedFeatures->end())
- {
- return 0;
- }
+ return 0;
+ }
- feature.setFeatureId(((QgsFeature*)(*mFeatureIterator))->featureId());
- if(mFetchGeom)
- {
- QgsGeometry* geometry = ((QgsFeature*)(*mFeatureIterator))->geometry();
- unsigned char* geom = geometry->wkbBuffer();
- int geomSize = geometry->wkbSize();
-
- unsigned char* copiedGeom = new unsigned char[geomSize];
- memcpy(copiedGeom, geom, geomSize);
- feature.setGeometryAndOwnership(copiedGeom, geomSize);
- }
-
- const QgsAttributeMap& attributes = ((QgsFeature*)(*mFeatureIterator))->attributeMap();
- for(QgsAttributeList::const_iterator it = mAttributesToFetch.begin(); it != mAttributesToFetch.end(); ++it)
- {
- feature.addAttribute(*it, attributes[*it]);
- }
- ++mFeatureIterator;
- if(mUseIntersect)
- {
- if(feature.geometry()->intersects(mSpatialFilter))
- {
- return true;
- }
- else
- {
- continue; //go for the next feature
- }
- }
+ feature.setFeatureId( mFeatures[*mFeatureIterator]->featureId() );
+ if(mFetchGeom)
+ {
+ QgsGeometry* geometry = mFeatures[*mFeatureIterator]->geometry();
+ unsigned char *geom = geometry->wkbBuffer();
+ int geomSize = geometry->wkbSize();
+
+ unsigned char* copiedGeom = new unsigned char[geomSize];
+ memcpy(copiedGeom, geom, geomSize);
+ feature.setGeometryAndOwnership(copiedGeom, geomSize);
+ }
+
+ const QgsAttributeMap& attributes = mFeatures[*mFeatureIterator]->attributeMap();
+ for(QgsAttributeList::const_iterator it = mAttributesToFetch.begin(); it != mAttributesToFetch.end(); ++it)
+ {
+ feature.addAttribute(*it, attributes[*it]);
+ }
+ ++mFeatureIterator;
+ if(mUseIntersect)
+ {
+ if(feature.geometry()->intersects(mSpatialFilter))
+ {
+ return true;
+ }
else
- {
- return true;
- }
+ {
+ continue; //go for the next feature
+ }
}
+ else
+ {
+ return true;
+ }
+ }
}
@@ -132,10 +132,7 @@
void QgsWFSProvider::reset()
{
- if(mSelectedFeatures)
- {
- mFeatureIterator = mSelectedFeatures->begin();
- }
+ mFeatureIterator = mSelectedFeatures.begin();
}
QgsSpatialRefSys QgsWFSProvider::getSRS()
@@ -162,24 +159,17 @@
mAttributesToFetch = fetchAttributes;
mFetchGeom = fetchGeometry;
- delete mSelectedFeatures;
if(rect.isEmpty())
- {
- mSpatialFilter = mExtent;
- }
+ {
+ mSpatialFilter = mExtent;
+ }
else
- {
- mSpatialFilter = rect;
- }
+ {
+ mSpatialFilter = rect;
+ }
- GEOS_GEOM::Envelope filter(mSpatialFilter.xMin(), mSpatialFilter.xMax(), mSpatialFilter.yMin(), mSpatialFilter.yMax());
-#if GEOS_VERSION_MAJOR < 3
- mSelectedFeatures = mSpatialIndex.query(&filter);
-#else
- mSelectedFeatures = new std::vector<void*>;
- mSpatialIndex.query(&filter, *mSelectedFeatures);
-#endif
- mFeatureIterator = mSelectedFeatures->begin();
+ mSelectedFeatures = mSpatialIndex->intersects(mSpatialFilter);
+ mFeatureIterator = mSelectedFeatures.begin();
}
int QgsWFSProvider::getFeature(const QString& uri)
@@ -249,20 +239,20 @@
QByteArray result;
QgsHttpTransaction http(request);
http.getSynchronously(result);
-
+
QDomDocument getFeatureDocument;
if(!getFeatureDocument.setContent(result, true))
- {
- return 1; //error
- }
+ {
+ return 1; //error
+ }
QDomElement featureCollectionElement = getFeatureDocument.documentElement();
-
+
//get and set Extent
if(getExtentFromGML2(&mExtent, featureCollectionElement) != 0)
- {
- return 3;
- }
+ {
+ return 3;
+ }
setSRSFromGML2(featureCollectionElement);
@@ -275,58 +265,52 @@
#endif
//the new and faster method with the expat parser
- std::list<QgsFeature*> dataFeatures;
- std::set<QString> thematicAttributes;
+ QSet<QString> thematicAttributes;
for(QgsFieldMap::const_iterator it = mFields.begin(); it != mFields.end(); ++it)
- {
- thematicAttributes.insert(it->name());
- }
-
- QgsWFSData dataReader(uri, &mExtent, &mSourceSRS, &dataFeatures, geometryAttribute, thematicAttributes, &mWKBType);
+ {
+ thematicAttributes << it->name();
+ }
+
+ QgsWFSData dataReader(uri, &mExtent, &mSourceSRS, mFeatures, geometryAttribute, thematicAttributes, &mWKBType);
QObject::connect(dataReader.http(), SIGNAL(dataReadProgress(int, int)), this, SLOT(handleWFSProgressMessage(int, int)));
//also connect to setStatus signal of qgisapp (if it exists)
QWidget* mainWindow = 0;
-
+
QWidgetList topLevelWidgets = qApp->topLevelWidgets();
QWidgetList::iterator it = topLevelWidgets.begin();
for(; it != topLevelWidgets.end(); ++it)
+ {
+ if((*it)->objectName() == "QgisApp")
{
- if((*it)->objectName() == "QgisApp")
- {
- mainWindow = *it;
- break;
- }
+ mainWindow = *it;
+ break;
}
-
+ }
+
if(mainWindow)
- {
- QObject::connect(this, SIGNAL(dataReadProgressMessage(QString)), mainWindow, SLOT(showStatusMessage(QString)));
- }
+ {
+ QObject::connect(this, SIGNAL(dataReadProgressMessage(QString)), mainWindow, SLOT(showStatusMessage(QString)));
+ }
if(dataReader.getWFSData() != 0)
- {
- qWarning("getWFSData returned with error");
- return 1;
- }
+ {
+ qWarning("getWFSData returned with error");
+ return 1;
+ }
qWarning("feature count after request is:");
- qWarning(QString::number(dataFeatures.size()).toLocal8Bit().data());
+ qWarning(QString::number(mFeatures.size()).toLocal8Bit().data());
qWarning("mExtent after request is:");
qWarning(mExtent.stringRep().toLocal8Bit().data());
- mFeatureCount = 0;
+ for(QList<QgsFeature*>::iterator it = mFeatures.begin(); it != mFeatures.end(); ++it) {
+ QgsDebugMsg("feature " + QString::number((*it)->featureId()));
+ mSpatialIndex->insertFeature(**it);
+ }
- QgsRect featureBBox;
- GEOS_GEOM::Envelope* geosBBox;
- for(std::list<QgsFeature*>::const_iterator it = dataFeatures.begin(); it != dataFeatures.end(); ++it)
- {
- featureBBox = (*it)->geometry()->boundingBox();
- geosBBox = new GEOS_GEOM::Envelope(featureBBox.xMin(), featureBBox.xMax(), featureBBox.yMin(), featureBBox.yMax());
- mSpatialIndex.insert(geosBBox, (void*)(*it));
- mEnvelopesAndFeatures.push_back(std::make_pair(geosBBox, (*it)));
- ++mFeatureCount;
- }
+ mFeatureCount = mFeatures.size();
+
return 0;
}
@@ -755,8 +739,6 @@
unsigned char* wkb = 0;
int wkbSize = 0;
QGis::WKBTYPE currentType;
- QgsRect featureBBox;
- GEOS_GEOM::Envelope* geosBBox;
mFeatureCount = 0;
for(int i = 0; i < featureTypeNodeList.size(); ++i)
@@ -800,10 +782,8 @@
if(wkb && wkbSize > 0)
{
//insert bbox and pointer to feature into search tree
- featureBBox = f->geometry()->boundingBox();
- geosBBox = new GEOS_GEOM::Envelope(featureBBox.xMin(), featureBBox.xMax(), featureBBox.yMin(), featureBBox.yMax());
- mSpatialIndex.insert(geosBBox, (void*)f);
- mEnvelopesAndFeatures.push_back(std::make_pair(geosBBox, f));
+ mSpatialIndex->insertFeature(*f);
+ mFeatures << f;
++mFeatureCount;
}
++counter;
Modified: trunk/qgis/src/providers/wfs/qgswfsprovider.h
===================================================================
--- trunk/qgis/src/providers/wfs/qgswfsprovider.h 2008-08-20 08:52:05 UTC (rev 9082)
+++ trunk/qgis/src/providers/wfs/qgswfsprovider.h 2008-08-20 09:03:14 UTC (rev 9083)
@@ -23,20 +23,9 @@
#include "qgsrect.h"
#include "qgsspatialrefsys.h"
#include "qgsvectordataprovider.h"
-#include <geos/version.h>
-#if GEOS_VERSION_MAJOR < 3
-#include <geos/geom.h>
-#include <geos/indexStrtree.h>
-#define GEOS_GEOM geos
-#define GEOS_INDEX_STRTREE geos
-#else
-#include <geos/geom/Envelope.h>
-#include <geos/index/strtree/STRtree.h>
-#define GEOS_GEOM geos::geom
-#define GEOS_INDEX_STRTREE geos::index::strtree
-#endif
class QgsRect;
+class QgsSpatialIndex;
/**A provider reading features from a WFS server*/
class QgsWFSProvider: public QgsVectorDataProvider
@@ -122,13 +111,13 @@
/**Flag if precise intersection test is needed. Otherwise, every feature is returned (even if a filter is set)*/
bool mUseIntersect;
/**A spatial index for fast access to a feature subset*/
- GEOS_INDEX_STRTREE::STRtree mSpatialIndex;
- /**Stores all the inserted rectangles and features. This is used to clean up the memory in the destructor*/
- std::list< std::pair<GEOS_GEOM::Envelope*, QgsFeature*> > mEnvelopesAndFeatures;
- /**Vector where the QgsFeature* of a query are inserted*/
- std::vector<void*>* mSelectedFeatures;
+ QgsSpatialIndex *mSpatialIndex;
+ /**Vector where the ids of the selected features are inserted*/
+ QList<int> mSelectedFeatures;
/**Iterator on the feature vector for use in reset(), getNextFeature(), etc...*/
- std::vector<void*>::iterator mFeatureIterator;
+ QList<int>::iterator mFeatureIterator;
+ /**Vector where the features are inserted*/
+ QList<QgsFeature*> mFeatures;
/**Geometry type of the features in this layer*/
mutable QGis::WKBTYPE mWKBType;
/**Source SRS*/
More information about the QGIS-commit
mailing list