Skip to content

Commit

Permalink
Merge branch 'iterator'
Browse files Browse the repository at this point in the history
Semi fix #7472.
Semi fix #7862
  • Loading branch information
NathanW2 committed Jun 21, 2013
2 parents 9bbc647 + 6876540 commit 4164d6e
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 20 deletions.
49 changes: 35 additions & 14 deletions src/providers/ogr/qgsogrfeatureiterator.cpp
Expand Up @@ -32,17 +32,31 @@


QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrProvider* p, const QgsFeatureRequest& request )
: QgsAbstractFeatureIterator( request ), P( p )
: QgsAbstractFeatureIterator( request ), P( p ), ogrDataSource(0), ogrLayer(0), mSubsetStringSet(false)
{
// make sure that only one iterator is active
if ( P->mActiveIterator )
mFeatureFetched = false;
P->mActiveIterators.insert( this );

ogrDataSource = OGROpen( TO8F( P->filePath() ), false, NULL );

if ( P->layerName().isNull() )
{
QgsMessageLog::logMessage( QObject::tr( "Already active iterator on this provider was closed." ), QObject::tr( "OGR" ) );
P->mActiveIterator->close();
ogrLayer = OGR_DS_GetLayer( ogrDataSource, P->layerIndex() );
}
else
{
ogrLayer = OGR_DS_GetLayerByName( ogrDataSource, TO8( p->layerName() ) );
}
P->mActiveIterator = this;

mFeatureFetched = false;
if ( !P->subsetString().isEmpty() )
{
QString sql = QString( "SELECT * FROM %1 WHERE %2" )
.arg( P->quotedIdentifier( FROM8( OGR_FD_GetName( OGR_L_GetLayerDefn( ogrLayer ) ) ) ) )
.arg( P->subsetString() );
QgsDebugMsg( QString( "SQL: %1" ).arg( sql ) );
ogrLayer = OGR_DS_ExecuteSQL( ogrDataSource, P->textEncoding()->fromUnicode( sql ).constData(), NULL, NULL );
mSubsetStringSet = true;
}

ensureRelevantFields();

Expand All @@ -56,12 +70,12 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrProvider* p, const QgsFeatur

OGR_G_CreateFromWkt(( char ** )&wktText, NULL, &filter );
QgsDebugMsg( "Setting spatial filter using " + wktExtent );
OGR_L_SetSpatialFilter( P->ogrLayer, filter );
OGR_L_SetSpatialFilter( ogrLayer, filter );
OGR_G_DestroyGeometry( filter );
}
else
{
OGR_L_SetSpatialFilter( P->ogrLayer, 0 );
OGR_L_SetSpatialFilter( ogrLayer, 0 );
}

//start with first feature
Expand Down Expand Up @@ -94,7 +108,7 @@ bool QgsOgrFeatureIterator::nextFeature( QgsFeature& feature )

if ( mRequest.filterType() == QgsFeatureRequest::FilterFid )
{
OGRFeatureH fet = OGR_L_GetFeature( P->ogrLayer, FID_TO_NUMBER( mRequest.filterFid() ) );
OGRFeatureH fet = OGR_L_GetFeature( ogrLayer, FID_TO_NUMBER( mRequest.filterFid() ) );
if ( !fet )
{
close();
Expand All @@ -111,7 +125,7 @@ bool QgsOgrFeatureIterator::nextFeature( QgsFeature& feature )

OGRFeatureH fet;

while (( fet = OGR_L_GetNextFeature( P->ogrLayer ) ) )
while (( fet = OGR_L_GetNextFeature( ogrLayer ) ) )
{
if ( !readFeature( fet, feature ) )
continue;
Expand All @@ -135,7 +149,7 @@ bool QgsOgrFeatureIterator::rewind()
if ( mClosed )
return false;

OGR_L_ResetReading( P->ogrLayer );
OGR_L_ResetReading( ogrLayer );

return true;
}
Expand All @@ -146,10 +160,17 @@ bool QgsOgrFeatureIterator::close()
if ( mClosed )
return false;

// tell provider that this iterator is not active anymore
P->mActiveIterator = 0;
P->mActiveIterators.remove( this );

if (mSubsetStringSet)
{
OGR_DS_ReleaseResultSet(ogrDataSource, ogrLayer );
}

OGR_DS_Destroy( ogrDataSource );

mClosed = true;
ogrDataSource = 0;
return true;
}

Expand Down
5 changes: 5 additions & 0 deletions src/providers/ogr/qgsogrfeatureiterator.h
Expand Up @@ -48,6 +48,11 @@ class QgsOgrFeatureIterator : public QgsAbstractFeatureIterator
void getFeatureAttribute( OGRFeatureH ogrFet, QgsFeature & f, int attindex );

bool mFeatureFetched;

OGRDataSourceH ogrDataSource;
OGRLayerH ogrLayer;

bool mSubsetStringSet;
};


Expand Down
9 changes: 6 additions & 3 deletions src/providers/ogr/qgsogrprovider.cpp
Expand Up @@ -209,7 +209,6 @@ QgsOgrProvider::QgsOgrProvider( QString const & uri )
, ogrDriver( 0 )
, valid( false )
, featuresCounted( -1 )
, mActiveIterator( 0 )
{
QgsCPLErrorHandler handler;

Expand Down Expand Up @@ -360,8 +359,12 @@ QgsOgrProvider::QgsOgrProvider( QString const & uri )

QgsOgrProvider::~QgsOgrProvider()
{
if ( mActiveIterator )
mActiveIterator->close();
// Do we need to close all active iterators here?

foreach ( QgsOgrFeatureIterator* it, mActiveIterators )
{
it->close();
}

if ( ogrLayer != ogrOrigLayer )
{
Expand Down
16 changes: 13 additions & 3 deletions src/providers/ogr/qgsogrprovider.h
Expand Up @@ -15,6 +15,8 @@ email : sherman at mrcc.com
* *
***************************************************************************/

#include "QTextCodec"

#include "qgsrectangle.h"
#include "qgsvectordataprovider.h"
#include "qgsvectorfilewriter.h"
Expand Down Expand Up @@ -250,6 +252,16 @@ class QgsOgrProvider : public QgsVectorDataProvider
/** Get single flatten geometry type */
static OGRwkbGeometryType ogrWkbSingleFlatten( OGRwkbGeometryType type );

QString layerName() { return mLayerName; }

QString filePath() { return mFilePath; }

int layerIndex() { return mLayerIndex; }

QTextCodec* textEncoding() { return mEncoding; }

QString quotedIdentifier( QString field );

protected:
/** loads fields from input file to member attributeFields */
void loadFields();
Expand Down Expand Up @@ -323,11 +335,9 @@ class QgsOgrProvider : public QgsVectorDataProvider
/**Deletes one feature*/
bool deleteFeature( QgsFeatureId id );

QString quotedIdentifier( QString field );

/**Calls OGR_L_SyncToDisk and recreates the spatial index if present*/
bool syncToDisc();

friend class QgsOgrFeatureIterator;
QgsOgrFeatureIterator* mActiveIterator; //!< pointer to currently active iterator (0 if none)
QSet< QgsOgrFeatureIterator*> mActiveIterators;
};

0 comments on commit 4164d6e

Please sign in to comment.