Skip to content

Commit

Permalink
[processing] Allow specifying a project path to load when running
Browse files Browse the repository at this point in the history
algorithms via qgis_process

Allows execution of algorithms which require a project, e.g. Rasterize

Also show graceful errors/help text when attempting to run an algorithm
which requires a project but one is not specified
  • Loading branch information
nyalldawson committed Jul 29, 2020
1 parent 68c7cfb commit 6f0b7b0
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 5 deletions.
33 changes: 29 additions & 4 deletions src/process/qgsprocess.cpp
Expand Up @@ -26,6 +26,7 @@
#include "qgsapplication.h"
#include "qgsprocessingparametertype.h"
#include "processing/models/qgsprocessingmodelalgorithm.h"
#include "qgsproject.h"

#if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID)
#include "sigwatch.h"
Expand Down Expand Up @@ -219,6 +220,7 @@ int QgsProcessingExec::run( const QStringList &args )
QString ellipsoid;
QgsUnitTypes::DistanceUnit distanceUnit = QgsUnitTypes::DistanceUnknownUnit;
QgsUnitTypes::AreaUnit areaUnit = QgsUnitTypes::AreaUnknownUnit;
QString projectPath;
QVariantMap params;
for ( int i = 3; i < args.count(); i++ )
{
Expand All @@ -243,6 +245,10 @@ int QgsProcessingExec::run( const QStringList &args )
{
areaUnit = QgsUnitTypes::decodeAreaUnit( parts.mid( 1 ).join( '=' ) );
}
else if ( name.compare( QLatin1String( "project_path" ), Qt::CaseInsensitive ) == 0 )
{
projectPath = parts.mid( 1 ).join( '=' );
}
else
{
const QString value = parts.mid( 1 ).join( '=' );
Expand All @@ -256,7 +262,7 @@ int QgsProcessingExec::run( const QStringList &args )
}
}

return execute( algId, params, ellipsoid, distanceUnit, areaUnit );
return execute( algId, params, ellipsoid, distanceUnit, areaUnit, projectPath );
}
else
{
Expand All @@ -276,8 +282,9 @@ void QgsProcessingExec::showUsage( const QString &appName )
<< "\tplugins\tlist available and active plugins\n"
<< "\tlist\tlist all available processing algorithms\n"
<< "\thelp\tshow help for an algorithm. The algorithm id or a path to a model file must be specified.\n"
<< "\trun\truns an algorithm. The algorithm id or a path to a model file and parameter values must be specified. Parameter values are specified via the --PARAMETER=VALUE syntax. "
"If required, the ellipsoid to use for distance and area calculations can be specified via the \"--ELLIPSOID=name\" argument.\n";
<< "\trun\truns an algorithm. The algorithm id or a path to a model file and parameter values must be specified. Parameter values are specified via the --PARAMETER=VALUE syntax.\n"
<< "\t\tIf required, the ellipsoid to use for distance and area calculations can be specified via the \"--ELLIPSOID=name\" argument.\n"
<< "\t\tIf required, an existing QGIS project to use during the algorithm execution can be specified via the \"--PROJECT_PATH=path\" argument.\n";

std::cout << msg.join( QString() ).toLocal8Bit().constData();
}
Expand Down Expand Up @@ -430,7 +437,7 @@ int QgsProcessingExec::showAlgorithmHelp( const QString &id )
return 0;
}

int QgsProcessingExec::execute( const QString &id, const QVariantMap &params, const QString &ellipsoid, QgsUnitTypes::DistanceUnit distanceUnit, QgsUnitTypes::AreaUnit areaUnit )
int QgsProcessingExec::execute( const QString &id, const QVariantMap &params, const QString &ellipsoid, QgsUnitTypes::DistanceUnit distanceUnit, QgsUnitTypes::AreaUnit areaUnit, const QString &projectPath )
{
std::unique_ptr< QgsProcessingModelAlgorithm > model;
const QgsProcessingAlgorithm *alg = nullptr;
Expand Down Expand Up @@ -473,6 +480,23 @@ int QgsProcessingExec::execute( const QString &id, const QVariantMap &params, co
std::cout << "Warning: this algorithm is deprecated and may be removed in a future QGIS version!\n";
std::cout << "****************\n\n";
}

if ( alg->flags() & QgsProcessingAlgorithm::FlagRequiresProject && projectPath.isEmpty() )
{
std::cerr << QStringLiteral( "The \"%1\" algorithm requires a QGIS project to execute. Specify a path to an existing project with the \"--PROJECT_PATH=xxx\" argument.\n" ).arg( id ).toLocal8Bit().constData();
return 1;
}
}

std::unique_ptr< QgsProject > project;
if ( !projectPath.isEmpty() )
{
project = qgis::make_unique< QgsProject >();
if ( !project->read( projectPath ) )
{
std::cerr << QStringLiteral( "Could not load the QGIS project \"%1\"\n" ).arg( projectPath ).toLocal8Bit().constData();
return 1;
}
}

std::cout << "\n----------------\n";
Expand All @@ -496,6 +520,7 @@ int QgsProcessingExec::execute( const QString &id, const QVariantMap &params, co
context.setEllipsoid( ellipsoid );
context.setDistanceUnit( distanceUnit );
context.setAreaUnit( areaUnit );
context.setProject( project.get() );

const QgsProcessingParameterDefinitions defs = alg->parameterDefinitions();
QList< const QgsProcessingParameterDefinition * > missingParams;
Expand Down
7 changes: 6 additions & 1 deletion src/process/qgsprocess.h
Expand Up @@ -69,7 +69,12 @@ class QgsProcessingExec
void listAlgorithms();
void listPlugins();
int showAlgorithmHelp( const QString &id );
int execute( const QString &algId, const QVariantMap &parameters, const QString &ellipsoid, QgsUnitTypes::DistanceUnit distanceUnit, QgsUnitTypes::AreaUnit areaUnit );
int execute( const QString &algId,
const QVariantMap &parameters,
const QString &ellipsoid,
QgsUnitTypes::DistanceUnit distanceUnit,
QgsUnitTypes::AreaUnit areaUnit,
const QString &projectPath = QString() );

std::unique_ptr< QgsPythonUtils > mPythonUtils;
std::unique_ptr<QgsPythonUtils> loadPythonSupport();
Expand Down

0 comments on commit 6f0b7b0

Please sign in to comment.