Move iterator exception handling to c++

This commit is contained in:
Nyall Dawson 2017-06-24 08:15:06 +10:00
parent a8b364e2e2
commit d667bf595f
4 changed files with 70 additions and 32 deletions

View File

@ -142,7 +142,6 @@ Destination project
.. seealso:: invalidGeometryCheck()
%End
void setInvalidGeometryCallback( SIP_PYCALLABLE / AllowNone / );
%Docstring
Sets a callback function to use when encountering an invalid geometry and
@ -198,16 +197,29 @@ Destination project
%Docstring
Sets the default ``encoding`` to use for newly created files.
.. seealso:: defaultEncoding()
%End
QgsProcessingFeedback *feedback();
%Docstring
Returns the associated feedback object.
.. seealso:: setFeedback()
:rtype: QgsProcessingFeedback
%End
void setFeedback( QgsProcessingFeedback *feedback );
%Docstring
Sets an associated ``feedback`` object. This allows context related functions
to report feedback and errors to users and processing logs. While ideally this feedback
object should outlive the context, only a weak pointer to ``feedback`` is stored
and no errors will occur if feedback is deleted before the context.
Ownership of ``feedback`` is not transferred.
.. seealso:: setFeedback()
%End
private:
QgsProcessingContext( const QgsProcessingContext &other );
};
QFlags<QgsProcessingContext::Flag> operator|(QgsProcessingContext::Flag f1, QFlags<QgsProcessingContext::Flag> f2);

View File

@ -189,7 +189,7 @@ class AlgorithmDialogBase(BASE, WIDGET):
def setInfo(self, msg, error=False, escape_html=True):
if error:
self.txtLog.append('<span style="color:red"><br>{}<br></span>'.format(msg, quote=False))
self.txtLog.append('<span style="color:red">{}</span><br />'.format(msg, quote=False))
elif escape_html:
self.txtLog.append(html.escape(msg))
else:

View File

@ -71,27 +71,13 @@ def createContext(feedback=None):
"""
context = QgsProcessingContext()
context.setProject(QgsProject.instance())
context.setFeedback(feedback)
invalid_features_method = ProcessingConfig.getSetting(ProcessingConfig.FILTER_INVALID_GEOMETRIES)
if invalid_features_method is None:
invalid_features_method = QgsFeatureRequest.GeometryAbortOnInvalid
context.setInvalidGeometryCheck(invalid_features_method)
def raise_invalid_geometry_error(f, feedback=feedback):
if feedback:
feedback.pushInfo(QCoreApplication.translate("FeatureIterator",
'Feature with id {} has invalid geometry, skipping feature.'.format(f.id())))
if context.invalidGeometryCheck() == QgsFeatureRequest.GeometrySkipInvalid:
context.setInvalidGeometryCallback(raise_invalid_geometry_error)
def raise_transform_error(f, feedback=feedback):
if feedback:
feedback.pushInfo(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

@ -25,6 +25,7 @@
#include "qgsfeaturerequest.h"
#include "qgsmaplayerlistutils.h"
#include "qgsexception.h"
#include "qgsprocessingfeedback.h"
/**
* \class QgsProcessingContext
@ -50,7 +51,15 @@ class CORE_EXPORT QgsProcessingContext
/**
* Constructor for QgsProcessingContext.
*/
QgsProcessingContext() = default;
QgsProcessingContext()
{
auto callback = [ = ]( const QgsFeature & feature )
{
if ( mFeedback )
mFeedback->reportError( QObject::tr( "Encountered a transform error when reprojecting feature with id %1." ).arg( feature.id() ) );
};
mTransformErrorCallback = callback;
}
//! QgsProcessingContext cannot be copied
QgsProcessingContext( const QgsProcessingContext &other ) = delete;
@ -176,17 +185,34 @@ class CORE_EXPORT QgsProcessingContext
{
mInvalidGeometryCheck = check;
if ( mInvalidGeometryCheck == QgsFeatureRequest::GeometryAbortOnInvalid )
switch ( mInvalidGeometryCheck )
{
auto callback = []( const QgsFeature & feature )
case QgsFeatureRequest::GeometryAbortOnInvalid:
{
throw QgsProcessingException( QObject::tr( "Feature (%1) has invalid geometry. Please fix the geometry or change the Processing setting to the \"Ignore invalid input features\" option." ).arg( feature.id() ) );
};
mInvalidGeometryCallback = callback;
auto callback = []( const QgsFeature & feature )
{
throw QgsProcessingException( QObject::tr( "Feature (%1) has invalid geometry. Please fix the geometry or change the Processing setting to the \"Ignore invalid input features\" option." ).arg( feature.id() ) );
};
mInvalidGeometryCallback = callback;
break;
}
case QgsFeatureRequest::GeometrySkipInvalid:
{
auto callback = [ = ]( const QgsFeature & feature )
{
if ( mFeedback )
mFeedback->reportError( QObject::tr( "Feature (%1) has invalid geometry and has been skipped. Please fix the geometry or change the Processing setting to the \"Ignore invalid input features\" option." ).arg( feature.id() ) );
};
mInvalidGeometryCallback = callback;
break;
}
default:
break;
}
}
/**
* Sets a callback function to use when encountering an invalid geometry and
* invalidGeometryCheck() is set to GeometryAbortOnInvalid. This function will be
@ -268,6 +294,22 @@ class CORE_EXPORT QgsProcessingContext
*/
void setDefaultEncoding( const QString &encoding ) { mDefaultEncoding = encoding; }
/**
* Returns the associated feedback object.
* \see setFeedback()
*/
QgsProcessingFeedback *feedback() { return mFeedback; }
/**
* Sets an associated \a feedback object. This allows context related functions
* to report feedback and errors to users and processing logs. While ideally this feedback
* object should outlive the context, only a weak pointer to \a feedback is stored
* and no errors will occur if feedback is deleted before the context.
* Ownership of \a feedback is not transferred.
* \see setFeedback()
*/
void setFeedback( QgsProcessingFeedback *feedback ) { mFeedback = feedback; }
private:
QgsProcessingContext::Flags mFlags = 0;
@ -282,15 +324,13 @@ class CORE_EXPORT QgsProcessingContext
QString mDefaultEncoding;
QMap< QString, LayerDetails > mLayersToLoadOnCompletion;
QPointer< QgsProcessingFeedback > mFeedback;
#ifdef SIP_RUN
QgsProcessingContext( const QgsProcessingContext &other );
#endif
};
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsProcessingContext::Flags )
#endif // QGSPROCESSINGPARAMETERS_H