[processing] Catch transform errors in when iterating features

This commit is contained in:
Nyall Dawson 2017-06-12 08:05:32 +10:00
parent bc9b1b64f9
commit 29f50b72ee
5 changed files with 66 additions and 0 deletions

View File

@ -163,6 +163,28 @@ Destination project
%End
void setTransformErrorCallback( SIP_PYCALLABLE / AllowNone / );
%Docstring
Sets a callback function to use when encountering a transform error when iterating
features. This function will be
called using the feature which encountered the transform error as a parameter.
.. versionadded:: 3.0
.. seealso:: transformErrorCallback()
%End
%MethodCode
Py_BEGIN_ALLOW_THREADS
sipCpp->setTransformErrorCallback( [a0]( const QgsFeature &arg )
{
SIP_BLOCK_THREADS
Py_XDECREF( sipCallMethod( NULL, a0, "D", &arg, sipType_QgsFeature, NULL ) );
SIP_UNBLOCK_THREADS
} );
Py_END_ALLOW_THREADS
%End
QString defaultEncoding() const;
%Docstring
Returns the default encoding to use for newly created files.

View File

@ -85,6 +85,11 @@ def createContext():
context.setInvalidGeometryCallback(raise_error)
def raise_transform_error(f):
raise GeoAlgorithmExecutionException(QCoreApplication.translate("FeatureIterator",
'Encountered a transform error when reprojecting feature with id {}.'.format(f.id())))
context.setTransformErrorCallback(raise_transform_error)
settings = QgsSettings()
context.setDefaultEncoding(settings.value("/Processing/encoding", "System"))

View File

@ -206,6 +206,41 @@ class CORE_EXPORT QgsProcessingContext
*/
SIP_SKIP std::function< void( const QgsFeature & ) > invalidGeometryCallback() const { return mInvalidGeometryCallback; }
/**
* Sets a callback function to use when encountering a transform error when iterating
* features. This function will be
* called using the feature which encountered the transform error as a parameter.
* \since QGIS 3.0
* \see transformErrorCallback()
*/
#ifndef SIP_RUN
void setTransformErrorCallback( std::function< void( const QgsFeature & ) > callback ) { mTransformErrorCallback = callback; }
#else
void setTransformErrorCallback( SIP_PYCALLABLE / AllowNone / );
% MethodCode
Py_BEGIN_ALLOW_THREADS
sipCpp->setTransformErrorCallback( [a0]( const QgsFeature &arg )
{
SIP_BLOCK_THREADS
Py_XDECREF( sipCallMethod( NULL, a0, "D", &arg, sipType_QgsFeature, NULL ) );
SIP_UNBLOCK_THREADS
} );
Py_END_ALLOW_THREADS
% End
#endif
/**
* Returns the callback function to use when encountering a transform error when iterating
* features.
* \since QGIS 3.0
* \note not available in Python bindings
* \see setTransformErrorCallback()
* \see destinationCrs()
*/
std::function< void( const QgsFeature & ) > transformErrorCallback() const { return mTransformErrorCallback; } SIP_SKIP
/**
* Returns the default encoding to use for newly created files.
* \see setDefaultEncoding()
@ -228,6 +263,7 @@ class CORE_EXPORT QgsProcessingContext
QgsExpressionContext mExpressionContext;
QgsFeatureRequest::InvalidGeometryCheck mInvalidGeometryCheck = QgsFeatureRequest::GeometryNoCheck;
std::function< void( const QgsFeature & ) > mInvalidGeometryCallback;
std::function< void( const QgsFeature & ) > mTransformErrorCallback;
QString mDefaultEncoding;
QMap< QString, LayerDetails > mLayersToLoadOnCompletion;

View File

@ -375,6 +375,7 @@ QgsProcessingFeatureSource::QgsProcessingFeatureSource( QgsFeatureSource *origin
, mOwnsSource( ownsOriginalSource )
, mInvalidGeometryCheck( context.invalidGeometryCheck() )
, mInvalidGeometryCallback( context.invalidGeometryCallback() )
, mTransformErrorCallback( context.transformErrorCallback() )
{}
QgsProcessingFeatureSource::~QgsProcessingFeatureSource()
@ -388,6 +389,7 @@ QgsFeatureIterator QgsProcessingFeatureSource::getFeatures( const QgsFeatureRequ
QgsFeatureRequest req( request );
req.setInvalidGeometryCheck( mInvalidGeometryCheck );
req.setInvalidGeometryCallback( mInvalidGeometryCallback );
req.setTransformErrorCallback( mTransformErrorCallback );
return mSource->getFeatures( req );
}

View File

@ -228,6 +228,7 @@ class QgsProcessingFeatureSource : public QgsFeatureSource
bool mOwnsSource = false;
QgsFeatureRequest::InvalidGeometryCheck mInvalidGeometryCheck = QgsFeatureRequest::GeometryNoCheck;
std::function< void( const QgsFeature & ) > mInvalidGeometryCallback;
std::function< void( const QgsFeature & ) > mTransformErrorCallback;
};