Skip to content

Commit

Permalink
[processing] Add method for providers to specify a different list
Browse files Browse the repository at this point in the history
of supported output formats when an output has no geometry
  • Loading branch information
nyalldawson committed Dec 3, 2018
1 parent 583b602 commit 4bca783
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 24 deletions.
20 changes: 20 additions & 0 deletions python/core/auto_generated/processing/qgsprocessingprovider.sip.in
Expand Up @@ -113,11 +113,31 @@ Returns a list of the raster format file extensions supported by this provider.
%Docstring
Returns a list of the vector format file extensions supported by this provider.

.. seealso:: :py:func:`supportedOutputTableExtensions`

.. seealso:: :py:func:`defaultVectorFileExtension`

.. seealso:: :py:func:`supportedOutputRasterLayerExtensions`

.. seealso:: :py:func:`supportsNonFileBasedOutput`
%End

virtual QStringList supportedOutputTableExtensions() const;
%Docstring
Returns a list of the table (geometry-less vector layers) file extensions supported by this provider.

By default this is the same as supportedOutputVectorLayerExtensions(). Providers which utilize different
formats for geometry-less layers can override this method to return a different list of supported formats.

.. seealso:: :py:func:`supportedOutputVectorLayerExtensions`

.. seealso:: :py:func:`defaultVectorFileExtension`

.. seealso:: :py:func:`supportedOutputRasterLayerExtensions`

.. seealso:: :py:func:`supportsNonFileBasedOutput`

.. versionadded:: 3.4.3
%End

virtual QString defaultVectorFileExtension( bool hasGeometry = true ) const;
Expand Down
20 changes: 16 additions & 4 deletions src/core/processing/qgsprocessingparameters.cpp
Expand Up @@ -3728,11 +3728,17 @@ QStringList QgsProcessingParameterFeatureSink::supportedOutputVectorLayerExtensi
{
if ( originalProvider() )
{
return originalProvider()->supportedOutputVectorLayerExtensions();
if ( hasGeometry() )
return originalProvider()->supportedOutputVectorLayerExtensions();
else
return originalProvider()->supportedOutputTableExtensions();
}
else if ( QgsProcessingProvider *p = provider() )
{
return p->supportedOutputVectorLayerExtensions();
if ( hasGeometry() )
return p->supportedOutputVectorLayerExtensions();
else
return p->supportedOutputTableExtensions();
}
else
{
Expand Down Expand Up @@ -4288,11 +4294,17 @@ QStringList QgsProcessingParameterVectorDestination::supportedOutputVectorLayerE
{
if ( originalProvider() )
{
return originalProvider()->supportedOutputVectorLayerExtensions();
if ( hasGeometry() )
return originalProvider()->supportedOutputVectorLayerExtensions();
else
return originalProvider()->supportedOutputTableExtensions();
}
else if ( QgsProcessingProvider *p = provider() )
{
return p->supportedOutputVectorLayerExtensions();
if ( hasGeometry() )
return p->supportedOutputVectorLayerExtensions();
else
return p->supportedOutputTableExtensions();
}
else
{
Expand Down
5 changes: 5 additions & 0 deletions src/core/processing/qgsprocessingprovider.cpp
Expand Up @@ -102,6 +102,11 @@ QStringList QgsProcessingProvider::supportedOutputVectorLayerExtensions() const
return QgsVectorFileWriter::supportedFormatExtensions();
}

QStringList QgsProcessingProvider::supportedOutputTableExtensions() const
{
return supportedOutputVectorLayerExtensions();
}

QString QgsProcessingProvider::defaultVectorFileExtension( bool hasGeometry ) const
{
QgsSettings settings;
Expand Down
16 changes: 16 additions & 0 deletions src/core/processing/qgsprocessingprovider.h
Expand Up @@ -118,12 +118,28 @@ class CORE_EXPORT QgsProcessingProvider : public QObject

/**
* Returns a list of the vector format file extensions supported by this provider.
* \see supportedOutputTableExtensions()
* \see defaultVectorFileExtension()
* \see supportedOutputRasterLayerExtensions()
* \see supportsNonFileBasedOutput()
*/
virtual QStringList supportedOutputVectorLayerExtensions() const;

/**
* Returns a list of the table (geometry-less vector layers) file extensions supported by this provider.
*
* By default this is the same as supportedOutputVectorLayerExtensions(). Providers which utilize different
* formats for geometry-less layers can override this method to return a different list of supported formats.
*
* \see supportedOutputVectorLayerExtensions()
* \see defaultVectorFileExtension()
* \see supportedOutputRasterLayerExtensions()
* \see supportsNonFileBasedOutput()
*
* \since QGIS 3.4.3
*/
virtual QStringList supportedOutputTableExtensions() const;

/**
* Returns the default file extension to use for vector outputs created by the
* provider.
Expand Down
110 changes: 90 additions & 20 deletions tests/src/analysis/testqgsprocessing.cpp
Expand Up @@ -385,27 +385,7 @@ class DummyProviderNoLoad : public DummyProvider

};

class DummyProvider3 : public QgsProcessingProvider
{
public:

DummyProvider3() = default;
QString id() const override { return QStringLiteral( "dummy3" ); }
QString name() const override { return QStringLiteral( "dummy3" ); }

QStringList supportedOutputVectorLayerExtensions() const override
{
return QStringList() << QStringLiteral( "mif" ) << QStringLiteral( "tab" );
}

QStringList supportedOutputRasterLayerExtensions() const override
{
return QStringList() << QStringLiteral( "mig" ) << QStringLiteral( "asc" );
}

void loadAlgorithms() override {}

};

class DummyAlgorithm2 : public QgsProcessingAlgorithm
{
Expand Down Expand Up @@ -433,6 +413,36 @@ class DummyAlgorithm2 : public QgsProcessingAlgorithm
};


class DummyProvider3 : public QgsProcessingProvider
{
public:

DummyProvider3() = default;
QString id() const override { return QStringLiteral( "dummy3" ); }
QString name() const override { return QStringLiteral( "dummy3" ); }

QStringList supportedOutputVectorLayerExtensions() const override
{
return QStringList() << QStringLiteral( "mif" ) << QStringLiteral( "tab" );
}

QStringList supportedOutputTableExtensions() const override
{
return QStringList() << QStringLiteral( "dbf" );
}

QStringList supportedOutputRasterLayerExtensions() const override
{
return QStringList() << QStringLiteral( "mig" ) << QStringLiteral( "asc" );
}

void loadAlgorithms() override
{
QVERIFY( addAlgorithm( new DummyAlgorithm2( "alg1" ) ) );
}

};

class DummyProvider4 : public QgsProcessingProvider
{
public:
Expand Down Expand Up @@ -564,6 +574,7 @@ class TestQgsProcessing: public QObject
void indicesToFields();
void stringToPythonLiteral();
void defaultExtensionsForProvider();
void supportedExtensions();
void supportsNonFileBasedOutput();
void addParameterType();
void removeParameterType();
Expand Down Expand Up @@ -4678,6 +4689,30 @@ void TestQgsProcessing::parameterFeatureSink()
QCOMPARE( QgsProcessingAlgorithm::invalidSinkError( params, QStringLiteral( "OUTPUT" ) ), QStringLiteral( "Could not create destination layer for OUTPUT: d:/test3.shp" ) );
params.insert( QStringLiteral( "OUTPUT" ), QgsProcessingFeatureSourceDefinition( QStringLiteral( "source" ) ) );
QCOMPARE( QgsProcessingAlgorithm::invalidSinkError( params, QStringLiteral( "OUTPUT" ) ), QStringLiteral( "Could not create destination layer for OUTPUT: invalid value" ) );

// test supported output vector layer extensions

def.reset( new QgsProcessingParameterFeatureSink( "with_geom", QString(), QgsProcessing::TypeVectorAnyGeometry, QString(), true ) );
DummyProvider3 provider;
provider.loadAlgorithms();
def->mOriginalProvider = &provider;
QCOMPARE( def->supportedOutputVectorLayerExtensions().count(), 2 );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "mif" ) );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 1 ), QStringLiteral( "tab" ) );
def->mOriginalProvider = nullptr;
def->mAlgorithm = const_cast< QgsProcessingAlgorithm * >( provider.algorithms().at( 0 ) );
QCOMPARE( def->supportedOutputVectorLayerExtensions().count(), 2 );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "mif" ) );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 1 ), QStringLiteral( "tab" ) );

def.reset( new QgsProcessingParameterFeatureSink( "no_geom", QString(), QgsProcessing::TypeVector, QString(), true ) );
def->mOriginalProvider = &provider;
QCOMPARE( def->supportedOutputVectorLayerExtensions().count(), 1 );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "dbf" ) );
def->mOriginalProvider = nullptr;
def->mAlgorithm = const_cast< QgsProcessingAlgorithm * >( provider.algorithms().at( 0 ) );
QCOMPARE( def->supportedOutputVectorLayerExtensions().count(), 1 );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "dbf" ) );
}

void TestQgsProcessing::parameterVectorOut()
Expand Down Expand Up @@ -4811,6 +4846,30 @@ void TestQgsProcessing::parameterVectorOut()
QCOMPARE( context2.layersToLoadOnCompletion().values().at( 0 ).name, QStringLiteral( "my_dest" ) );
QCOMPARE( context2.layersToLoadOnCompletion().values().at( 0 ).outputName, QStringLiteral( "x" ) );
QCOMPARE( context2.layersToLoadOnCompletion().values().at( 0 ).layerTypeHint, QgsProcessingUtils::Vector );

// test supported output vector layer extensions

def.reset( new QgsProcessingParameterVectorDestination( "with_geom", QString(), QgsProcessing::TypeVectorAnyGeometry, QString(), true ) );
DummyProvider3 provider;
provider.loadAlgorithms();
def->mOriginalProvider = &provider;
QCOMPARE( def->supportedOutputVectorLayerExtensions().count(), 2 );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "mif" ) );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 1 ), QStringLiteral( "tab" ) );
def->mOriginalProvider = nullptr;
def->mAlgorithm = const_cast< QgsProcessingAlgorithm * >( provider.algorithms().at( 0 ) );
QCOMPARE( def->supportedOutputVectorLayerExtensions().count(), 2 );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "mif" ) );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 1 ), QStringLiteral( "tab" ) );

def.reset( new QgsProcessingParameterVectorDestination( "no_geom", QString(), QgsProcessing::TypeVector, QString(), true ) );
def->mOriginalProvider = &provider;
QCOMPARE( def->supportedOutputVectorLayerExtensions().count(), 1 );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "dbf" ) );
def->mOriginalProvider = nullptr;
def->mAlgorithm = const_cast< QgsProcessingAlgorithm * >( provider.algorithms().at( 0 ) );
QCOMPARE( def->supportedOutputVectorLayerExtensions().count(), 1 );
QCOMPARE( def->supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "dbf" ) );
}

void TestQgsProcessing::parameterRasterOut()
Expand Down Expand Up @@ -6971,6 +7030,17 @@ void TestQgsProcessing::defaultExtensionsForProvider()
QCOMPARE( provider.defaultRasterFileExtension(), QStringLiteral( "mig" ) );
}

void TestQgsProcessing::supportedExtensions()
{
DummyProvider4 provider;
QCOMPARE( provider.supportedOutputVectorLayerExtensions().count(), 1 );
QCOMPARE( provider.supportedOutputVectorLayerExtensions().at( 0 ), QStringLiteral( "mif" ) );

// if supportedOutputTableExtensions is not implemented, supportedOutputVectorLayerExtensions should be used instead
QCOMPARE( provider.supportedOutputTableExtensions().count(), 1 );
QCOMPARE( provider.supportedOutputTableExtensions().at( 0 ), QStringLiteral( "mif" ) );
}

void TestQgsProcessing::supportsNonFileBasedOutput()
{
DummyAlgorithm alg( QStringLiteral( "test" ) );
Expand Down
Binary file modified tests/testdata/points_gpkg.gpkg
Binary file not shown.

0 comments on commit 4bca783

Please sign in to comment.