From 595f104830877c494c8ff28e2f1b9fe500ef7123 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 24 Apr 2017 16:33:57 +1000 Subject: [PATCH] Allow specifying a callback for encountering invalid geometries while iterating --- src/core/qgsfeaturerequest.cpp | 6 ++++++ src/core/qgsfeaturerequest.h | 20 ++++++++++++++++++++ src/core/qgsvectorlayerfeatureiterator.cpp | 6 +++++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/core/qgsfeaturerequest.cpp b/src/core/qgsfeaturerequest.cpp index e8aec6e09ac6..c2efa9837dc3 100644 --- a/src/core/qgsfeaturerequest.cpp +++ b/src/core/qgsfeaturerequest.cpp @@ -111,6 +111,12 @@ QgsFeatureRequest &QgsFeatureRequest::setInvalidGeometryCheck( QgsFeatureRequest return *this; } +QgsFeatureRequest &QgsFeatureRequest::setInvalidGeometryCallback( std::function callback ) +{ + mInvalidGeometryCallback = callback; + return *this; +} + QgsFeatureRequest &QgsFeatureRequest::setFilterExpression( const QString &expression ) { mFilter = FilterExpression; diff --git a/src/core/qgsfeaturerequest.h b/src/core/qgsfeaturerequest.h index 6e730764301a..50dcd31165bc 100644 --- a/src/core/qgsfeaturerequest.h +++ b/src/core/qgsfeaturerequest.h @@ -294,6 +294,25 @@ class CORE_EXPORT QgsFeatureRequest */ InvalidGeometryCheck invalidGeometryCheck() const { return mInvalidGeometryFilter; } + /** + * Sets a callback function to use when encountering an invalid geometry and + * invalidGeometryCheck() is set to GeometryAbortOnInvalid. This function will be + * called using the feature with invalid geometry as a parameter. + * \since QGIS 3.0 + * \note not available in Python bindings + * \see invalidGeometryCallback() + */ + QgsFeatureRequest &setInvalidGeometryCallback( std::function< void( const QgsFeature & ) > callback ); + + /** + * Returns the callback function to use when encountering an invalid geometry and + * invalidGeometryCheck() is set to GeometryAbortOnInvalid. + * \since QGIS 3.0 + * \note not available in Python bindings + * \see setInvalidGeometryCallback() + */ + std::function< void( const QgsFeature & ) > invalidGeometryCallback() const { return mInvalidGeometryCallback; } + /** Set the filter expression. {\see QgsExpression} * \param expression expression string * \see filterExpression @@ -440,6 +459,7 @@ class CORE_EXPORT QgsFeatureRequest long mLimit = -1; OrderBy mOrderBy; InvalidGeometryCheck mInvalidGeometryFilter = GeometryNoCheck; + std::function< void( const QgsFeature & ) > mInvalidGeometryCallback; }; Q_DECLARE_OPERATORS_FOR_FLAGS( QgsFeatureRequest::Flags ) diff --git a/src/core/qgsvectorlayerfeatureiterator.cpp b/src/core/qgsvectorlayerfeatureiterator.cpp index c3ec663b4e09..4a181fa0b531 100644 --- a/src/core/qgsvectorlayerfeatureiterator.cpp +++ b/src/core/qgsvectorlayerfeatureiterator.cpp @@ -698,8 +698,12 @@ bool QgsVectorLayerFeatureIterator::checkGeometry( const QgsFeature &feature ) case QgsFeatureRequest::GeometryAbortOnInvalid: if ( !feature.geometry().isGeosValid() ) { - QgsMessageLog::logMessage( QObject::tr( "Geometry error: One or more input features have invalid geometry." ), QString(), QgsMessageLog::CRITICAL); + QgsMessageLog::logMessage( QObject::tr( "Geometry error: One or more input features have invalid geometry." ), QString(), QgsMessageLog::CRITICAL ); close(); + if ( mRequest.invalidGeometryCallback() ) + { + mRequest.invalidGeometryCallback()( feature ); + } return false; } break;