Skip to content

Commit

Permalink
Fix loading of results after running algorithms
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jun 5, 2017
1 parent f9887aa commit 5b9d925
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 81 deletions.
12 changes: 12 additions & 0 deletions python/core/processing/qgsprocessingparameters.sip
Expand Up @@ -41,6 +41,12 @@ class QgsProcessingFeatureSourceDefinition
True if only selected features in the source should be used by algorithms.
%End


operator QVariant() const;
%Docstring
Allows direct construction of QVariants.
%End

};


Expand Down Expand Up @@ -79,6 +85,12 @@ class QgsProcessingFeatureSink
Encoding for destination file.
%End


operator QVariant() const;
%Docstring
Allows direct construction of QVariants.
%End

};


Expand Down
23 changes: 8 additions & 15 deletions python/plugins/processing/gui/AlgorithmDialog.py
Expand Up @@ -35,6 +35,7 @@
QgsMessageLog,
QgsProcessingParameterDefinition,
QgsProcessingOutputVectorLayer,
QgsProcessingFeatureSink,
QgsProcessingParameterFeatureSink)
from qgis.gui import QgsMessageBar
from qgis.utils import iface
Expand Down Expand Up @@ -109,20 +110,15 @@ def getParamValues(self):
if not param.checkValueIsAcceptable(value):
raise AlgorithmDialogBase.InvalidParameterValue(param, wrapper.widget)
else:
parameters[param.name()] = self.mainWidget.outputWidgets[param.name()].getValue()
open_after_run = False
if not param.flags() & QgsProcessingParameterDefinition.FlagHidden and \
isinstance(param, (OutputRaster, QgsProcessingParameterFeatureSink, OutputTable)):
if self.mainWidget.checkBoxes[param.name()].isChecked():
open_after_run = True

return parameters

def getLayersToOpen(self):
layer_outputs = []
for param in self.alg.destinationParameterDefinitions():
if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
continue
if isinstance(param, (OutputRaster, QgsProcessingParameterFeatureSink, OutputTable)):
if self.mainWidget.checkBoxes[param.name()].isChecked():
layer_outputs.append(param.name())
parameters[param.name()] = QgsProcessingFeatureSink(self.mainWidget.outputWidgets[param.name()].getValue(), open_after_run)

return layer_outputs
return parameters

def checkExtentCRS(self):
unmatchingCRS = False
Expand Down Expand Up @@ -255,9 +251,6 @@ def finish(self, result, context):

if self.iterateParam is None:

for o in self.getLayersToOpen():
context.addLayerToLoadOnCompletion(result[o])

if not handleAlgorithmResults(self.alg, context, self.feedback, not keepOpen):
self.resetGUI()
return
Expand Down
80 changes: 27 additions & 53 deletions python/plugins/processing/gui/Postprocessing.py
Expand Up @@ -55,32 +55,6 @@ def handleAlgorithmResults(alg, context, feedback=None, showResults=True):
feedback = QgsProcessingFeedback()
feedback.setProgressText(QCoreApplication.translate('Postprocessing', 'Loading resulting layers'))
i = 0
#for out in alg.outputs:
# feedback.setProgress(100 * i / float(len(alg.outputs)))
# if out.flags() & QgsProcessingParameterDefinition.FlagHidden or not out.open:
# continue
# if isinstance(out, (OutputRaster, OutputVector, OutputTable)):
# try:
# layer = QgsProcessingUtils.mapLayerFromString(out.value, context)
# if layer:
# layer.setName(out.description())
# QgsProject.instance().addMapLayer(context.temporaryLayerStore().takeMapLayer(layer))
# else:
# if ProcessingConfig.getSetting(
# ProcessingConfig.USE_FILENAME_AS_LAYER_NAME):
# name = os.path.basename(out.value)
# else:
# name = out.description()
# dataobjects.load(out.value, name, alg.crs,
# RenderingStyles.getStyle(alg.id(),
# out.name))
# except Exception:
# QgsMessageLog.logMessage("Error loading result layer:\n" + traceback.format_exc(), 'Processing', QgsMessageLog.CRITICAL)
# wrongLayers.append(out.description())
# elif isinstance(out, OutputHTML):
# resultsList.addResult(alg.icon(), out.description(), out.value)
# i += 1
i = 0
for l in context.layersToLoadOnCompletion():
feedback.setProgress(100 * i / float(len(context.layersToLoadOnCompletion())))
try:
Expand All @@ -103,33 +77,33 @@ def handleAlgorithmResults(alg, context, feedback=None, showResults=True):
QgsMessageLog.logMessage("Error loading result layer:\n" + traceback.format_exc(), 'Processing', QgsMessageLog.CRITICAL)
#wrongLayers.append(out.description())
wrongLayers.append(l)
for out in alg.outputs:
feedback.setProgress(100 * i / float(len(alg.outputs)))
if out.hidden or not out.open:
continue
if isinstance(out, (OutputRaster, OutputVector, OutputTable)):
try:
layer = QgsProcessingUtils.mapLayerFromString(out.value, context)
if layer:
layer.setName(out.description)
QgsProject.instance().addMapLayer(context.temporaryLayerStore().takeMapLayer(layer))
else:
if ProcessingConfig.getSetting(
ProcessingConfig.USE_FILENAME_AS_LAYER_NAME):
name = os.path.basename(out.value)
else:
name = out.description

isRaster = True if isinstance(out, OutputRaster) else False
dataobjects.load(out.value, name, alg.crs,
RenderingStyles.getStyle(alg.id(), out.name),
isRaster)
except Exception:
QgsMessageLog.logMessage("Error loading result layer:\n" + traceback.format_exc(), 'Processing', QgsMessageLog.CRITICAL)
wrongLayers.append(out.description)
elif isinstance(out, OutputHTML):
resultsList.addResult(alg.icon(), out.description, out.value)
i += 1
# for out in alg.outputs:
# feedback.setProgress(100 * i / float(len(alg.outputs)))
# if out.flags() & QgsProcessingParameterDefinition.FlagHidden or not out.open:
# continue
# if isinstance(out, (OutputRaster, OutputVector, OutputTable)):
# try:
# layer = QgsProcessingUtils.mapLayerFromString(out.value, context)
# if layer:
# layer.setName(out.description)
# QgsProject.instance().addMapLayer(context.temporaryLayerStore().takeMapLayer(layer))
# else:
# if ProcessingConfig.getSetting(
# ProcessingConfig.USE_FILENAME_AS_LAYER_NAME):
# name = os.path.basename(out.value)
# else:
# name = out.description
#
# isRaster = True if isinstance(out, OutputRaster) else False
# dataobjects.load(out.value, name, alg.crs,
# RenderingStyles.getStyle(alg.id(), out.name),
# isRaster)
# except Exception:
# QgsMessageLog.logMessage("Error loading result layer:\n" + traceback.format_exc(), 'Processing', QgsMessageLog.CRITICAL)
# wrongLayers.append(out.description)
# elif isinstance(out, OutputHTML):
# resultsList.addResult(alg.icon(), out.description, out.value)
# i += 1

QApplication.restoreOverrideCursor()
if wrongLayers:
Expand Down
30 changes: 22 additions & 8 deletions src/core/processing/qgsprocessingparameters.cpp
Expand Up @@ -1268,15 +1268,22 @@ QgsProcessingParameterFeatureSource::QgsProcessingParameterFeatureSource( const

bool QgsProcessingParameterFeatureSource::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context ) const
{
if ( !input.isValid() )
QVariant var = input;
if ( !var.isValid() )
return mFlags & FlagOptional;

if ( input.canConvert<QgsProperty>() )
if ( var.canConvert<QgsProcessingFeatureSourceDefinition>() )
{
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( var );
var = fromVar.source;
}

if ( var.canConvert<QgsProperty>() )
{
return true;
}

if ( input.type() != QVariant::String || input.toString().isEmpty() )
if ( var.type() != QVariant::String || var.toString().isEmpty() )
return mFlags & FlagOptional;

if ( !context )
Expand All @@ -1286,7 +1293,7 @@ bool QgsProcessingParameterFeatureSource::checkValueIsAcceptable( const QVariant
}

// try to load as layer
if ( QgsProcessingUtils::mapLayerFromString( input.toString(), *context ) )
if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context ) )
return true;

return false;
Expand All @@ -1312,18 +1319,25 @@ QgsProcessingParameterFeatureSink::QgsProcessingParameterFeatureSink( const QStr

bool QgsProcessingParameterFeatureSink::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
if ( !input.isValid() )
QVariant var = input;
if ( !var.isValid() )
return mFlags & FlagOptional;

if ( input.canConvert<QgsProperty>() )
if ( var.canConvert<QgsProcessingFeatureSink>() )
{
QgsProcessingFeatureSink fromVar = qvariant_cast<QgsProcessingFeatureSink>( var );
var = fromVar.sink;
}

if ( var.canConvert<QgsProperty>() )
{
return true;
}

if ( input.type() != QVariant::String )
if ( var.type() != QVariant::String )
return false;

if ( input.toString().isEmpty() )
if ( var.toString().isEmpty() )
return mFlags & FlagOptional;

return true;
Expand Down
14 changes: 14 additions & 0 deletions src/core/processing/qgsprocessingparameters.h
Expand Up @@ -63,6 +63,13 @@ class CORE_EXPORT QgsProcessingFeatureSourceDefinition
*/
bool selectedFeaturesOnly;


//! Allows direct construction of QVariants.
operator QVariant() const
{
return QVariant::fromValue( *this );
}

};

Q_DECLARE_METATYPE( QgsProcessingFeatureSourceDefinition )
Expand Down Expand Up @@ -103,6 +110,13 @@ class CORE_EXPORT QgsProcessingFeatureSink
*/
QString fileEncoding;


//! Allows direct construction of QVariants.
operator QVariant() const
{
return QVariant::fromValue( *this );
}

};

Q_DECLARE_METATYPE( QgsProcessingFeatureSink )
Expand Down
2 changes: 2 additions & 0 deletions src/core/qgsapplication.cpp
Expand Up @@ -130,6 +130,8 @@ void QgsApplication::init( QString customConfigPath )
}

qRegisterMetaType<QgsGeometry::Error>( "QgsGeometry::Error" );
qRegisterMetaType<QgsProcessingFeatureSourceDefinition>( "QgsProcessingFeatureSourceDefinition" );
qRegisterMetaType<QgsProcessingFeatureSink>( "QgsProcessingFeatureSink" );

QString prefixPath( getenv( "QGIS_PREFIX_PATH" ) ? getenv( "QGIS_PREFIX_PATH" ) : applicationDirPath() );
// QgsDebugMsg( QString( "prefixPath(): %1" ).arg( prefixPath ) );
Expand Down
13 changes: 8 additions & 5 deletions tests/src/core/testqgsprocessing.cpp
Expand Up @@ -213,8 +213,8 @@ class TestQgsProcessing: public QObject
void parameterString();
void parameterExpression();
void parameterField();
void parameterVectorLayer();
void parameterOutputVectorLayer();
void parameterFeatureSource();
void parameterFeatureSink();
void checkParamValues();
void combineLayerExtent();
void processingFeatureSource();
Expand Down Expand Up @@ -2179,7 +2179,7 @@ void TestQgsProcessing::parameterField()
QCOMPARE( fields, QStringList() << "abc" << "def" );
}

void TestQgsProcessing::parameterVectorLayer()
void TestQgsProcessing::parameterFeatureSource()
{
// setup a context
QgsProject p;
Expand All @@ -2202,6 +2202,7 @@ void TestQgsProcessing::parameterVectorLayer()
QVERIFY( def->checkValueIsAcceptable( "layer12312312" ) );
QVERIFY( !def->checkValueIsAcceptable( "" ) );
QVERIFY( !def->checkValueIsAcceptable( QVariant() ) );
QVERIFY( def->checkValueIsAcceptable( QgsProcessingFeatureSourceDefinition( "layer1231123" ) ) );

// should be OK
QVERIFY( def->checkValueIsAcceptable( "c:/Users/admin/Desktop/roads_clipped_transformed_v1_reprojected_final_clipped_aAAA.shp" ) );
Expand Down Expand Up @@ -2236,10 +2237,10 @@ void TestQgsProcessing::parameterVectorLayer()
QVERIFY( def->checkValueIsAcceptable( "c:/Users/admin/Desktop/roads_clipped_transformed_v1_reprojected_final_clipped_aAAA.shp" ) );
QVERIFY( def->checkValueIsAcceptable( "" ) );
QVERIFY( def->checkValueIsAcceptable( QVariant() ) );

QVERIFY( def->checkValueIsAcceptable( QgsProcessingFeatureSourceDefinition( "layer1231123" ) ) );
}

void TestQgsProcessing::parameterOutputVectorLayer()
void TestQgsProcessing::parameterFeatureSink()
{
// setup a context
QgsProject p;
Expand All @@ -2255,6 +2256,7 @@ void TestQgsProcessing::parameterOutputVectorLayer()
QVERIFY( def->checkValueIsAcceptable( "layer12312312" ) );
QVERIFY( !def->checkValueIsAcceptable( "" ) );
QVERIFY( !def->checkValueIsAcceptable( QVariant() ) );
QVERIFY( def->checkValueIsAcceptable( QgsProcessingFeatureSink( "layer1231123" ) ) );

// should be OK with or without context - it's an output layer!
QVERIFY( def->checkValueIsAcceptable( "c:/Users/admin/Desktop/roads_clipped_transformed_v1_reprojected_final_clipped_aAAA.shp" ) );
Expand All @@ -2269,6 +2271,7 @@ void TestQgsProcessing::parameterOutputVectorLayer()
QVERIFY( def->checkValueIsAcceptable( "c:/Users/admin/Desktop/roads_clipped_transformed_v1_reprojected_final_clipped_aAAA.shp" ) );
QVERIFY( def->checkValueIsAcceptable( "" ) );
QVERIFY( def->checkValueIsAcceptable( QVariant() ) );
QVERIFY( def->checkValueIsAcceptable( QgsProcessingFeatureSink( "layer1231123" ) ) );
}

void TestQgsProcessing::checkParamValues()
Expand Down

0 comments on commit 5b9d925

Please sign in to comment.