Skip to content

Commit

Permalink
#8275-R: simplification on a per-iterator basis
Browse files Browse the repository at this point in the history
  • Loading branch information
ahuarte47 authored and m-kuhn committed Jan 15, 2014
1 parent 61c8cad commit 7cb8ff7
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 45 deletions.
22 changes: 18 additions & 4 deletions src/core/qgsfeatureiterator.cpp
Expand Up @@ -23,6 +23,7 @@ QgsAbstractFeatureIterator::QgsAbstractFeatureIterator( const QgsFeatureRequest&
, mClosed( false )
, refs( 0 )
, mGeometrySimplifier( NULL )
, mLocalSimplification( false )
{
}

Expand Down Expand Up @@ -52,7 +53,7 @@ bool QgsAbstractFeatureIterator::nextFeature( QgsFeature& f )
}

// simplify the geometry using the simplifier configured
if ( dataOk )
if ( dataOk && mLocalSimplification )
{
QgsGeometry* geometry = f.geometry();
if ( geometry ) simplify( f );
Expand Down Expand Up @@ -82,6 +83,11 @@ bool QgsAbstractFeatureIterator::nextFeatureFilterFids( QgsFeature& f )

void QgsAbstractFeatureIterator::ref()
{
// prepare if required the simplification of geometries to fetch
if ( refs == 0 )
{
prepareSimplification( mRequest.simplifyMethod() );
}
refs++;
}

Expand All @@ -94,18 +100,26 @@ void QgsAbstractFeatureIterator::deref()

bool QgsAbstractFeatureIterator::prepareSimplification( const QgsSimplifyMethod& simplifyMethod )
{
mLocalSimplification = false;

delete mGeometrySimplifier;
mGeometrySimplifier = NULL;

// setup the local simplification of geometries to fetch
if ( simplifyMethod.methodType() != QgsSimplifyMethod::NoSimplification && simplifyMethod.forceLocalOptimization() && !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) )
// setup the simplification of geometries to fetch
if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) && simplifyMethod.methodType() != QgsSimplifyMethod::NoSimplification && ( simplifyMethod.forceLocalOptimization() || !providerCanSimplify( simplifyMethod.methodType() ) ) )
{
mGeometrySimplifier = QgsSimplifyMethod::createGeometrySimplifier( simplifyMethod );
return mGeometrySimplifier != NULL;
mLocalSimplification = mGeometrySimplifier != NULL;
return mLocalSimplification;
}
return false;
}

bool QgsAbstractFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
{
return false;
}

bool QgsAbstractFeatureIterator::simplify( QgsFeature& feature )
{
// simplify locally the geometry using the configured simplifier
Expand Down
5 changes: 5 additions & 0 deletions src/core/qgsfeatureiterator.h
Expand Up @@ -93,6 +93,11 @@ class CORE_EXPORT QgsAbstractFeatureIterator
private:
//! optional object to locally simplify geometries fetched by this feature iterator
QgsAbstractGeometrySimplifier* mGeometrySimplifier;
//! this iterator runs local simplification
bool mLocalSimplification;

//! returns whether the iterator can simplify on provider side the geometries to fetch using the specified method type
virtual bool providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const;

//! simplify the specified geometry if it was configured
virtual bool simplify( QgsFeature& feature );
Expand Down
7 changes: 0 additions & 7 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -737,13 +737,6 @@ bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
simplifyMethod.setTolerance( map2pixelTol );
simplifyMethod.setForceLocalOptimization( mSimplifyMethod.forceLocalOptimization() );

// fix simplification non supported on server side
if ( !simplifyMethod.forceLocalOptimization() && !( mDataProvider->capabilities() & QgsVectorDataProvider::SimplifyGeometries ) )
{
QgsDebugMsg( "Data provider does not support geometry simplification on provider side" );
simplifyMethod.setForceLocalOptimization( true );
}

featureRequest.setSimplifyMethod( simplifyMethod );
}

Expand Down
39 changes: 24 additions & 15 deletions src/core/qgsvectorlayerfeatureiterator.cpp
Expand Up @@ -70,15 +70,6 @@ QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayer* la
}
else // no filter or filter by rect
{
QgsSimplifyMethod simplifyMethod = request.simplifyMethod();

// if required, local simplification will be configured for all providers, then avoid simplify twice (this iterator and provider iterator)
if ( simplifyMethod.methodType() != QgsSimplifyMethod::NoSimplification && simplifyMethod.forceLocalOptimization() )
{
simplifyMethod.setMethodType( QgsSimplifyMethod::NoSimplification );
if ( L->editBuffer() ) mChangedFeaturesRequest.setSimplifyMethod( simplifyMethod ); else mProviderRequest.setSimplifyMethod( simplifyMethod );
}

if ( L->editBuffer() )
{
mChangedFeaturesIterator = L->dataProvider()->getFeatures( mChangedFeaturesRequest );
Expand All @@ -95,9 +86,6 @@ QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayer* la
{
mRequest.filterExpression()->prepare( L->pendingFields() );
}

// prepare if required the local simplification of geometries to fetch
prepareSimplification( request.simplifyMethod() );
}


Expand Down Expand Up @@ -466,13 +454,34 @@ bool QgsVectorLayerFeatureIterator::prepareSimplification( const QgsSimplifyMeth
delete mEditGeometrySimplifier;
mEditGeometrySimplifier = NULL;

// setup the simplification of edited geometries to fetch
if ( simplifyMethod.methodType() != QgsSimplifyMethod::NoSimplification && !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) )
// setup simplification for edited geometries to fetch
if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) && simplifyMethod.methodType() != QgsSimplifyMethod::NoSimplification )
{
mEditGeometrySimplifier = QgsSimplifyMethod::createGeometrySimplifier( simplifyMethod );
return mEditGeometrySimplifier != NULL;
}
return false;
}

bool QgsVectorLayerFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
{
QgsVectorDataProvider* provider = L->dataProvider();

return QgsAbstractFeatureIterator::prepareSimplification( simplifyMethod );
if ( provider && methodType != QgsSimplifyMethod::NoSimplification )
{
int capabilities = provider->capabilities();

if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
{
return ( capabilities & QgsVectorDataProvider::SimplifyGeometries );
}
else
if ( methodType == QgsSimplifyMethod::PreserveTopology )
{
return ( capabilities & QgsVectorDataProvider::SimplifyGeometriesWithTopologicalValidation );
}
}
return false;
}


Expand Down
3 changes: 3 additions & 0 deletions src/core/qgsvectorlayerfeatureiterator.h
Expand Up @@ -121,6 +121,9 @@ class CORE_EXPORT QgsVectorLayerFeatureIterator : public QgsAbstractFeatureItera
private:
//! optional object to locally simplify edited (changed or added) geometries fetched by this feature iterator
QgsAbstractGeometrySimplifier* mEditGeometrySimplifier;

//! returns whether the iterator can simplify on provider side the geometries to fetch using the specified method type
virtual bool providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const;
};

#endif // QGSVECTORLAYERFEATUREITERATOR_H
20 changes: 10 additions & 10 deletions src/providers/ogr/qgsogrfeatureiterator.cpp
Expand Up @@ -80,9 +80,6 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrProvider* p, const QgsFeatur
OGR_L_SetSpatialFilter( ogrLayer, 0 );
}

//setup if required the simplification of OGR-geometries fetched
prepareSimplification( request.simplifyMethod() );

//start with first feature
rewind();
}
Expand All @@ -105,34 +102,37 @@ void QgsOgrFeatureIterator::ensureRelevantFields()

bool QgsOgrFeatureIterator::prepareSimplification( const QgsSimplifyMethod& simplifyMethod )
{
bool providerSimplification = false;

delete mGeometrySimplifier;
mGeometrySimplifier = NULL;

// setup if required the simplification of OGR-geometries fetched
if ( simplifyMethod.methodType() != QgsSimplifyMethod::NoSimplification && !simplifyMethod.forceLocalOptimization() && !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) )
// setup simplification of OGR-geometries fetched
if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) && simplifyMethod.methodType() != QgsSimplifyMethod::NoSimplification && !simplifyMethod.forceLocalOptimization() )
{
QgsSimplifyMethod::MethodType methodType = simplifyMethod.methodType();

if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
{
int simplifyFlags = QgsMapToPixelSimplifier::SimplifyGeometry | QgsMapToPixelSimplifier::SimplifyEnvelope;
mGeometrySimplifier = new QgsOgrMapToPixelSimplifier( simplifyFlags, simplifyMethod.tolerance() );
providerSimplification = true;
return true;
}
else
if ( methodType == QgsSimplifyMethod::PreserveTopology )
{
mGeometrySimplifier = new QgsOgrTopologyPreservingSimplifier( simplifyMethod.tolerance() );
providerSimplification = true;
return true;
}
else
{
QgsDebugMsg( QString( "Simplification method type (%1) is not recognised by OgrFeatureIterator class" ).arg( methodType ) );
}
}
return QgsAbstractFeatureIterator::prepareSimplification( simplifyMethod ) || providerSimplification;
return QgsAbstractFeatureIterator::prepareSimplification( simplifyMethod );
}

bool QgsOgrFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
{
return methodType == QgsSimplifyMethod::OptimizeForRendering || methodType == QgsSimplifyMethod::PreserveTopology;
}

bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature )
Expand Down
3 changes: 3 additions & 0 deletions src/providers/ogr/qgsogrfeatureiterator.h
Expand Up @@ -64,6 +64,9 @@ class QgsOgrFeatureIterator : public QgsAbstractFeatureIterator
private:
//! optional object to simplify OGR-geometries fecthed by this feature iterator
QgsOgrAbstractGeometrySimplifier* mGeometrySimplifier;

//! returns whether the iterator can simplify on provider side the geometries to fetch using the specified method type
virtual bool providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const;
};

#endif // QGSOGRFEATUREITERATOR_H
18 changes: 9 additions & 9 deletions src/providers/postgres/qgspostgresfeatureiterator.cpp
Expand Up @@ -80,9 +80,6 @@ QgsPostgresFeatureIterator::QgsPostgresFeatureIterator( QgsPostgresProvider* p,
return;
}

//setup if required the simplification of geometries to fetch
prepareSimplification( request.simplifyMethod() );

mFetched = 0;
}

Expand Down Expand Up @@ -175,23 +172,26 @@ bool QgsPostgresFeatureIterator::fetchFeature( QgsFeature& feature )

bool QgsPostgresFeatureIterator::prepareSimplification( const QgsSimplifyMethod& simplifyMethod )
{
bool providerSimplification = false;

// validate settings of simplification of geometries to fetch
if ( simplifyMethod.methodType() != QgsSimplifyMethod::NoSimplification && !simplifyMethod.forceLocalOptimization() && !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) )
// setup simplification of geometries to fetch
if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) && simplifyMethod.methodType() != QgsSimplifyMethod::NoSimplification && !simplifyMethod.forceLocalOptimization() )
{
QgsSimplifyMethod::MethodType methodType = simplifyMethod.methodType();

if ( methodType == QgsSimplifyMethod::OptimizeForRendering || methodType == QgsSimplifyMethod::PreserveTopology )
{
providerSimplification = true;
return true;
}
else
{
QgsDebugMsg( QString( "Simplification method type (%1) is not recognised by PostgresFeatureIterator" ).arg( methodType ) );
}
}
return QgsAbstractFeatureIterator::prepareSimplification( simplifyMethod ) || providerSimplification;
return QgsAbstractFeatureIterator::prepareSimplification( simplifyMethod );
}

bool QgsPostgresFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
{
return methodType == QgsSimplifyMethod::OptimizeForRendering || methodType == QgsSimplifyMethod::PreserveTopology;
}

bool QgsPostgresFeatureIterator::rewind()
Expand Down
3 changes: 3 additions & 0 deletions src/providers/postgres/qgspostgresfeatureiterator.h
Expand Up @@ -69,6 +69,9 @@ class QgsPostgresFeatureIterator : public QgsAbstractFeatureIterator

static const int sFeatureQueueSize;

private:
//! returns whether the iterator can simplify on provider side the geometries to fetch using the specified method type
virtual bool providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const;
};

#endif // QGSPOSTGRESFEATUREITERATOR_H

0 comments on commit 7cb8ff7

Please sign in to comment.