mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
First steps to model/save restore in c++
Models now save to QVariantMap, using QgsXmlUtils to save to an xml based format (with extension .model3)
This commit is contained in:
parent
179a377da0
commit
9a2f14b931
@ -139,6 +139,20 @@ class QgsProcessingModelAlgorithm : QgsProcessingAlgorithm
|
||||
.. seealso:: setOutputChildId()
|
||||
%End
|
||||
|
||||
QVariant toVariant() const;
|
||||
%Docstring
|
||||
Saves this source to a QVariant.
|
||||
.. seealso:: loadVariant()
|
||||
:rtype: QVariant
|
||||
%End
|
||||
|
||||
bool loadVariant( const QVariantMap &map );
|
||||
%Docstring
|
||||
Loads this source from a QVariantMap.
|
||||
.. seealso:: toVariant()
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
class Component
|
||||
@ -192,6 +206,18 @@ Copies are protected to avoid slicing
|
||||
%End
|
||||
|
||||
|
||||
void saveCommonProperties( QVariantMap &map ) const;
|
||||
%Docstring
|
||||
Saves the component properties to a QVariantMap.
|
||||
.. seealso:: restoreCommonProperties()
|
||||
%End
|
||||
|
||||
void restoreCommonProperties( const QVariantMap &map );
|
||||
%Docstring
|
||||
Restores the component properties from a QVariantMap.
|
||||
.. seealso:: saveCommonProperties()
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
class ModelParameter : QgsProcessingModelAlgorithm::Component
|
||||
@ -227,6 +253,20 @@ Copies are protected to avoid slicing
|
||||
.. seealso:: parameterName()
|
||||
%End
|
||||
|
||||
QVariant toVariant() const;
|
||||
%Docstring
|
||||
Saves this parameter to a QVariant.
|
||||
.. seealso:: loadVariant()
|
||||
:rtype: QVariant
|
||||
%End
|
||||
|
||||
bool loadVariant( const QVariantMap &map );
|
||||
%Docstring
|
||||
Loads this parameter from a QVariantMap.
|
||||
.. seealso:: toVariant()
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -273,6 +313,20 @@ Copies are protected to avoid slicing
|
||||
.. seealso:: outputName()
|
||||
%End
|
||||
|
||||
QVariant toVariant() const;
|
||||
%Docstring
|
||||
Saves this output to a QVariant.
|
||||
.. seealso:: loadVariant()
|
||||
:rtype: QVariant
|
||||
%End
|
||||
|
||||
bool loadVariant( const QVariantMap &map );
|
||||
%Docstring
|
||||
Loads this output from a QVariantMap.
|
||||
.. seealso:: toVariant()
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
class ChildAlgorithm : QgsProcessingModelAlgorithm::Component
|
||||
@ -461,6 +515,20 @@ Copies are protected to avoid slicing
|
||||
.. seealso:: modelOutputs()
|
||||
%End
|
||||
|
||||
QVariant toVariant() const;
|
||||
%Docstring
|
||||
Saves this child to a QVariant.
|
||||
.. seealso:: loadVariant()
|
||||
:rtype: QVariant
|
||||
%End
|
||||
|
||||
bool loadVariant( const QVariant &child );
|
||||
%Docstring
|
||||
Loads this child from a QVariant.
|
||||
.. seealso:: toVariant()
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
QgsProcessingModelAlgorithm( const QString &name = QString(), const QString &group = QString() );
|
||||
@ -484,6 +552,18 @@ Copies are protected to avoid slicing
|
||||
virtual QVariantMap processAlgorithm( const QVariantMap ¶meters,
|
||||
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const;
|
||||
|
||||
void setName( const QString &name );
|
||||
%Docstring
|
||||
Sets the model ``name``.
|
||||
.. seealso:: name()
|
||||
%End
|
||||
|
||||
void setGroup( const QString &group );
|
||||
%Docstring
|
||||
Sets the model ``group``.
|
||||
.. seealso:: group()
|
||||
%End
|
||||
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ChildAlgorithm> childAlgorithms() const;
|
||||
%Docstring
|
||||
Returns the map of child algorithms contained in the model. The keys
|
||||
@ -651,6 +731,20 @@ Copies are protected to avoid slicing
|
||||
:rtype: QgsProcessingModelAlgorithm.ModelParameter
|
||||
%End
|
||||
|
||||
bool toFile( const QString &path ) const;
|
||||
%Docstring
|
||||
Writes the model to a file, at the specified ``path``.
|
||||
.. seealso:: fromFile()
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool fromFile( const QString &path );
|
||||
%Docstring
|
||||
Reads the model from a file, at the specified ``path``.
|
||||
.. seealso:: toFile()
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -56,22 +56,16 @@ class AddModelFromFileAction(ToolboxAction):
|
||||
self.tr('Open model', 'AddModelFromFileAction'), lastDir,
|
||||
self.tr('Processing model files (*.model *.MODEL)', 'AddModelFromFileAction'))
|
||||
if filename:
|
||||
try:
|
||||
settings.setValue('Processing/lastModelsDir',
|
||||
QFileInfo(filename).absoluteDir().absolutePath())
|
||||
settings.setValue('Processing/lastModelsDir',
|
||||
QFileInfo(filename).absoluteDir().absolutePath())
|
||||
|
||||
ModelerAlgorithm.fromFile(filename)
|
||||
except WrongModelException:
|
||||
alg = ModelerAlgorithm()
|
||||
if not alg.fromFile(filename):
|
||||
QMessageBox.warning(
|
||||
self.toolbox,
|
||||
self.tr('Error reading model', 'AddModelFromFileAction'),
|
||||
self.tr('The selected file does not contain a valid model', 'AddModelFromFileAction'))
|
||||
return
|
||||
except:
|
||||
QMessageBox.warning(self.toolbox,
|
||||
self.tr('Error reading model', 'AddModelFromFileAction'),
|
||||
self.tr('Cannot read file', 'AddModelFromFileAction'))
|
||||
return
|
||||
destFilename = os.path.join(ModelerUtils.modelsFolders()[0], os.path.basename(filename))
|
||||
shutil.copyfile(filename, destFilename)
|
||||
QgsApplication.processingRegistry().providerById('model').refreshAlgorithms()
|
||||
|
@ -365,15 +365,6 @@ class ModelerAlgorithm(QgsProcessingModelAlgorithm):
|
||||
model._name = model.modeler_name
|
||||
return model
|
||||
|
||||
@staticmethod
|
||||
def fromFile(filename):
|
||||
with open(filename) as f:
|
||||
s = f.read()
|
||||
alg = ModelerAlgorithm.fromJson(s)
|
||||
if alg:
|
||||
alg.descriptionFile = filename
|
||||
return alg
|
||||
|
||||
def toPython(self):
|
||||
s = ['##%s=name' % self.name()]
|
||||
for param in list(self.parameterComponents().values()):
|
||||
|
@ -27,10 +27,13 @@ __revision__ = '$Format:%H$'
|
||||
|
||||
import os
|
||||
|
||||
from qgis.PyQt.QtXml import QDomDocument
|
||||
|
||||
from qgis.core import (QgsApplication,
|
||||
QgsProcessingProvider,
|
||||
QgsMessageLog,
|
||||
QgsProcessingUtils)
|
||||
QgsProcessingUtils,
|
||||
QgsXmlUtils)
|
||||
|
||||
from processing.core.ProcessingConfig import ProcessingConfig, Setting
|
||||
from processing.modeler.ModelerUtils import ModelerUtils
|
||||
@ -98,13 +101,15 @@ class ModelerAlgorithmProvider(QgsProcessingProvider):
|
||||
return
|
||||
for path, subdirs, files in os.walk(folder):
|
||||
for descriptionFile in files:
|
||||
if descriptionFile.endswith('model'):
|
||||
if descriptionFile.endswith('model3'):
|
||||
try:
|
||||
fullpath = os.path.join(path, descriptionFile)
|
||||
alg = ModelerAlgorithm.fromFile(fullpath)
|
||||
if alg.name():
|
||||
alg.descriptionFile = fullpath
|
||||
self.algs.append(alg)
|
||||
|
||||
alg = ModelerAlgorithm()
|
||||
if alg.fromFile(fullpath):
|
||||
if alg.name():
|
||||
alg.descriptionFile = fullpath
|
||||
self.algs.append(alg)
|
||||
else:
|
||||
QgsMessageLog.logMessage(self.tr('Could not load model {0}', 'ModelerAlgorithmProvider').format(descriptionFile),
|
||||
self.tr('Processing'), QgsMessageLog.CRITICAL)
|
||||
|
@ -42,7 +42,8 @@ from qgis.core import (QgsApplication,
|
||||
QgsSettings,
|
||||
QgsMessageLog,
|
||||
QgsProcessingUtils,
|
||||
QgsProcessingModelAlgorithm)
|
||||
QgsProcessingModelAlgorithm,
|
||||
QgsXmlUtils)
|
||||
from qgis.gui import QgsMessageBar
|
||||
from processing.gui.HelpEditionDialog import HelpEditionDialog
|
||||
from processing.gui.AlgorithmDialog import AlgorithmDialog
|
||||
@ -52,6 +53,7 @@ from processing.modeler.ModelerParametersDialog import ModelerParametersDialog
|
||||
from processing.modeler.ModelerUtils import ModelerUtils
|
||||
from processing.modeler.ModelerScene import ModelerScene
|
||||
from processing.modeler.WrongModelException import WrongModelException
|
||||
from qgis.PyQt.QtXml import QDomDocument
|
||||
|
||||
pluginPath = os.path.split(os.path.dirname(__file__))[0]
|
||||
WIDGET, BASE = uic.loadUiType(
|
||||
@ -435,25 +437,21 @@ class ModelerDialog(BASE, WIDGET):
|
||||
self, self.tr('Warning'), self.tr('Please enter group and model names before saving')
|
||||
)
|
||||
return
|
||||
self.model._name = str(self.textName.text())
|
||||
self.model._group = str(self.textGroup.text())
|
||||
self.model.setName(str(self.textName.text()))
|
||||
self.model.setGroup(str(self.textGroup.text()))
|
||||
if self.model.descriptionFile is not None and not saveAs:
|
||||
filename = self.model.descriptionFile
|
||||
else:
|
||||
filename, filter = QFileDialog.getSaveFileName(self,
|
||||
self.tr('Save Model'),
|
||||
ModelerUtils.modelsFolders()[0],
|
||||
self.tr('Processing models (*.model)'))
|
||||
self.tr('Processing models (*.model3)'))
|
||||
if filename:
|
||||
if not filename.endswith('.model'):
|
||||
filename += '.model'
|
||||
if not filename.endswith('.model3'):
|
||||
filename += '.model3'
|
||||
self.model.descriptionFile = filename
|
||||
if filename:
|
||||
text = self.model.toJson()
|
||||
try:
|
||||
with codecs.open(filename, 'w', encoding='utf-8') as fout:
|
||||
fout.write(text)
|
||||
except:
|
||||
if not self.model.toFile(filename):
|
||||
if saveAs:
|
||||
QMessageBox.warning(self, self.tr('I/O error'),
|
||||
self.tr('Unable to save edits. Reason:\n {0}').format(str(sys.exc_info()[1])))
|
||||
@ -475,28 +473,22 @@ class ModelerDialog(BASE, WIDGET):
|
||||
ModelerUtils.modelsFolders()[0],
|
||||
self.tr('Processing models (*.model *.MODEL)'))
|
||||
if filename:
|
||||
try:
|
||||
alg = ModelerAlgorithm.fromFile(filename)
|
||||
alg = ModelerAlgorithm()
|
||||
if alg.fromFile(filename):
|
||||
self.model = alg
|
||||
self.textGroup.setText(alg._group)
|
||||
self.textName.setText(alg._name)
|
||||
self.textGroup.setText(alg.group())
|
||||
self.textName.setText(alg.name())
|
||||
self.repaintModel()
|
||||
|
||||
self.view.centerOn(0, 0)
|
||||
self.hasChanged = False
|
||||
except WrongModelException as e:
|
||||
QgsMessageLog.logMessage(self.tr('Could not load model {0}\n{1}').format(filename, e.msg),
|
||||
else:
|
||||
QgsMessageLog.logMessage(self.tr('Could not load model {0}').format(filename),
|
||||
self.tr('Processing'),
|
||||
QgsMessageLog.CRITICAL)
|
||||
QMessageBox.critical(self, self.tr('Could not open model'),
|
||||
self.tr('The selected model could not be loaded.\n'
|
||||
'See the log for more information.'))
|
||||
except Exception as e:
|
||||
QgsMessageLog.logMessage(self.tr('Could not load model {0}\n{1}').format(filename, e.args[0]),
|
||||
self.tr('Processing'), QgsMessageLog.CRITICAL)
|
||||
QMessageBox.critical(self, self.tr('Could not open model'),
|
||||
self.tr('The selected model could not be loaded.\n'
|
||||
'See the log for more information.'))
|
||||
|
||||
def repaintModel(self, controls=True):
|
||||
self.scene = ModelerScene(self, dialog=self)
|
||||
|
@ -17,6 +17,9 @@
|
||||
|
||||
#include "qgsprocessingmodelalgorithm.h"
|
||||
#include "qgsprocessingregistry.h"
|
||||
#include "qgsxmlutils.h"
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm::ChildAlgorithm( const QString &algorithmId )
|
||||
: mAlgorithmId( algorithmId )
|
||||
@ -78,6 +81,22 @@ QgsProcessingModelAlgorithm::Component::Component( const QString &description )
|
||||
: mDescription( description )
|
||||
{}
|
||||
|
||||
void QgsProcessingModelAlgorithm::Component::saveCommonProperties( QVariantMap &map ) const
|
||||
{
|
||||
map.insert( QStringLiteral( "component_pos_x" ), mPosition.x() );
|
||||
map.insert( QStringLiteral( "component_pos_y" ), mPosition.y() );
|
||||
map.insert( QStringLiteral( "component_description" ), mDescription );
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::Component::restoreCommonProperties( const QVariantMap &map )
|
||||
{
|
||||
QPointF pos;
|
||||
pos.setX( map.value( QStringLiteral( "component_pos_x" ) ).toDouble() );
|
||||
pos.setY( map.value( QStringLiteral( "component_pos_y" ) ).toDouble() );
|
||||
mPosition = pos;
|
||||
mDescription = map.value( QStringLiteral( "component_description" ) ).toString();
|
||||
}
|
||||
|
||||
QStringList QgsProcessingModelAlgorithm::ChildAlgorithm::dependencies() const
|
||||
{
|
||||
return mDependencies;
|
||||
@ -113,6 +132,77 @@ void QgsProcessingModelAlgorithm::ChildAlgorithm::setModelOutputs( const QMap<QS
|
||||
mModelOutputs = modelOutputs;
|
||||
}
|
||||
|
||||
QVariant QgsProcessingModelAlgorithm::ChildAlgorithm::toVariant() const
|
||||
{
|
||||
QVariantMap map;
|
||||
map.insert( QStringLiteral( "id" ), mId );
|
||||
map.insert( QStringLiteral( "alg_id" ), mAlgorithmId );
|
||||
map.insert( QStringLiteral( "active" ), mActive );
|
||||
map.insert( QStringLiteral( "dependencies" ), mDependencies );
|
||||
map.insert( QStringLiteral( "parameters_collapsed" ), mParametersCollapsed );
|
||||
map.insert( QStringLiteral( "outputs_collapsed" ), mOutputsCollapsed );
|
||||
|
||||
saveCommonProperties( map );
|
||||
|
||||
QVariantMap paramMap;
|
||||
QMap< QString, QgsProcessingModelAlgorithm::ChildParameterSource >::const_iterator paramIt = mParams.constBegin();
|
||||
for ( ; paramIt != mParams.constEnd(); ++paramIt )
|
||||
{
|
||||
paramMap.insert( paramIt.key(), paramIt.value().toVariant() );
|
||||
}
|
||||
map.insert( "params", paramMap );
|
||||
|
||||
QVariantMap outputMap;
|
||||
QMap< QString, QgsProcessingModelAlgorithm::ModelOutput >::const_iterator outputIt = mModelOutputs.constBegin();
|
||||
for ( ; outputIt != mModelOutputs.constEnd(); ++outputIt )
|
||||
{
|
||||
outputMap.insert( outputIt.key(), outputIt.value().toVariant() );
|
||||
}
|
||||
map.insert( "outputs", outputMap );
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
bool QgsProcessingModelAlgorithm::ChildAlgorithm::loadVariant( const QVariant &child )
|
||||
{
|
||||
QVariantMap map = child.toMap();
|
||||
|
||||
mId = map.value( QStringLiteral( "id" ) ).toString();
|
||||
mAlgorithmId = map.value( QStringLiteral( "alg_id" ) ).toString();
|
||||
mActive = map.value( QStringLiteral( "active" ) ).toBool();
|
||||
mDependencies = map.value( QStringLiteral( "dependencies" ) ).toStringList();
|
||||
mParametersCollapsed = map.value( QStringLiteral( "parameters_collapsed" ) ).toBool();
|
||||
mOutputsCollapsed = map.value( QStringLiteral( "outputs_collapsed" ) ).toBool();
|
||||
|
||||
restoreCommonProperties( map );
|
||||
|
||||
mParams.clear();
|
||||
QVariantMap paramMap = map.value( QStringLiteral( "params" ) ).toMap();
|
||||
QVariantMap::const_iterator paramIt = paramMap.constBegin();
|
||||
for ( ; paramIt != paramMap.constEnd(); ++paramIt )
|
||||
{
|
||||
ChildParameterSource param;
|
||||
if ( !param.loadVariant( paramIt.value().toMap() ) )
|
||||
return false;
|
||||
|
||||
mParams.insert( paramIt.key(), param );
|
||||
}
|
||||
|
||||
mModelOutputs.clear();
|
||||
QVariantMap outputMap = map.value( QStringLiteral( "outputs" ) ).toMap();
|
||||
QVariantMap::const_iterator outputIt = outputMap.constBegin();
|
||||
for ( ; outputIt != outputMap.constEnd(); ++outputIt )
|
||||
{
|
||||
ModelOutput output;
|
||||
if ( !output.loadVariant( outputIt.value().toMap() ) )
|
||||
return false;
|
||||
|
||||
mModelOutputs.insert( outputIt.key(), output );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsProcessingModelAlgorithm::ChildAlgorithm::parametersCollapsed() const
|
||||
{
|
||||
return mParametersCollapsed;
|
||||
@ -201,6 +291,16 @@ QVariantMap QgsProcessingModelAlgorithm::processAlgorithm( const QVariantMap &pa
|
||||
return QVariantMap();
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::setName( const QString &name )
|
||||
{
|
||||
mModelName = name;
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::setGroup( const QString &group )
|
||||
{
|
||||
mModelGroup = group;
|
||||
}
|
||||
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ChildAlgorithm> QgsProcessingModelAlgorithm::childAlgorithms() const
|
||||
{
|
||||
return mChildAlgorithms;
|
||||
@ -227,6 +327,99 @@ QgsProcessingModelAlgorithm::ModelParameter &QgsProcessingModelAlgorithm::parame
|
||||
return mParameterComponents[ name ];
|
||||
}
|
||||
|
||||
QVariant QgsProcessingModelAlgorithm::toVariant() const
|
||||
{
|
||||
QVariantMap map;
|
||||
map.insert( QStringLiteral( "model_name" ), mModelName );
|
||||
map.insert( QStringLiteral( "model_group" ), mModelGroup );
|
||||
|
||||
QVariantMap childMap;
|
||||
QMap< QString, ChildAlgorithm >::const_iterator childIt = mChildAlgorithms.constBegin();
|
||||
for ( ; childIt != mChildAlgorithms.constEnd(); ++childIt )
|
||||
{
|
||||
childMap.insert( childIt.key(), childIt.value().toVariant() );
|
||||
}
|
||||
map.insert( "children", childMap );
|
||||
|
||||
QVariantMap paramMap;
|
||||
QMap< QString, ModelParameter >::const_iterator paramIt = mParameterComponents.constBegin();
|
||||
for ( ; paramIt != mParameterComponents.constEnd(); ++paramIt )
|
||||
{
|
||||
paramMap.insert( paramIt.key(), paramIt.value().toVariant() );
|
||||
}
|
||||
map.insert( "parameters", paramMap );
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
bool QgsProcessingModelAlgorithm::loadVariant( const QVariant &model )
|
||||
{
|
||||
QVariantMap map = model.toMap();
|
||||
|
||||
mModelName = map.value( QStringLiteral( "model_name" ) ).toString();
|
||||
mModelGroup = map.value( QStringLiteral( "model_group" ) ).toString();
|
||||
|
||||
mChildAlgorithms.clear();
|
||||
QVariantMap childMap = map.value( QStringLiteral( "children" ) ).toMap();
|
||||
QVariantMap::const_iterator childIt = childMap.constBegin();
|
||||
for ( ; childIt != childMap.constEnd(); ++childIt )
|
||||
{
|
||||
ChildAlgorithm child;
|
||||
if ( !child.loadVariant( childIt.value() ) )
|
||||
return false;
|
||||
|
||||
mChildAlgorithms.insert( child.childId(), child );
|
||||
}
|
||||
|
||||
mParameterComponents.clear();
|
||||
QVariantMap paramMap = map.value( QStringLiteral( "parameters" ) ).toMap();
|
||||
QVariantMap::const_iterator paramIt = paramMap.constBegin();
|
||||
for ( ; paramIt != paramMap.constEnd(); ++paramIt )
|
||||
{
|
||||
ModelParameter param;
|
||||
if ( !param.loadVariant( paramIt.value().toMap() ) )
|
||||
return false;
|
||||
|
||||
mParameterComponents.insert( param.parameterName(), param );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsProcessingModelAlgorithm::toFile( const QString &path ) const
|
||||
{
|
||||
QDomDocument doc = QDomDocument( "model" );
|
||||
QDomElement elem = QgsXmlUtils::writeVariant( toVariant(), doc );
|
||||
doc.appendChild( elem );
|
||||
|
||||
QFile file( path );
|
||||
if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
|
||||
{
|
||||
QTextStream stream( &file );
|
||||
doc.save( stream, 2 );
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QgsProcessingModelAlgorithm::fromFile( const QString &path )
|
||||
{
|
||||
QDomDocument doc;
|
||||
|
||||
QFile file( path );
|
||||
if ( file.open( QFile::ReadOnly ) )
|
||||
{
|
||||
if ( !doc.setContent( &file ) )
|
||||
return false;
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
QVariant props = QgsXmlUtils::readVariant( doc.firstChildElement() );
|
||||
return loadVariant( props );
|
||||
}
|
||||
|
||||
void QgsProcessingModelAlgorithm::setChildAlgorithms( const QMap<QString, ChildAlgorithm> &childAlgorithms )
|
||||
{
|
||||
mChildAlgorithms = childAlgorithms;
|
||||
@ -484,13 +677,91 @@ QgsProcessingModelAlgorithm::ChildParameterSource::Source QgsProcessingModelAlgo
|
||||
return mSource;
|
||||
}
|
||||
|
||||
QVariant QgsProcessingModelAlgorithm::ChildParameterSource::toVariant() const
|
||||
{
|
||||
QVariantMap map;
|
||||
map.insert( QStringLiteral( "source" ), mSource );
|
||||
switch ( mSource )
|
||||
{
|
||||
case ModelParameter:
|
||||
map.insert( QStringLiteral( "parameter_name" ), mParameterName );
|
||||
break;
|
||||
|
||||
case ChildOutput:
|
||||
map.insert( QStringLiteral( "child_id" ), mChildId );
|
||||
map.insert( QStringLiteral( "output_name" ), mOutputName );
|
||||
break;
|
||||
|
||||
case StaticValue:
|
||||
map.insert( QStringLiteral( "static_value" ), mStaticValue );
|
||||
break;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
bool QgsProcessingModelAlgorithm::ChildParameterSource::loadVariant( const QVariantMap &map )
|
||||
{
|
||||
mSource = static_cast< Source >( map.value( QStringLiteral( "source" ) ).toInt() );
|
||||
switch ( mSource )
|
||||
{
|
||||
case ModelParameter:
|
||||
mParameterName = map.value( QStringLiteral( "parameter_name" ) ).toString();
|
||||
break;
|
||||
|
||||
case ChildOutput:
|
||||
mChildId = map.value( QStringLiteral( "child_id" ) ).toString();
|
||||
mOutputName = map.value( QStringLiteral( "output_name" ) ).toString();
|
||||
break;
|
||||
|
||||
case StaticValue:
|
||||
mStaticValue = map.value( QStringLiteral( "static_value" ) );
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QgsProcessingModelAlgorithm::ModelOutput::ModelOutput( const QString &description )
|
||||
: QgsProcessingModelAlgorithm::Component( description )
|
||||
{}
|
||||
|
||||
QVariant QgsProcessingModelAlgorithm::ModelOutput::toVariant() const
|
||||
{
|
||||
QVariantMap map;
|
||||
map.insert( QStringLiteral( "child_id" ), mChildId );
|
||||
map.insert( QStringLiteral( "output_name" ), mOutputName );
|
||||
saveCommonProperties( map );
|
||||
return map;
|
||||
}
|
||||
|
||||
bool QgsProcessingModelAlgorithm::ModelOutput::loadVariant( const QVariantMap &map )
|
||||
{
|
||||
mChildId = map.value( QStringLiteral( "child_id" ) ).toString();
|
||||
mOutputName = map.value( QStringLiteral( "output_name" ) ).toString();
|
||||
restoreCommonProperties( map );
|
||||
return true;
|
||||
}
|
||||
|
||||
QgsProcessingModelAlgorithm::ModelParameter::ModelParameter( const QString ¶meterName )
|
||||
: QgsProcessingModelAlgorithm::Component()
|
||||
, mParameterName( parameterName )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QVariant QgsProcessingModelAlgorithm::ModelParameter::toVariant() const
|
||||
{
|
||||
QVariantMap map;
|
||||
map.insert( QStringLiteral( "name" ), mParameterName );
|
||||
|
||||
//TODO - parameter definition
|
||||
|
||||
saveCommonProperties( map );
|
||||
return map;
|
||||
}
|
||||
|
||||
bool QgsProcessingModelAlgorithm::ModelParameter::loadVariant( const QVariantMap &map )
|
||||
{
|
||||
mParameterName = map.value( QStringLiteral( "name" ) ).toString();
|
||||
restoreCommonProperties( map );
|
||||
return true;
|
||||
}
|
||||
|
@ -140,6 +140,18 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
|
||||
*/
|
||||
void setOutputName( const QString &name ) { mOutputName = name; mSource = ChildOutput; }
|
||||
|
||||
/**
|
||||
* Saves this source to a QVariant.
|
||||
* \see loadVariant()
|
||||
*/
|
||||
QVariant toVariant() const;
|
||||
|
||||
/**
|
||||
* Loads this source from a QVariantMap.
|
||||
* \see toVariant()
|
||||
*/
|
||||
bool loadVariant( const QVariantMap &map );
|
||||
|
||||
private:
|
||||
|
||||
Source mSource = StaticValue;
|
||||
@ -194,6 +206,18 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
|
||||
//! Copies are protected to avoid slicing
|
||||
Component &operator=( const QgsProcessingModelAlgorithm::Component &other ) = default;
|
||||
|
||||
/**
|
||||
* Saves the component properties to a QVariantMap.
|
||||
* \see restoreCommonProperties()
|
||||
*/
|
||||
void saveCommonProperties( QVariantMap &map ) const;
|
||||
|
||||
/**
|
||||
* Restores the component properties from a QVariantMap.
|
||||
* \see saveCommonProperties()
|
||||
*/
|
||||
void restoreCommonProperties( const QVariantMap &map );
|
||||
|
||||
private:
|
||||
|
||||
//! Position of component within model
|
||||
@ -232,6 +256,18 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
|
||||
*/
|
||||
void setParameterName( const QString &name ) { mParameterName = name; }
|
||||
|
||||
/**
|
||||
* Saves this parameter to a QVariant.
|
||||
* \see loadVariant()
|
||||
*/
|
||||
QVariant toVariant() const;
|
||||
|
||||
/**
|
||||
* Loads this parameter from a QVariantMap.
|
||||
* \see toVariant()
|
||||
*/
|
||||
bool loadVariant( const QVariantMap &map );
|
||||
|
||||
private:
|
||||
|
||||
QString mParameterName;
|
||||
@ -277,6 +313,18 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
|
||||
*/
|
||||
void setOutputName( const QString &name ) { mOutputName = name; }
|
||||
|
||||
/**
|
||||
* Saves this output to a QVariant.
|
||||
* \see loadVariant()
|
||||
*/
|
||||
QVariant toVariant() const;
|
||||
|
||||
/**
|
||||
* Loads this output from a QVariantMap.
|
||||
* \see toVariant()
|
||||
*/
|
||||
bool loadVariant( const QVariantMap &map );
|
||||
|
||||
private:
|
||||
|
||||
QString mChildId;
|
||||
@ -456,6 +504,18 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
|
||||
*/
|
||||
void setModelOutputs( const QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> &outputs );
|
||||
|
||||
/**
|
||||
* Saves this child to a QVariant.
|
||||
* \see loadVariant()
|
||||
*/
|
||||
QVariant toVariant() const;
|
||||
|
||||
/**
|
||||
* Loads this child from a QVariant.
|
||||
* \see toVariant()
|
||||
*/
|
||||
bool loadVariant( const QVariant &child );
|
||||
|
||||
private:
|
||||
|
||||
QString mId;
|
||||
@ -494,6 +554,18 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
|
||||
QVariantMap processAlgorithm( const QVariantMap ¶meters,
|
||||
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const override;
|
||||
|
||||
/**
|
||||
* Sets the model \a name.
|
||||
* \see name()
|
||||
*/
|
||||
void setName( const QString &name );
|
||||
|
||||
/**
|
||||
* Sets the model \a group.
|
||||
* \see group()
|
||||
*/
|
||||
void setGroup( const QString &group );
|
||||
|
||||
/**
|
||||
* Returns the map of child algorithms contained in the model. The keys
|
||||
* are the child algorithm ids (see QgsProcessingModelAlgorithm::ChildAlgorithm::childId()).
|
||||
@ -650,6 +722,18 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
|
||||
*/
|
||||
QgsProcessingModelAlgorithm::ModelParameter ¶meterComponent( const QString &name );
|
||||
|
||||
/**
|
||||
* Writes the model to a file, at the specified \a path.
|
||||
* \see fromFile()
|
||||
*/
|
||||
bool toFile( const QString &path ) const;
|
||||
|
||||
/**
|
||||
* Reads the model from a file, at the specified \a path.
|
||||
* \see toFile()
|
||||
*/
|
||||
bool fromFile( const QString &path );
|
||||
|
||||
private:
|
||||
|
||||
QString mModelName;
|
||||
@ -662,6 +746,24 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
|
||||
|
||||
void dependsOnChildAlgorithmsRecursive( const QString &childId, QSet<QString> &depends ) const;
|
||||
void dependentChildAlgorithmsRecursive( const QString &childId, QSet<QString> &depends ) const;
|
||||
|
||||
/**
|
||||
* Saves this model to a QVariantMap, wrapped in a QVariant.
|
||||
* You can use QgsXmlUtils::writeVariant to save it to an XML document.
|
||||
*
|
||||
* \see loadVariant()
|
||||
*/
|
||||
QVariant toVariant() const;
|
||||
|
||||
/**
|
||||
* Loads this model from a QVariantMap, wrapped in a QVariant.
|
||||
* You can use QgsXmlUtils::readVariant to load it from an XML document.
|
||||
*
|
||||
* \see toVariant()
|
||||
*/
|
||||
bool loadVariant( const QVariant &model );
|
||||
|
||||
friend class TestQgsProcessing;
|
||||
};
|
||||
|
||||
#endif // QGSPROCESSINGMODELALGORITHM_H
|
||||
|
@ -132,6 +132,19 @@ QDomElement QgsXmlUtils::writeVariant( const QVariant &value, QDomDocument &doc
|
||||
break;
|
||||
}
|
||||
|
||||
case QVariant::StringList:
|
||||
{
|
||||
QStringList list = value.toStringList();
|
||||
|
||||
Q_FOREACH ( const QString &value, list )
|
||||
{
|
||||
QDomElement valueElement = writeVariant( value, doc );
|
||||
element.appendChild( valueElement );
|
||||
element.setAttribute( QStringLiteral( "type" ), QStringLiteral( "StringList" ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QVariant::Int:
|
||||
case QVariant::Bool:
|
||||
case QVariant::Double:
|
||||
@ -193,6 +206,17 @@ QVariant QgsXmlUtils::readVariant( const QDomElement &element )
|
||||
}
|
||||
return list;
|
||||
}
|
||||
else if ( type == QLatin1String( "StringList" ) )
|
||||
{
|
||||
QStringList list;
|
||||
QDomNodeList values = element.childNodes();
|
||||
for ( int i = 0; i < values.count(); ++i )
|
||||
{
|
||||
QDomElement elem = values.at( i ).toElement();
|
||||
list.append( readVariant( elem ).toString() );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
else
|
||||
{
|
||||
return QVariant();
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgsvectorfilewriter.h"
|
||||
#include "qgsexpressioncontext.h"
|
||||
#include "qgsxmlutils.h"
|
||||
|
||||
class DummyAlgorithm : public QgsProcessingAlgorithm
|
||||
{
|
||||
@ -3065,6 +3066,11 @@ void TestQgsProcessing::modelerAlgorithm()
|
||||
QCOMPARE( alg.name(), QStringLiteral( "test" ) );
|
||||
QCOMPARE( alg.displayName(), QStringLiteral( "test" ) );
|
||||
QCOMPARE( alg.group(), QStringLiteral( "testGroup" ) );
|
||||
alg.setName( QStringLiteral( "test2" ) );
|
||||
QCOMPARE( alg.name(), QStringLiteral( "test2" ) );
|
||||
QCOMPARE( alg.displayName(), QStringLiteral( "test2" ) );
|
||||
alg.setGroup( QStringLiteral( "group2" ) );
|
||||
QCOMPARE( alg.group(), QStringLiteral( "group2" ) );
|
||||
|
||||
// child algorithms
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ChildAlgorithm> algs;
|
||||
@ -3299,6 +3305,90 @@ void TestQgsProcessing::modelerAlgorithm()
|
||||
c10.addParameterSource( "y", QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( "p1" ) );
|
||||
alg4.setChildAlgorithm( c10 );
|
||||
QVERIFY( alg4.childAlgorithmsDependOnParameter( "p1" ) );
|
||||
|
||||
|
||||
|
||||
// to/from XML
|
||||
QgsProcessingModelAlgorithm alg5( "test", "testGroup" );
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm alg5c1;
|
||||
alg5c1.setChildId( "cx1" );
|
||||
alg5c1.setAlgorithmId( "buffer" );
|
||||
alg5c1.addParameterSource( "x", QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( "p1" ) );
|
||||
alg5c1.addParameterSource( "y", QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( "cx2", "out3" ) );
|
||||
alg5c1.addParameterSource( "z", QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 5 ) );
|
||||
alg5c1.setActive( true );
|
||||
alg5c1.setOutputsCollapsed( true );
|
||||
alg5c1.setParametersCollapsed( true );
|
||||
alg5c1.setDescription( "child 1" );
|
||||
alg5c1.setPosition( QPointF( 1, 2 ) );
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> alg5c1outputs;
|
||||
QgsProcessingModelAlgorithm::ModelOutput alg5c1out1;
|
||||
alg5c1out1.setDescription( QStringLiteral( "my output" ) );
|
||||
alg5c1out1.setPosition( QPointF( 3, 4 ) );
|
||||
alg5c1outputs.insert( QStringLiteral( "a" ), alg5c1out1 );
|
||||
alg5c1.setModelOutputs( alg5c1outputs );
|
||||
alg5.addChildAlgorithm( alg5c1 );
|
||||
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm alg5c2;
|
||||
alg5c2.setChildId( "cx2" );
|
||||
alg5c2.setActive( false );
|
||||
alg5c2.setOutputsCollapsed( false );
|
||||
alg5c2.setParametersCollapsed( false );
|
||||
alg5c2.setDependencies( QStringList() << "a" << "b" );
|
||||
alg5.addChildAlgorithm( alg5c2 );
|
||||
|
||||
QMap<QString, QgsProcessingModelAlgorithm::ModelParameter> alg5pComponents;
|
||||
QgsProcessingModelAlgorithm::ModelParameter alg5pc1;
|
||||
alg5pc1.setParameterName( QStringLiteral( "my_param" ) );
|
||||
alg5pc1.setPosition( QPointF( 11, 12 ) );
|
||||
alg5pComponents.insert( QStringLiteral( "my_param" ), alg5pc1 );
|
||||
alg5.setParameterComponents( alg5pComponents );
|
||||
|
||||
QDomDocument doc = QDomDocument( "model" );
|
||||
QDomElement elem = QgsXmlUtils::writeVariant( alg5.toVariant(), doc );
|
||||
doc.appendChild( elem );
|
||||
|
||||
QgsProcessingModelAlgorithm alg6;
|
||||
QVERIFY( alg6.loadVariant( QgsXmlUtils::readVariant( doc.firstChildElement() ) ) );
|
||||
QCOMPARE( alg6.name(), QStringLiteral( "test" ) );
|
||||
QCOMPARE( alg6.group(), QStringLiteral( "testGroup" ) );
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm alg6c1 = alg6.childAlgorithm( "cx1" );
|
||||
QCOMPARE( alg6c1.childId(), QStringLiteral( "cx1" ) );
|
||||
QCOMPARE( alg6c1.algorithmId(), QStringLiteral( "buffer" ) );
|
||||
QVERIFY( alg6c1.isActive() );
|
||||
QVERIFY( alg6c1.outputsCollapsed() );
|
||||
QVERIFY( alg6c1.parametersCollapsed() );
|
||||
QCOMPARE( alg6c1.description(), QStringLiteral( "child 1" ) );
|
||||
QCOMPARE( alg6c1.position().x(), 1.0 );
|
||||
QCOMPARE( alg6c1.position().y(), 2.0 );
|
||||
QCOMPARE( alg6c1.parameterSources().count(), 3 );
|
||||
QCOMPARE( alg6c1.parameterSources().value( "x" ).source(), QgsProcessingModelAlgorithm::ChildParameterSource::ModelParameter );
|
||||
QCOMPARE( alg6c1.parameterSources().value( "x" ).parameterName(), QStringLiteral( "p1" ) );
|
||||
QCOMPARE( alg6c1.parameterSources().value( "y" ).source(), QgsProcessingModelAlgorithm::ChildParameterSource::ChildOutput );
|
||||
QCOMPARE( alg6c1.parameterSources().value( "y" ).outputChildId(), QStringLiteral( "cx2" ) );
|
||||
QCOMPARE( alg6c1.parameterSources().value( "y" ).outputName(), QStringLiteral( "out3" ) );
|
||||
QCOMPARE( alg6c1.parameterSources().value( "z" ).source(), QgsProcessingModelAlgorithm::ChildParameterSource::StaticValue );
|
||||
QCOMPARE( alg6c1.parameterSources().value( "z" ).staticValue().toInt(), 5 );
|
||||
QCOMPARE( alg6c1.modelOutputs().count(), 1 );
|
||||
QCOMPARE( alg6c1.modelOutputs().value( QStringLiteral( "a" ) ).description(), QStringLiteral( "my output" ) );
|
||||
QCOMPARE( alg6c1.modelOutput( "a" ).description(), QStringLiteral( "my output" ) );
|
||||
QCOMPARE( alg6c1.modelOutput( "a" ).position().x(), 3.0 );
|
||||
QCOMPARE( alg6c1.modelOutput( "a" ).position().y(), 4.0 );
|
||||
|
||||
|
||||
QgsProcessingModelAlgorithm::ChildAlgorithm alg6c2 = alg6.childAlgorithm( "cx2" );
|
||||
QCOMPARE( alg6c2.childId(), QStringLiteral( "cx2" ) );
|
||||
QVERIFY( !alg6c2.isActive() );
|
||||
QVERIFY( !alg6c2.outputsCollapsed() );
|
||||
QVERIFY( !alg6c2.parametersCollapsed() );
|
||||
QCOMPARE( alg6c2.dependencies(), QStringList() << "a" << "b" );
|
||||
|
||||
QCOMPARE( alg6.parameterComponents().count(), 1 );
|
||||
QCOMPARE( alg6.parameterComponents().value( QStringLiteral( "my_param" ) ).parameterName(), QStringLiteral( "my_param" ) );
|
||||
QCOMPARE( alg6.parameterComponent( "my_param" ).parameterName(), QStringLiteral( "my_param" ) );
|
||||
QCOMPARE( alg6.parameterComponent( "my_param" ).position().x(), 11.0 );
|
||||
QCOMPARE( alg6.parameterComponent( "my_param" ).position().y(), 12.0 );
|
||||
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsProcessing )
|
||||
|
Loading…
x
Reference in New Issue
Block a user