Skip to content
Permalink
Browse files

Merge pull request #6754 from m-kuhn/processing_filter_algorithm

 [FEATURE] Feature filter algorithm for processing models
  • Loading branch information
m-kuhn committed Apr 11, 2018
2 parents 9dc3ee4 + fbb4ef5 commit 29b080fce3c2a99dd5cbc2ba96d2a747018d5a8c
Showing with 1,343 additions and 40 deletions.
  1. +1 −3 python/core/processing/qgsprocessingalgorithm.sip.in
  2. +1 −0 python/core/processing/qgsprocessingparameters.sip.in
  3. +0 −1 python/core/processing/qgsprocessingregistry.sip.in
  4. +2 −0 python/gui/gui_auto.sip
  5. +79 −0 python/gui/processing/qgsprocessingalgorithmconfigurationwidget.sip.in
  6. 0 python/gui/processing/qgsprocessingconfigurationwidgets.sip.in
  7. +68 −0 python/gui/processing/qgsprocessingguiregistry.sip.in
  8. +7 −0 python/gui/qgsgui.sip.in
  9. +1 −1 python/plugins/processing/modeler/ModelerGraphicItem.py
  10. +23 −2 python/plugins/processing/modeler/ModelerParametersDialog.py
  11. +7 −1 python/plugins/processing/tests/QgisAlgorithmsTest.py
  12. +80 −0 python/plugins/processing/tests/models/filtertest.model3
  13. +26 −0 python/plugins/processing/tests/testdata/expected/filter_points_big.gfs
  14. +42 −0 python/plugins/processing/tests/testdata/expected/filter_points_big.gml
  15. +26 −0 python/plugins/processing/tests/testdata/expected/filter_points_small.gfs
  16. +49 −0 python/plugins/processing/tests/testdata/expected/filter_points_small.gml
  17. +16 −0 python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
  18. +1 −0 src/analysis/CMakeLists.txt
  19. +0 −2 src/analysis/processing/qgsalgorithmbuffer.h
  20. +144 −0 src/analysis/processing/qgsalgorithmfilter.cpp
  21. +77 −0 src/analysis/processing/qgsalgorithmfilter.h
  22. +2 −0 src/analysis/processing/qgsnativealgorithms.cpp
  23. +1 −0 src/app/CMakeLists.txt
  24. +3 −5 src/app/main.cpp
  25. +4 −4 src/core/processing/models/qgsprocessingmodelalgorithm.cpp
  26. +1 −0 src/core/processing/models/qgsprocessingmodelchildalgorithm.cpp
  27. +12 −14 src/core/processing/qgsprocessingalgorithm.cpp
  28. +3 −3 src/core/processing/qgsprocessingalgorithm.h
  29. +1 −0 src/core/processing/qgsprocessingparameters.h
  30. +0 −1 src/core/processing/qgsprocessingregistry.cpp
  31. +1 −1 src/core/processing/qgsprocessingregistry.h
  32. +10 −1 src/gui/CMakeLists.txt
  33. +23 −0 src/gui/processing/qgsprocessingalgorithmconfigurationwidget.cpp
  34. +85 −0 src/gui/processing/qgsprocessingalgorithmconfigurationwidget.h
  35. +167 −0 src/gui/processing/qgsprocessingconfigurationwidgets.cpp
  36. +59 −0 src/gui/processing/qgsprocessingconfigurationwidgets.h
  37. +56 −0 src/gui/processing/qgsprocessingguiregistry.cpp
  38. +78 −0 src/gui/processing/qgsprocessingguiregistry.h
  39. +8 −0 src/gui/qgsgui.cpp
  40. +8 −0 src/gui/qgsgui.h
  41. +51 −0 tests/src/analysis/testqgsprocessingalgs.cpp
  42. +6 −1 tests/src/gui/CMakeLists.txt
  43. +114 −0 tests/src/gui/testprocessinggui.cpp
@@ -10,12 +10,10 @@




%ModuleHeaderCode
#include <qgsprocessingmodelalgorithm.h>
%End


class QgsProcessingAlgorithm
{
%Docstring
@@ -276,7 +274,7 @@ Returns true if this algorithm generates HTML outputs.
%End

QVariantMap run( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback, bool *ok /Out/ = 0 ) const;
QgsProcessingContext &context, QgsProcessingFeedback *feedback, bool *ok /Out/ = 0, const QVariantMap &configuration = QVariantMap() ) const;
%Docstring
Executes the algorithm using the specified ``parameters``. This method internally
creates a copy of the algorithm before running it, so it is safe to call
@@ -168,6 +168,7 @@ their acceptable ranges, defaults, etc.
FlagAdvanced,
FlagHidden,
FlagOptional,
FlagIsModelOutput,
};
typedef QFlags<QgsProcessingParameterDefinition::Flag> Flags;

@@ -143,7 +143,6 @@ Return a list with all known parameter types.
.. versionadded:: 3.2
%End


signals:

void providerAdded( const QString &id );
@@ -45,6 +45,7 @@
%Include layertree/qgslayertreeembeddedconfigwidget.sip
%Include layertree/qgslayertreeembeddedwidgetregistry.sip
%Include layout/qgslayoutviewmouseevent.sip
%Include processing/qgsprocessingguiregistry.sip
%Include raster/qgsrasterrendererwidget.sip
%Include symbology/qgssymbolwidgetcontext.sip
%Include qgisinterface.sip
@@ -311,5 +312,6 @@
%Include layout/qgslayoutviewtooltemporarymousepan.sip
%Include layout/qgslayoutviewtoolzoom.sip
%Include locator/qgslocatorwidget.sip
%Include processing/qgsprocessingalgorithmconfigurationwidget.sip
%Include processing/qgsprocessingalgorithmdialogbase.sip
%Include qgsadvanceddigitizingcanvasitem.sip
@@ -0,0 +1,79 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/processing/qgsprocessingalgorithmconfigurationwidget.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/







class QgsProcessingAlgorithmConfigurationWidget : QWidget
{
%Docstring
A configuration widget for processing algorithms allows providing additional
configuration options directly on algorithm level, in addition to parameters.

.. versionadded:: 3.2
%End

%TypeHeaderCode
#include "qgsprocessingalgorithmconfigurationwidget.h"
%End
public:

QgsProcessingAlgorithmConfigurationWidget( QWidget *parent = 0 );
%Docstring
Creates a new QgsProcessingAlgorithmConfigurationWidget
%End
virtual ~QgsProcessingAlgorithmConfigurationWidget();

virtual QVariantMap configuration() const = 0;
%Docstring
Read the current configuration from this widget.
%End

virtual void setConfiguration( const QVariantMap &configuration ) = 0;
%Docstring
Set the configuration which this widget should represent.
%End
};


class QgsProcessingAlgorithmConfigurationWidgetFactory
{
%Docstring
Interface base class for factories for algorithm configuration widgets.

.. versionadded:: 3.2
%End

%TypeHeaderCode
#include "qgsprocessingalgorithmconfigurationwidget.h"
%End
public:
virtual ~QgsProcessingAlgorithmConfigurationWidgetFactory();

virtual QgsProcessingAlgorithmConfigurationWidget *create( const QgsProcessingAlgorithm *algorithm ) const = 0 /Factory/;
%Docstring
Create a new configuration widget for ``algorithm``.
%End

virtual bool canCreateFor( const QgsProcessingAlgorithm *algorithm ) const = 0;
%Docstring
Check if this factory can create widgets for ``algorithm``.
%End
};


/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/processing/qgsprocessingalgorithmconfigurationwidget.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
No changes.
@@ -0,0 +1,68 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/processing/qgsprocessingguiregistry.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/






class QgsProcessingGuiRegistry
{
%Docstring
The QgsProcessingGuiRegistry is a home for widgets for processing
configuration widgets.

.. versionadded:: 3.2
%End

%TypeHeaderCode
#include "qgsprocessingguiregistry.h"
%End
public:

QgsProcessingGuiRegistry();
%Docstring
Constructor. Should never be called manually, is already
created by :py:class:`QgsGui`.
%End
~QgsProcessingGuiRegistry();

void addAlgorithmConfigurationWidgetFactory( QgsProcessingAlgorithmConfigurationWidgetFactory *factory /Transfer/ );
%Docstring
Add a new configuration widget factory for customized algorithm configuration
widgets. Ownership is taken.

.. versionadded:: 3.2
%End

void removeAlgorithmConfigurationWidgetFactory( QgsProcessingAlgorithmConfigurationWidgetFactory *factory );
%Docstring
Remove a configuration widget factory for customized algorithm configuration
widgets.

.. versionadded:: 3.2
%End

QgsProcessingAlgorithmConfigurationWidget *algorithmConfigurationWidget( const QgsProcessingAlgorithm *algorithm ) const;
%Docstring
Get the configuration widget for an ``algorithm``. This widget will be shown
next to parameter widgets. Most algorithms do not have a configuration widget
and in this case, None will be returned.

.. versionadded:: 3.2
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/processing/qgsprocessingguiregistry.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
@@ -60,6 +60,13 @@ Returns the global map layer action registry, used for registering map layer act
static QgsLayoutItemGuiRegistry *layoutItemGuiRegistry();
%Docstring
Returns the global layout item GUI registry, used for registering the GUI behavior of layout items.
%End

static QgsProcessingGuiRegistry *processingGuiRegistry();
%Docstring
Returns the global processing gui registry, used for registering the GUI behavior of processing algorithms.

.. versionadded:: 3.2
%End

static void enableAutoGeometryRestore( QWidget *widget, const QString &key = QString() );
@@ -208,7 +208,7 @@ def editElement(self):
self.scene.dialog.repaintModel()
elif isinstance(self.element, QgsProcessingModelChildAlgorithm):
elemAlg = self.element.algorithm()
dlg = ModelerParametersDialog(elemAlg, self.model, self.element.childId())
dlg = ModelerParametersDialog(elemAlg, self.model, self.element.childId(), self.element.configuration())
if dlg.exec_():
alg = dlg.createAlgorithm()
alg.setChildId(self.element.childId())
@@ -36,6 +36,7 @@
QHBoxLayout, QWidget)

from qgis.core import (Qgis,
QgsApplication,
QgsProcessingParameterDefinition,
QgsProcessingParameterPoint,
QgsProcessingParameterExtent,
@@ -52,7 +53,8 @@
QgsProcessingOutputDefinition,
QgsSettings)

from qgis.gui import (QgsMessageBar,
from qgis.gui import (QgsGui,
QgsMessageBar,
QgsScrollArea,
QgsFilterLineEdit,
QgsHelp)
@@ -63,13 +65,15 @@


class ModelerParametersDialog(QDialog):
def __init__(self, alg, model, algName=None):

def __init__(self, alg, model, algName=None, configuration=None):
QDialog.__init__(self)
self.setModal(True)

self._alg = alg # The algorithm to define in this dialog. It is an instance of QgsProcessingAlgorithm
self.model = model # The model this algorithm is going to be added to. It is an instance of QgsProcessingModelAlgorithm
self.childId = algName # The name of the algorithm in the model, in case we are editing it and not defining it for the first time
self.configuration = configuration

self.setupUi()
self.params = None
@@ -87,6 +91,8 @@ def setupUi(self):
self.wrappers = {}
self.valueItems = {}
self.dependentItems = {}
self.algorithmItem = None

self.resize(650, 450)
self.buttonBox = QDialogButtonBox()
self.buttonBox.setOrientation(Qt.Horizontal)
@@ -114,6 +120,10 @@ def setupUi(self):
line.setFrameShape(QFrame.HLine)
line.setFrameShadow(QFrame.Sunken)
self.verticalLayout.addWidget(line)
self.algorithmItem = QgsGui.instance().processingGuiRegistry().algorithmConfigurationWidget(self._alg)
if self.configuration:
self.algorithmItem.setConfiguration(self.configuration)
self.verticalLayout.addWidget(self.algorithmItem)

for param in self._alg.parameterDefinitions():
if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
@@ -284,6 +294,9 @@ def createAlgorithm(self):
else:
alg.setChildId(self.childId)
alg.setDescription(self.descriptionBox.text())
if self.algorithmItem:
alg.setConfiguration(self.algorithmItem.configuration())
self._alg = alg.algorithm().create(self.algorithmItem.configuration())
for param in self._alg.parameterDefinitions():
if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden:
continue
@@ -320,6 +333,14 @@ def createAlgorithm(self):
output.setChildId(alg.childId())
output.setChildOutputName(dest.name())
outputs[name] = output

if dest.flags() & QgsProcessingParameterDefinition.FlagIsModelOutput:
if dest.name() not in outputs:
output = QgsProcessingModelOutput(dest.name(), dest.name())
output.setChildId(alg.childId())
output.setChildOutputName(dest.name())
outputs[dest.name()] = output

alg.setModelOutputs(outputs)

selectedOptions = self.dependenciesPanel.selectedoptions
@@ -29,6 +29,7 @@

import nose2
import shutil
import os

from qgis.core import (QgsApplication,
QgsProcessingAlgorithm,
@@ -37,6 +38,8 @@
from qgis.analysis import (QgsNativeAlgorithms)
from qgis.testing import start_app, unittest
from processing.tools.dataobjects import createContext
from processing.core.ProcessingConfig import ProcessingConfig
from processing.modeler.ModelerUtils import ModelerUtils


class TestAlg(QgsProcessingAlgorithm):
@@ -66,19 +69,22 @@ class TestQgisAlgorithms(unittest.TestCase, AlgorithmsTestBase.AlgorithmsTest):
@classmethod
def setUpClass(cls):
start_app()
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
from processing.core.Processing import Processing
Processing.initialize()
ProcessingConfig.setSettingValue(ModelerUtils.MODELS_FOLDER, os.path.join(os.path.dirname(__file__), 'models'))
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
cls.cleanup_paths = []
cls.in_place_layers = {}
cls.vector_layer_params = {}
cls._original_models_folder = ProcessingConfig.getSetting(ModelerUtils.MODELS_FOLDER)

@classmethod
def tearDownClass(cls):
from processing.core.Processing import Processing
Processing.deinitialize()
for path in cls.cleanup_paths:
shutil.rmtree(path)
ProcessingConfig.setSettingValue(ModelerUtils.MODELS_FOLDER, cls._original_models_folder)

def test_definition_file(self):
return 'qgis_algorithm_tests.yaml'

0 comments on commit 29b080f

Please sign in to comment.
You can’t perform that action at this time.