From 3b6ed3bfc81ae079fd30b3a382f11c2435bdddd5 Mon Sep 17 00:00:00 2001 From: Alvaro Huarte Date: Fri, 27 Dec 2013 09:21:22 +0100 Subject: [PATCH] #8725-R: PostgresProvider simplifies on provider side PostgresFeatureIterator implements simplification on provider side --- .../postgres/qgspostgresfeatureiterator.cpp | 49 +++++++++++++++++++ .../postgres/qgspostgresfeatureiterator.h | 3 ++ .../postgres/qgspostgresprovider.cpp | 3 ++ 3 files changed, 55 insertions(+) diff --git a/src/providers/postgres/qgspostgresfeatureiterator.cpp b/src/providers/postgres/qgspostgresfeatureiterator.cpp index 6c088ab4452a..47054cb43d5a 100644 --- a/src/providers/postgres/qgspostgresfeatureiterator.cpp +++ b/src/providers/postgres/qgspostgresfeatureiterator.cpp @@ -80,6 +80,9 @@ QgsPostgresFeatureIterator::QgsPostgresFeatureIterator( QgsPostgresProvider* p, return; } + //setup if required the simplification of geometries to fetch + prepareProviderSimplification(); + mFetched = 0; } @@ -170,6 +173,26 @@ bool QgsPostgresFeatureIterator::fetchFeature( QgsFeature& feature ) return true; } +bool QgsPostgresFeatureIterator::prepareProviderSimplification() +{ + const QgsSimplifyMethod& simplifyMethod = mRequest.simplifyMethod(); + + // validate settings of simplification of geometries to fetch + if ( simplifyMethod.methodType() != QgsSimplifyMethod::NoSimplification && !simplifyMethod.forceLocalOptimization() && !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) ) + { + QgsSimplifyMethod::MethodType methodType = simplifyMethod.methodType(); + + if ( methodType == QgsSimplifyMethod::OptimizeForRendering || methodType == QgsSimplifyMethod::PreserveTopology ) + { + return true; + } + else + { + QgsDebugMsg( QString( "Simplification method type (%1) is not recognised by PostgresFeatureIterator" ).arg( methodType ) ); + } + } + return false; +} bool QgsPostgresFeatureIterator::rewind() { @@ -272,8 +295,34 @@ bool QgsPostgresFeatureIterator::declareCursor( const QString& whereClause ) try { + const QgsSimplifyMethod& simplifyMethod = mRequest.simplifyMethod(); + QString query = "SELECT ", delim = ""; + if ( mFetchGeometry && !simplifyMethod.forceLocalOptimization() && simplifyMethod.methodType() != QgsSimplifyMethod::NoSimplification ) + { + QString simplifyFunctionName = simplifyMethod.methodType() == QgsSimplifyMethod::OptimizeForRendering + ? + ( P->mConnectionRO->majorVersion() < 2 ? "simplify" : "st_simplify" ) + : + ( P->mConnectionRO->majorVersion() < 2 ? "simplifypreservetopology" : "st_simplifypreservetopology" ); + + double tolerance = simplifyMethod.methodType() == QgsSimplifyMethod::OptimizeForRendering + ? + simplifyMethod.tolerance() / 5.0f /* experimental */ + : + simplifyMethod.tolerance(); + + query += QString( "%1(%5(%2%3,%6),'%4')" ) + .arg( P->mConnectionRO->majorVersion() < 2 ? "asbinary" : "st_asbinary" ) + .arg( P->quotedIdentifier( P->mGeometryColumn ) ) + .arg( P->mSpatialColType == sctGeography ? "::geometry" : "" ) + .arg( P->endianString() ) + .arg( simplifyFunctionName ) + .arg( tolerance ); + delim = ","; + } + else if ( mFetchGeometry ) { query += QString( "%1(%2%3,'%4')" ) diff --git a/src/providers/postgres/qgspostgresfeatureiterator.h b/src/providers/postgres/qgspostgresfeatureiterator.h index a69d63a9c368..b4ba18716d51 100644 --- a/src/providers/postgres/qgspostgresfeatureiterator.h +++ b/src/providers/postgres/qgspostgresfeatureiterator.h @@ -40,6 +40,9 @@ class QgsPostgresFeatureIterator : public QgsAbstractFeatureIterator //! fetch next feature, return true on success virtual bool fetchFeature( QgsFeature& feature ); + //! setup if required the simplification of geometries to fetch, it uses the settings of current FeatureRequest + virtual bool prepareProviderSimplification(); + QgsPostgresProvider* P; QString whereClauseRect(); diff --git a/src/providers/postgres/qgspostgresprovider.cpp b/src/providers/postgres/qgspostgresprovider.cpp index dd97bf14bb8a..a6d1574b3fad 100644 --- a/src/providers/postgres/qgspostgresprovider.cpp +++ b/src/providers/postgres/qgspostgresprovider.cpp @@ -993,6 +993,9 @@ bool QgsPostgresProvider::hasSufficientPermsAndCapabilities() } } + // supports geometry simplification on provider side + mEnabledCapabilities |= QgsVectorDataProvider::SimplifyGeometries; + return true; }