Skip to content

Commit

Permalink
[processing] Allow providers to determine default vector/raster file
Browse files Browse the repository at this point in the history
to use for their algorithm's parameters

Because some providers do not have support for all output types,
we need to give providers a way to restrict the default format
choices to those which are supported by the provider.
  • Loading branch information
nyalldawson committed Nov 6, 2017
1 parent 2a280d6 commit 4ae9241
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 13 deletions.
9 changes: 9 additions & 0 deletions python/core/processing/qgsprocessingparameters.sip
Expand Up @@ -357,9 +357,18 @@ class QgsProcessingParameterDefinition
%Docstring
Returns a pointer to the algorithm which owns this parameter. May be None
for non-owned parameters.
.. seealso:: provider()
:rtype: QgsProcessingAlgorithm
%End

QgsProcessingProvider *provider() const;
%Docstring
Returns a pointer to the provider for the algorithm which owns this parameter. May be None
for non-owned parameters or algorithms.
.. seealso:: algorithm()
:rtype: QgsProcessingProvider
%End

protected:


Expand Down
30 changes: 30 additions & 0 deletions python/core/processing/qgsprocessingprovider.sip
Expand Up @@ -101,6 +101,7 @@ class QgsProcessingProvider : QObject
virtual QStringList supportedOutputVectorLayerExtensions() const;
%Docstring
Returns a list of the vector format file extensions supported by this provider.
.. seealso:: defaultVectorFileExtension()
.. seealso:: supportedOutputRasterLayerExtensions()
.. seealso:: supportedOutputTableExtensions()
.. seealso:: supportsNonFileBasedOutput()
Expand All @@ -115,6 +116,35 @@ class QgsProcessingProvider : QObject
:rtype: list of str
%End

virtual QString defaultVectorFileExtension( bool hasGeometry = true ) const;
%Docstring
Returns the default file extension to use for vector outputs created by the
provider.

If ``hasGeometry`` is true then the output file format must have support for
geometry. If ``hasGeometry`` is false then non-spatial formats can be used.

The default implementation returns the user's default Processing vector output format
setting.

.. seealso:: supportedOutputVectorLayerExtensions()
.. seealso:: defaultRasterFileExtension()
:rtype: str
%End

virtual QString defaultRasterFileExtension() const;
%Docstring
Returns the default file extension to use for raster outputs created by the
provider.

The default implementation returns the user's default Processing raster output format
setting.

.. seealso:: supportedOutputRasterLayerExtensions()
.. seealso:: defaultVectorFileExtension()
:rtype: str
%End

virtual bool supportsNonFileBasedOutput() const;
%Docstring
Returns true if the provider supports non-file based outputs (such as memory layers
Expand Down
48 changes: 38 additions & 10 deletions src/core/processing/qgsprocessingparameters.cpp
Expand Up @@ -16,8 +16,10 @@
***************************************************************************/

#include "qgsprocessingparameters.h"
#include "qgsprocessingprovider.h"
#include "qgsprocessingcontext.h"
#include "qgsprocessingutils.h"
#include "qgsprocessingalgorithm.h"
#include "qgsvectorlayerfeatureiterator.h"
#include "qgsprocessingoutputs.h"
#include "qgssettings.h"
Expand Down Expand Up @@ -1242,6 +1244,11 @@ QgsProcessingAlgorithm *QgsProcessingParameterDefinition::algorithm() const
return mAlgorithm;
}

QgsProcessingProvider *QgsProcessingParameterDefinition::provider() const
{
return mAlgorithm ? mAlgorithm->provider() : nullptr;
}

QgsProcessingParameterBoolean::QgsProcessingParameterBoolean( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
{}
Expand Down Expand Up @@ -3092,14 +3099,21 @@ QgsProcessingOutputDefinition *QgsProcessingParameterFeatureSink::toOutputDefini

QString QgsProcessingParameterFeatureSink::defaultFileExtension() const
{
QgsSettings settings;
if ( hasGeometry() )
if ( QgsProcessingProvider *p = provider() )
{
return settings.value( QStringLiteral( "Processing/DefaultOutputVectorLayerExt" ), QStringLiteral( "shp" ), QgsSettings::Core ).toString();
return p->defaultVectorFileExtension( hasGeometry() );
}
else
{
return QStringLiteral( "dbf" );
QgsSettings settings;
if ( hasGeometry() )
{
return settings.value( QStringLiteral( "Processing/DefaultOutputVectorLayerExt" ), QStringLiteral( "shp" ), QgsSettings::Core ).toString();
}
else
{
return QStringLiteral( "dbf" );
}
}
}

Expand Down Expand Up @@ -3245,8 +3259,15 @@ QgsProcessingOutputDefinition *QgsProcessingParameterRasterDestination::toOutput

QString QgsProcessingParameterRasterDestination::defaultFileExtension() const
{
QgsSettings settings;
return settings.value( QStringLiteral( "Processing/DefaultOutputRasterLayerExt" ), QStringLiteral( "tif" ), QgsSettings::Core ).toString();
if ( QgsProcessingProvider *p = provider() )
{
return p->defaultRasterFileExtension();
}
else
{
QgsSettings settings;
return settings.value( QStringLiteral( "Processing/DefaultOutputRasterLayerExt" ), QStringLiteral( "tif" ), QgsSettings::Core ).toString();
}
}

QgsProcessingParameterRasterDestination *QgsProcessingParameterRasterDestination::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
Expand Down Expand Up @@ -3541,14 +3562,21 @@ QgsProcessingOutputDefinition *QgsProcessingParameterVectorDestination::toOutput

QString QgsProcessingParameterVectorDestination::defaultFileExtension() const
{
QgsSettings settings;
if ( hasGeometry() )
if ( QgsProcessingProvider *p = provider() )
{
return settings.value( QStringLiteral( "Processing/DefaultOutputVectorLayerExt" ), QStringLiteral( "shp" ), QgsSettings::Core ).toString();
return p->defaultVectorFileExtension( hasGeometry() );
}
else
{
return QStringLiteral( "dbf" );
QgsSettings settings;
if ( hasGeometry() )
{
return settings.value( QStringLiteral( "Processing/DefaultOutputVectorLayerExt" ), QStringLiteral( "shp" ), QgsSettings::Core ).toString();
}
else
{
return QStringLiteral( "dbf" );
}
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/core/processing/qgsprocessingparameters.h
Expand Up @@ -34,6 +34,7 @@ class QgsFeatureSink;
class QgsProcessingFeatureSource;
class QgsProcessingOutputDefinition;
class QgsProcessingFeedback;
class QgsProcessingProvider;

/**
* \class QgsProcessingFeatureSourceDefinition
Expand Down Expand Up @@ -394,9 +395,17 @@ class CORE_EXPORT QgsProcessingParameterDefinition
/**
* Returns a pointer to the algorithm which owns this parameter. May be nullptr
* for non-owned parameters.
* \see provider()
*/
QgsProcessingAlgorithm *algorithm() const;

/**
* Returns a pointer to the provider for the algorithm which owns this parameter. May be nullptr
* for non-owned parameters or algorithms.
* \see algorithm()
*/
QgsProcessingProvider *provider() const;

protected:

//! Parameter name
Expand Down
20 changes: 20 additions & 0 deletions src/core/processing/qgsprocessingprovider.cpp
Expand Up @@ -18,6 +18,7 @@
#include "qgsprocessingprovider.h"
#include "qgsapplication.h"
#include "qgsvectorfilewriter.h"
#include "qgssettings.h"

QgsProcessingProvider::QgsProcessingProvider( QObject *parent SIP_TRANSFERTHIS )
: QObject( parent )
Expand Down Expand Up @@ -84,3 +85,22 @@ QStringList QgsProcessingProvider::supportedOutputVectorLayerExtensions() const
return QgsVectorFileWriter::supportedFormatExtensions();
}

QString QgsProcessingProvider::defaultVectorFileExtension( bool hasGeometry ) const
{
QgsSettings settings;
if ( hasGeometry )
{
return settings.value( QStringLiteral( "Processing/DefaultOutputVectorLayerExt" ), QStringLiteral( "shp" ), QgsSettings::Core ).toString();
}
else
{
return QStringLiteral( "dbf" );
}
}

QString QgsProcessingProvider::defaultRasterFileExtension() const
{
QgsSettings settings;
return settings.value( QStringLiteral( "Processing/DefaultOutputRasterLayerExt" ), QStringLiteral( "tif" ), QgsSettings::Core ).toString();
}

28 changes: 28 additions & 0 deletions src/core/processing/qgsprocessingprovider.h
Expand Up @@ -110,6 +110,7 @@ class CORE_EXPORT QgsProcessingProvider : public QObject

/**
* Returns a list of the vector format file extensions supported by this provider.
* \see defaultVectorFileExtension()
* \see supportedOutputRasterLayerExtensions()
* \see supportedOutputTableExtensions()
* \see supportsNonFileBasedOutput()
Expand All @@ -123,6 +124,33 @@ class CORE_EXPORT QgsProcessingProvider : public QObject
*/
virtual QStringList supportedOutputTableExtensions() const { return QStringList() << QStringLiteral( "csv" ); }

/**
* Returns the default file extension to use for vector outputs created by the
* provider.
*
* If \a hasGeometry is true then the output file format must have support for
* geometry. If \a hasGeometry is false then non-spatial formats can be used.
*
* The default implementation returns the user's default Processing vector output format
* setting.
*
* \see supportedOutputVectorLayerExtensions()
* \see defaultRasterFileExtension()
*/
virtual QString defaultVectorFileExtension( bool hasGeometry = true ) const;

/**
* Returns the default file extension to use for raster outputs created by the
* provider.
*
* The default implementation returns the user's default Processing raster output format
* setting.
*
* \see supportedOutputRasterLayerExtensions()
* \see defaultVectorFileExtension()
*/
virtual QString defaultRasterFileExtension() const;

/**
* Returns true if the provider supports non-file based outputs (such as memory layers
* or direct database outputs).
Expand Down
55 changes: 52 additions & 3 deletions tests/src/analysis/testqgsprocessing.cpp
Expand Up @@ -130,6 +130,41 @@ class DummyAlgorithm : public QgsProcessingAlgorithm
QgsProcessingParameterVectorDestination *p8 = new QgsProcessingParameterVectorDestination( "p8" );
// this should fail - it would result in a duplicate output name
QVERIFY( !addParameter( p8 ) );

// default vector format extension
QgsProcessingParameterFeatureSink *sinkParam = new QgsProcessingParameterFeatureSink( "sink" );
QCOMPARE( sinkParam->defaultFileExtension(), QStringLiteral( "shp" ) ); // before alg is accessible
QVERIFY( !sinkParam->algorithm() );
QVERIFY( !sinkParam->provider() );
addParameter( sinkParam );
QCOMPARE( sinkParam->defaultFileExtension(), QStringLiteral( "shp" ) );
QCOMPARE( sinkParam->algorithm(), this );
QVERIFY( !sinkParam->provider() );

// default raster format extension
QgsProcessingParameterRasterDestination *rasterParam = new QgsProcessingParameterRasterDestination( "raster" );
QCOMPARE( rasterParam->defaultFileExtension(), QStringLiteral( "tif" ) ); // before alg is accessible
addParameter( rasterParam );
QCOMPARE( rasterParam->defaultFileExtension(), QStringLiteral( "tif" ) );
}

void runParameterChecks2()
{
// default vector format extension, taken from provider
QgsProcessingParameterFeatureSink *sinkParam = new QgsProcessingParameterFeatureSink( "sink2" );
QCOMPARE( sinkParam->defaultFileExtension(), QStringLiteral( "shp" ) ); // before alg is accessible
QVERIFY( !sinkParam->algorithm() );
QVERIFY( !sinkParam->provider() );
addParameter( sinkParam );
QCOMPARE( sinkParam->defaultFileExtension(), QStringLiteral( "xshp" ) );
QCOMPARE( sinkParam->algorithm(), this );
QCOMPARE( sinkParam->provider(), provider() );

// default raster format extension
QgsProcessingParameterRasterDestination *rasterParam = new QgsProcessingParameterRasterDestination( "raster2" );
QCOMPARE( rasterParam->defaultFileExtension(), QStringLiteral( "tif" ) ); // before alg is accessible
addParameter( rasterParam );
QCOMPARE( rasterParam->defaultFileExtension(), QStringLiteral( "pcx" ) );
}

void runOutputChecks()
Expand Down Expand Up @@ -254,6 +289,16 @@ class DummyProvider : public QgsProcessingProvider

void unload() override { if ( unloaded ) { *unloaded = true; } }

QString defaultVectorFileExtension( bool ) const override
{
return "xshp"; // shape-X. Just like shapefiles, but to the max!
}

QString defaultRasterFileExtension() const override
{
return "pcx"; // next-gen raster storage
}

bool *unloaded = nullptr;

protected:
Expand All @@ -273,7 +318,7 @@ class DummyProvider : public QgsProcessingProvider

QString mId;


friend class TestQgsProcessing;
};

class DummyProviderNoLoad : public DummyProvider
Expand Down Expand Up @@ -1419,8 +1464,12 @@ void TestQgsProcessing::parameters()

void TestQgsProcessing::algorithmParameters()
{
DummyAlgorithm alg( "test" );
alg.runParameterChecks();
DummyAlgorithm *alg = new DummyAlgorithm( "test" );
DummyProvider p( "test" );
alg->runParameterChecks();

p.addAlgorithm( alg );
alg->runParameterChecks2();
}

void TestQgsProcessing::algorithmOutputs()
Expand Down

0 comments on commit 4ae9241

Please sign in to comment.