Skip to content

Commit

Permalink
Add temporary layer store to processing context
Browse files Browse the repository at this point in the history
This temporary layer store (a QgsProject) is used as a
store for layers that are added if a parameter that
is evaluated to a layer requires that a new, non-active-project
layer is loaded. It means that these layers will remain accessible
for the duration of the algorithm's execution (or models
execution if an algorithm is run as part of a model), before
being automatically discarded when the QgsProcessingContext
used to run the algorithm/model goes out of scope.

This approach has several benefits:
- it means that algorithms (including c++ algorithms) are able
to use both project and non-project layers without needing
to handle any memory management themselves.
- it means that layers are guaranteed to last for the duration
of a model execution. This is currently an issue where models
which use memory layers as intermediate outputs do not
function correctly as the memory layers are destroyed before
the model has finished executing
- there should be no leakage of layers remaining open
after an algorithm exits
  • Loading branch information
nyalldawson committed Apr 26, 2017
1 parent 5169e0d commit 6b4ddb3
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 0 deletions.
6 changes: 6 additions & 0 deletions python/core/processing/qgsprocessingcontext.sip
Expand Up @@ -37,6 +37,7 @@ class QgsProcessingContext
Constructor for QgsProcessingContext.
%End

// QgsProcessingContext &operator=( const QgsProcessingContext &other ) = delete;
QgsProcessingContext::Flags flags() const;
%Docstring
Returns any flags set in the context.
Expand Down Expand Up @@ -74,6 +75,9 @@ class QgsProcessingContext
Sets the expression ``context``.
%End




QgsFeatureRequest::InvalidGeometryCheck invalidGeometryCheck() const;
%Docstring
Returns the behavior used for checking invalid geometries in input layers.
Expand Down Expand Up @@ -110,6 +114,8 @@ class QgsProcessingContext
%End


private:
QgsProcessingContext( const QgsProcessingContext &other );
};
QFlags<QgsProcessingContext::Flag> operator|(QgsProcessingContext::Flag f1, QFlags<QgsProcessingContext::Flag> f2);

Expand Down
19 changes: 19 additions & 0 deletions src/core/processing/qgsprocessingcontext.h
Expand Up @@ -50,6 +50,9 @@ class CORE_EXPORT QgsProcessingContext
*/
QgsProcessingContext() = default;

QgsProcessingContext( const QgsProcessingContext &other ) = delete;
QgsProcessingContext &operator=( const QgsProcessingContext &other ) = delete;

/**
* Returns any flags set in the context.
* \see setFlags()
Expand Down Expand Up @@ -84,6 +87,17 @@ class CORE_EXPORT QgsProcessingContext
*/
void setExpressionContext( const QgsExpressionContext &context ) { mExpressionContext = context; }

///@cond NOT_STABLE_API

/**
* Returns a reference to the project used for storing temporary layers during
* algorithm execution.
* \note not available in Python bindings
*/
SIP_SKIP QgsProject &temporaryLayerStore() { return tempProject; }

///@endcond

/**
* Returns the behavior used for checking invalid geometries in input layers.
* \see setInvalidGeometryCheck()
Expand Down Expand Up @@ -135,10 +149,15 @@ class CORE_EXPORT QgsProcessingContext

QgsProcessingContext::Flags mFlags = 0;
QPointer< QgsProject > mProject;
//! Temporary project owned by the context, used for storing temporarily loaded map layers
QgsProject tempProject;
QgsExpressionContext mExpressionContext;
QgsFeatureRequest::InvalidGeometryCheck mInvalidGeometryCheck = QgsFeatureRequest::GeometryNoCheck;
std::function< void( const QgsFeature & ) > mInvalidGeometryCallback;

#ifdef SIP_RUN
QgsProcessingContext( const QgsProcessingContext &other );
#endif
};
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsProcessingContext::Flags )

Expand Down

0 comments on commit 6b4ddb3

Please sign in to comment.