[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