[QGIS Commit] r13902 - branches/threading-branch/src/providers/wfs
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Thu Jul 8 09:45:20 EDT 2010
Author: wonder
Date: 2010-07-08 13:45:20 +0000 (Thu, 08 Jul 2010)
New Revision: 13902
Added:
branches/threading-branch/src/providers/wfs/qgswfsfeatureiterator.cpp
branches/threading-branch/src/providers/wfs/qgswfsfeatureiterator.h
Modified:
branches/threading-branch/src/providers/wfs/CMakeLists.txt
branches/threading-branch/src/providers/wfs/qgswfsprovider.cpp
branches/threading-branch/src/providers/wfs/qgswfsprovider.h
Log:
Adapted WFS provider to use new read API.
Modified: branches/threading-branch/src/providers/wfs/CMakeLists.txt
===================================================================
--- branches/threading-branch/src/providers/wfs/CMakeLists.txt 2010-07-08 12:53:32 UTC (rev 13901)
+++ branches/threading-branch/src/providers/wfs/CMakeLists.txt 2010-07-08 13:45:20 UTC (rev 13902)
@@ -2,7 +2,7 @@
########################################################
# Files
-SET(WFS_SRCS qgswfsprovider.cpp qgswfsdata.cpp)
+SET(WFS_SRCS qgswfsprovider.cpp qgswfsdata.cpp qgswfsfeatureiterator.cpp)
SET (WFS_MOC_HDRS
qgswfsdata.h
Added: branches/threading-branch/src/providers/wfs/qgswfsfeatureiterator.cpp
===================================================================
--- branches/threading-branch/src/providers/wfs/qgswfsfeatureiterator.cpp (rev 0)
+++ branches/threading-branch/src/providers/wfs/qgswfsfeatureiterator.cpp 2010-07-08 13:45:20 UTC (rev 13902)
@@ -0,0 +1,95 @@
+#include "qgswfsfeatureiterator.h"
+#include "qgswfsprovider.h"
+
+#include "qgsgeometry.h"
+#include "qgsspatialindex.h"
+
+// from provider:
+// - mExtent
+// - mSpatialIndex
+// - mFeatures
+
+QgsWFSFeatureIterator::QgsWFSFeatureIterator( QgsWFSProvider* p,
+ QgsAttributeList fetchAttributes,
+ QgsRectangle rect,
+ bool fetchGeometry,
+ bool useIntersect )
+ : QgsVectorDataProviderIterator(fetchAttributes, rect, fetchGeometry, useIntersect),
+ P(p)
+{
+ P->mDataMutex.lock();
+
+ if ( mRect.isEmpty() )
+ {
+ mRect = P->mExtent;
+ }
+
+ mSelectedFeatures = P->mSpatialIndex->intersects( mRect );
+ mFeatureIterator = mSelectedFeatures.begin();
+}
+
+QgsWFSFeatureIterator::~QgsWFSFeatureIterator()
+{
+ close();
+}
+
+bool QgsWFSFeatureIterator::nextFeature(QgsFeature& feature)
+{
+ if (mClosed)
+ return false;
+
+ feature.setValid( false );
+
+ //go through the loop until we find a feature in the filter
+ while ( mSelectedFeatures.size() != 0 && mFeatureIterator != mSelectedFeatures.end() )
+ {
+ QgsFeature* origFeature = P->mFeatures[*mFeatureIterator];
+
+ feature.setFeatureId( origFeature->id() );
+
+ //we need geometry anyway, e.g. for intersection tests
+ QgsGeometry* geometry = origFeature->geometry();
+ unsigned char *geom = geometry->asWkb();
+ int geomSize = geometry->wkbSize();
+ unsigned char* copiedGeom = new unsigned char[geomSize];
+ memcpy( copiedGeom, geom, geomSize );
+ feature.setGeometryAndOwnership( copiedGeom, geomSize );
+
+ const QgsAttributeMap& attributes = origFeature->attributeMap();
+ for ( QgsAttributeList::const_iterator it = mFetchAttributes.begin(); it != mFetchAttributes.end(); ++it )
+ {
+ feature.addAttribute( *it, attributes[*it] );
+ }
+ ++mFeatureIterator;
+
+ if ( mUseIntersect && feature.geometry() && !feature.geometry()->intersects( mRect ) )
+ continue;
+
+ feature.setValid( true );
+ return true;
+ }
+
+ return false;
+}
+
+bool QgsWFSFeatureIterator::rewind()
+{
+ if (mClosed)
+ return false;
+
+ mFeatureIterator = mSelectedFeatures.begin();
+ return true;
+}
+
+bool QgsWFSFeatureIterator::close()
+{
+ if (mClosed)
+ return false;
+
+ mSelectedFeatures.clear();
+
+ P->mDataMutex.unlock();
+
+ mClosed = true;
+ return true;
+}
Added: branches/threading-branch/src/providers/wfs/qgswfsfeatureiterator.h
===================================================================
--- branches/threading-branch/src/providers/wfs/qgswfsfeatureiterator.h (rev 0)
+++ branches/threading-branch/src/providers/wfs/qgswfsfeatureiterator.h 2010-07-08 13:45:20 UTC (rev 13902)
@@ -0,0 +1,38 @@
+#ifndef QGSWFSFEATUREITERATOR_H
+#define QGSWFSFEATUREITERATOR_H
+
+#include "qgsvectordataprovider.h"
+
+class QgsWFSProvider;
+
+class QgsWFSFeatureIterator : public QgsVectorDataProviderIterator
+{
+public:
+ QgsWFSFeatureIterator( QgsWFSProvider* p,
+ QgsAttributeList fetchAttributes,
+ QgsRectangle rect,
+ bool fetchGeometry,
+ bool useIntersect );
+
+ ~QgsWFSFeatureIterator();
+
+ //! fetch next feature, return true on success
+ virtual bool nextFeature(QgsFeature& f);
+
+ //! reset the iterator to the starting position
+ virtual bool rewind();
+
+ //! end of iterating: free the resources / lock
+ virtual bool close();
+
+protected:
+ QgsWFSProvider* P;
+
+ /**Iterator on the feature vector for use in rewind(), nextFeature(), etc...*/
+ QList<int>::iterator mFeatureIterator;
+
+ /**Vector where the ids of the selected features are inserted*/
+ QList<int> mSelectedFeatures;
+};
+
+#endif // QGSWFSFEATUREITERATOR_H
Modified: branches/threading-branch/src/providers/wfs/qgswfsprovider.cpp
===================================================================
--- branches/threading-branch/src/providers/wfs/qgswfsprovider.cpp 2010-07-08 12:53:32 UTC (rev 13901)
+++ branches/threading-branch/src/providers/wfs/qgswfsprovider.cpp 2010-07-08 13:45:20 UTC (rev 13902)
@@ -23,6 +23,7 @@
#include "qgscoordinatereferencesystem.h"
#include "qgswfsdata.h"
#include "qgswfsprovider.h"
+#include "qgswfsfeatureiterator.h"
#include "qgsspatialindex.h"
#include "qgslogger.h"
#include <QDomDocument>
@@ -38,7 +39,7 @@
static const QString GML_NAMESPACE = "http://www.opengis.net/gml";
QgsWFSProvider::QgsWFSProvider( const QString& uri )
- : QgsVectorDataProvider( uri ), mUseIntersect( false ), mSourceCRS( 0 ), mFeatureCount( 0 ), mValid( true )
+ : QgsVectorDataProvider( uri ), mSourceCRS( 0 ), mFeatureCount( 0 ), mValid( true )
{
mSpatialIndex = new QgsSpatialIndex;
if ( getFeature( uri ) == 0 )
@@ -56,62 +57,12 @@
QgsWFSProvider::~QgsWFSProvider()
{
- mSelectedFeatures.clear();
- for ( int i = 0; i < mFeatures.size(); i++ )
- delete mFeatures[i];
- mFeatures.clear();
+ mOldApiIter.close();
+
delete mSpatialIndex;
}
-bool QgsWFSProvider::nextFeature( QgsFeature& feature )
-{
- feature.setValid( false );
- while ( true ) //go through the loop until we find a feature in the filter
- {
- if ( mSelectedFeatures.size() == 0 || mFeatureIterator == mSelectedFeatures.end() )
- {
- return 0;
- }
-
- feature.setFeatureId( mFeatures[*mFeatureIterator]->id() );
-
- //we need geometry anyway, e.g. for intersection tests
- QgsGeometry* geometry = mFeatures[*mFeatureIterator]->geometry();
- unsigned char *geom = geometry->asWkb();
- 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() && feature.geometry()->intersects( mSpatialFilter ) )
- {
- feature.setValid( true );
- return true;
- }
- else
- {
- continue; //go for the next feature
- }
- }
- else
- {
- feature.setValid( true );
- return true;
- }
- }
-}
-
-
-
QGis::WkbType QgsWFSProvider::geometryType() const
{
return mWKBType;
@@ -132,11 +83,6 @@
return mFields;
}
-void QgsWFSProvider::rewind()
-{
- mFeatureIterator = mSelectedFeatures.begin();
-}
-
QgsCoordinateReferenceSystem QgsWFSProvider::crs()
{
return mSourceCRS;
@@ -152,28 +98,47 @@
return mValid;
}
+QgsFeatureIterator QgsWFSProvider::getFeatures( QgsAttributeList fetchAttributes,
+ QgsRectangle rect,
+ bool fetchGeometry,
+ bool useIntersect )
+{
+ if ( !mValid )
+ {
+ QgsDebugMsg( "Read attempt on an invalid WFS layer" );
+ return QgsFeatureIterator();
+ }
+
+ return QgsFeatureIterator( new QgsWFSFeatureIterator(this, fetchAttributes, rect, fetchGeometry, useIntersect) );
+}
+
+
void QgsWFSProvider::select( QgsAttributeList fetchAttributes,
QgsRectangle rect,
bool fetchGeometry,
bool useIntersect )
{
- mUseIntersect = useIntersect;
- mAttributesToFetch = fetchAttributes;
- mFetchGeom = fetchGeometry;
+ mOldApiIter = getFeatures( fetchAttributes, rect, fetchGeometry, useIntersect );
+}
- if ( rect.isEmpty() )
- {
- mSpatialFilter = mExtent;
- }
+bool QgsWFSProvider::nextFeature( QgsFeature& feature )
+{
+ if (mOldApiIter.nextFeature(feature))
+ return true;
else
{
- mSpatialFilter = rect;
+ mOldApiIter.close(); // make sure to unlock the layer
+ return false;
}
+}
- mSelectedFeatures = mSpatialIndex->intersects( mSpatialFilter );
- mFeatureIterator = mSelectedFeatures.begin();
+void QgsWFSProvider::rewind()
+{
+ mOldApiIter.rewind();
}
+
+
int QgsWFSProvider::getFeature( const QString& uri )
{
QString geometryAttribute;
Modified: branches/threading-branch/src/providers/wfs/qgswfsprovider.h
===================================================================
--- branches/threading-branch/src/providers/wfs/qgswfsprovider.h 2010-07-08 12:53:32 UTC (rev 13901)
+++ branches/threading-branch/src/providers/wfs/qgswfsprovider.h 2010-07-08 13:45:20 UTC (rev 13902)
@@ -24,6 +24,8 @@
#include "qgscoordinatereferencesystem.h"
#include "qgsvectordataprovider.h"
+#include <QMutex>
+
class QgsRectangle;
class QgsSpatialIndex;
@@ -65,6 +67,11 @@
*/
virtual bool nextFeature( QgsFeature& feature );
+ virtual QgsFeatureIterator getFeatures( QgsAttributeList fetchAttributes = QgsAttributeList(),
+ QgsRectangle rect = QgsRectangle(),
+ bool fetchGeometry = true,
+ bool useIntersect = false );
+
QGis::WkbType geometryType() const;
long featureCount() const;
uint fieldCount() const;
@@ -106,16 +113,8 @@
REQUEST_ENCODING mEncoding;
/**Bounding box for the layer*/
QgsRectangle mExtent;
- /**Spatial filter for the layer*/
- QgsRectangle mSpatialFilter;
- /**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*/
QgsSpatialIndex *mSpatialIndex;
- /**Vector where the ids of the selected features are inserted*/
- QList<int> mSelectedFeatures;
- /**Iterator on the feature vector for use in rewind(), nextFeature(), etc...*/
- QList<int>::iterator mFeatureIterator;
/**Vector where the features are inserted*/
QList<QgsFeature*> mFeatures;
/**Geometry type of the features in this layer*/
@@ -126,7 +125,12 @@
/**Flag if provider is valid*/
bool mValid;
+ friend class QgsWFSFeatureIterator;
+ QgsFeatureIterator mOldApiIter;
+ QMutex mDataMutex;
+
+
/**Collects information about the field types. Is called internally from QgsWFSProvider::getFeature. The method delegates the work to request specific ones and gives back the name of the geometry attribute and the thematic attributes with their types*/
int describeFeatureType( const QString& uri, QString& geometryAttribute, QgsFieldMap& fields );
More information about the QGIS-commit
mailing list