From 53d08d73e62cdb2a3d1b62194dc0a57a995d9b5f Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 16 Dec 2021 16:16:44 +1000 Subject: [PATCH] Add method to convert parameters for a processing algorithm to a JSON serializable map --- .../processing/qgsprocessingalgorithm.sip.in | 12 ++++- .../processing/qgsprocessingalgorithm.cpp | 24 ++++++++++ src/core/processing/qgsprocessingalgorithm.h | 11 ++++- tests/src/analysis/testqgsprocessing.cpp | 46 +++++++++++++++++++ 4 files changed, 91 insertions(+), 2 deletions(-) diff --git a/python/core/auto_generated/processing/qgsprocessingalgorithm.sip.in b/python/core/auto_generated/processing/qgsprocessingalgorithm.sip.in index 27ddfe92520..1201617dd22 100644 --- a/python/core/auto_generated/processing/qgsprocessingalgorithm.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingalgorithm.sip.in @@ -447,7 +447,7 @@ string. virtual QString asQgisProcessCommand( const QVariantMap ¶meters, QgsProcessingContext &context, bool &ok /Out/ ) const; %Docstring -Returns a command string which will execut the algorithm using the specified ``parameters`` +Returns a command string which will execute the algorithm using the specified ``parameters`` via the command line qgis_process tool. Note that some combinations of parameter types and values cannot be represented as a qgis_process string. @@ -457,6 +457,16 @@ Note that some combinations of parameter types and values cannot be represented :return: - equivalent qgis_process command - ok: will be set to ``True`` if the command was successfully generated + + +.. versionadded:: 3.24 +%End + + virtual QVariantMap asMap( const QVariantMap ¶meters, QgsProcessingContext &context ) const; +%Docstring +Returns a JSON serializable variant map containing the specified ``parameters`` and ``context`` settings. + +.. versionadded:: 3.24 %End void setProvider( QgsProcessingProvider *provider ); diff --git a/src/core/processing/qgsprocessingalgorithm.cpp b/src/core/processing/qgsprocessingalgorithm.cpp index 9f7420582bc..533e6cf97b6 100644 --- a/src/core/processing/qgsprocessingalgorithm.cpp +++ b/src/core/processing/qgsprocessingalgorithm.cpp @@ -340,6 +340,30 @@ QString QgsProcessingAlgorithm::asQgisProcessCommand( const QVariantMap ¶met return parts.join( ' ' ); } +QVariantMap QgsProcessingAlgorithm::asMap( const QVariantMap ¶meters, QgsProcessingContext &context ) const +{ + QVariantMap properties = context.exportToMap(); + + // we only include the project path argument if a project is actually required by the algorithm + if ( !( flags() & FlagRequiresProject ) ) + properties.remove( QStringLiteral( "project_path" ) ); + + QVariantMap paramValues; + for ( const QgsProcessingParameterDefinition *def : mParameters ) + { + if ( def->flags() & QgsProcessingParameterDefinition::FlagHidden ) + continue; + + if ( !parameters.contains( def->name() ) ) + continue; + + paramValues.insert( def->name(), def->valueAsJsonObject( parameters.value( def->name() ), context ) ); + } + + properties.insert( QStringLiteral( "inputs" ), paramValues ); + return properties; +} + bool QgsProcessingAlgorithm::addParameter( QgsProcessingParameterDefinition *definition, bool createOutput ) { if ( !definition ) diff --git a/src/core/processing/qgsprocessingalgorithm.h b/src/core/processing/qgsprocessingalgorithm.h index 61d460bbc81..a37508905c5 100644 --- a/src/core/processing/qgsprocessingalgorithm.h +++ b/src/core/processing/qgsprocessingalgorithm.h @@ -462,7 +462,7 @@ class CORE_EXPORT QgsProcessingAlgorithm virtual QString asPythonCommand( const QVariantMap ¶meters, QgsProcessingContext &context ) const; /** - * Returns a command string which will execut the algorithm using the specified \a parameters + * Returns a command string which will execute the algorithm using the specified \a parameters * via the command line qgis_process tool. * * Note that some combinations of parameter types and values cannot be represented as a qgis_process string. @@ -472,9 +472,18 @@ class CORE_EXPORT QgsProcessingAlgorithm * \param ok will be set to TRUE if the command was successfully generated * * \returns equivalent qgis_process command + * + * \since QGIS 3.24 */ virtual QString asQgisProcessCommand( const QVariantMap ¶meters, QgsProcessingContext &context, bool &ok SIP_OUT ) const; + /** + * Returns a JSON serializable variant map containing the specified \a parameters and \a context settings. + * + * \since QGIS 3.24 + */ + virtual QVariantMap asMap( const QVariantMap ¶meters, QgsProcessingContext &context ) const; + /** * Associates this algorithm with its provider. No transfer of ownership is involved. */ diff --git a/tests/src/analysis/testqgsprocessing.cpp b/tests/src/analysis/testqgsprocessing.cpp index 571e0b4eedc..19e5ccbff65 100644 --- a/tests/src/analysis/testqgsprocessing.cpp +++ b/tests/src/analysis/testqgsprocessing.cpp @@ -389,6 +389,43 @@ class DummyAlgorithm : public QgsProcessingAlgorithm QVERIFY( !ok ); } + void runAsAsJsonMapChecks() + { + addParameter( new QgsProcessingParameterString( "p1" ) ); + addParameter( new QgsProcessingParameterEnum( "p2", QString(), QStringList( {"a", "b"} ), true ) ); + QgsProcessingParameterString *hidden = new QgsProcessingParameterString( "p3" ); + hidden->setFlags( QgsProcessingParameterDefinition::FlagHidden ); + addParameter( hidden ); + + QVariantMap params; + QgsProcessingContext context; + + QString res; + QCOMPARE( asMap( params, context ), QVariantMap( { {QStringLiteral( "inputs" ), QVariantMap()}} ) ); + params.insert( QStringLiteral( "p1" ), "a" ); + res = QString::fromStdString( QgsJsonUtils::jsonFromVariant( asMap( params, context ) ).dump() ); + QCOMPARE( res, QStringLiteral( "{\"inputs\":{\"p1\":\"a\"}}" ) ); + params.insert( QStringLiteral( "p2" ), QVariant() ); + res = QString::fromStdString( QgsJsonUtils::jsonFromVariant( asMap( params, context ) ).dump() ); + QCOMPARE( res, QStringLiteral( "{\"inputs\":{\"p1\":\"a\",\"p2\":null}}" ) ); + params.insert( "p2", "b" ); + res = QString::fromStdString( QgsJsonUtils::jsonFromVariant( asMap( params, context ) ).dump() ); + QCOMPARE( res, QStringLiteral( "{\"inputs\":{\"p1\":\"a\",\"p2\":\"b\"}}" ) ); + + params.insert( "p2", QStringList( {"b", "c"} ) ); + res = QString::fromStdString( QgsJsonUtils::jsonFromVariant( asMap( params, context ) ).dump() ); + QCOMPARE( res, QStringLiteral( "{\"inputs\":{\"p1\":\"a\",\"p2\":[\"b\",\"c\"]}}" ) ); + + // hidden, shouldn't be shown + params.insert( "p3", "b" ); + res = QString::fromStdString( QgsJsonUtils::jsonFromVariant( asMap( params, context ) ).dump() ); + QCOMPARE( res, QStringLiteral( "{\"inputs\":{\"p1\":\"a\",\"p2\":[\"b\",\"c\"]}}" ) ); + + // test inclusion of a context setting + context.setDistanceUnit( QgsUnitTypes::DistanceMeters ); + res = QString::fromStdString( QgsJsonUtils::jsonFromVariant( asMap( params, context ) ).dump() ); + QCOMPARE( res, QStringLiteral( "{\"distance_units\":\"meters\",\"inputs\":{\"p1\":\"a\",\"p2\":[\"b\",\"c\"]}}" ) ); + } void addDestParams() { @@ -733,6 +770,7 @@ class TestQgsProcessing: public QObject void generateIteratingDestination(); void asPythonCommand(); void asQgisProcessCommand(); + void asJsonMap(); void modelerAlgorithm(); void modelExecution(); void modelBranchPruning(); @@ -10922,6 +10960,14 @@ void TestQgsProcessing::asQgisProcessCommand() alg.runAsQgisProcessCommandChecks(); } +void TestQgsProcessing::asJsonMap() +{ + // test converting an algorithm to a json serializable map + + DummyAlgorithm alg( "test" ); + alg.runAsAsJsonMapChecks(); +} + void TestQgsProcessing::modelerAlgorithm() { //static value source