Skip to content

Commit

Permalink
[processing] Fix missing vector inputs when run in batch mode
Browse files Browse the repository at this point in the history
Fix incorrect definition of compatibleVectorLayers, which was
using layer WKB type values instead of processing source types.
  • Loading branch information
nyalldawson committed Jun 1, 2018
1 parent d1bcfbf commit f6416a1
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,15 @@ value.
%End

static QList< QgsVectorLayer * > compatibleVectorLayers( QgsProject *project,
const QList< QgsWkbTypes::GeometryType > &geometryTypes = QList< QgsWkbTypes::GeometryType >(),
const QList< int > &sourceTypes = QList< int >(),
bool sort = true );
%Docstring
Returns a list of vector layers from a ``project`` which are compatible with the processing
framework.

If the ``geometryTypes`` list is non-empty then the layers will be sorted so that only
layers with geometry types included in the list will be returned. Leaving the ``geometryTypes``
The ``sourceTypes`` list should be filled with a list of QgsProcessing.SourceType values.
If the ``sourceTypes`` list is non-empty then the layers will be sorted so that only
layers with the specified source type included in the list will be returned. Leaving the ``sourceTypes``
list empty will cause all vector layers, regardless of their geometry type, to be returned.

If the ``sort`` argument is true then the layers will be sorted by their :py:func:`QgsMapLayer.name()`
Expand Down
1 change: 0 additions & 1 deletion src/core/processing/qgsprocessing.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

#include "qgis_core.h"
#include "qgis.h"
#include "qgsprocessingparameters.h"

//
// Output definitions
Expand Down
2 changes: 1 addition & 1 deletion src/core/processing/qgsprocessingalgorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
#include "qgsprocessingparameters.h"
#include "qgsprocessingoutputs.h"
#include "qgsprocessingcontext.h"
#include "qgsprocessingutils.h"
#include "qgsfeaturesource.h"
#include "qgsprocessingutils.h"
#include <QString>
#include <QVariant>
#include <QIcon>
Expand Down
18 changes: 13 additions & 5 deletions src/core/processing/qgsprocessingutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ QList<QgsRasterLayer *> QgsProcessingUtils::compatibleRasterLayers( QgsProject *
return layers;
}

QList<QgsVectorLayer *> QgsProcessingUtils::compatibleVectorLayers( QgsProject *project, const QList<QgsWkbTypes::GeometryType> &geometryTypes, bool sort )
QList<QgsVectorLayer *> QgsProcessingUtils::compatibleVectorLayers( QgsProject *project, const QList<int> &geometryTypes, bool sort )
{
if ( !project )
return QList<QgsVectorLayer *>();
Expand Down Expand Up @@ -81,7 +81,7 @@ QList<QgsMapLayer *> QgsProcessingUtils::compatibleLayers( QgsProject *project,
QList<QgsMapLayer *> layers;
Q_FOREACH ( QgsRasterLayer *rl, compatibleRasterLayers( project, false ) )
layers << rl;
Q_FOREACH ( QgsVectorLayer *vl, compatibleVectorLayers( project, QList< QgsWkbTypes::GeometryType >(), false ) )
Q_FOREACH ( QgsVectorLayer *vl, compatibleVectorLayers( project, QList< int >(), false ) )
layers << vl;

if ( sort )
Expand Down Expand Up @@ -288,10 +288,16 @@ bool QgsProcessingUtils::canUseLayer( const QgsRasterLayer *layer )
return layer && layer->providerType() == QStringLiteral( "gdal" );
}

bool QgsProcessingUtils::canUseLayer( const QgsVectorLayer *layer, const QList<QgsWkbTypes::GeometryType> &geometryTypes )
bool QgsProcessingUtils::canUseLayer( const QgsVectorLayer *layer, const QList<int> &sourceTypes )
{
return layer &&
( geometryTypes.isEmpty() || geometryTypes.contains( layer->geometryType() ) );
( sourceTypes.isEmpty()
|| ( sourceTypes.contains( QgsProcessing::TypeVectorPoint ) && layer->geometryType() == QgsWkbTypes::PointGeometry )
|| ( sourceTypes.contains( QgsProcessing::TypeVectorLine ) && layer->geometryType() == QgsWkbTypes::LineGeometry )
|| ( sourceTypes.contains( QgsProcessing::TypeVectorPolygon ) && layer->geometryType() == QgsWkbTypes::PolygonGeometry )
|| ( sourceTypes.contains( QgsProcessing::TypeVectorAnyGeometry ) && layer->isSpatial() )
|| sourceTypes.contains( QgsProcessing::TypeVector )
);
}

QString QgsProcessingUtils::normalizeLayerSource( const QString &source )
Expand Down Expand Up @@ -330,7 +336,7 @@ void QgsProcessingUtils::parseDestinationString( QString &destination, QString &
if ( !dsUri.table().isEmpty() )
{
layerName = dsUri.table();
options.insert( "layerName", layerName );
options.insert( QStringLiteral( "layerName" ), layerName );
}
uri = dsUri.database();
}
Expand Down Expand Up @@ -654,6 +660,7 @@ QList<int> QgsProcessingUtils::fieldNamesToIndices( const QStringList &fieldName
QList<int> indices;
if ( !fieldNames.isEmpty() )
{
indices.reserve( fieldNames.count() );
for ( const QString &f : fieldNames )
{
int idx = fields.lookupField( f );
Expand All @@ -663,6 +670,7 @@ QList<int> QgsProcessingUtils::fieldNamesToIndices( const QStringList &fieldName
}
else
{
indices.reserve( fields.count() );
for ( int i = 0; i < fields.count(); ++i )
indices.append( i );
}
Expand Down
10 changes: 6 additions & 4 deletions src/core/processing/qgsprocessingutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "qgsvectorlayer.h"
#include "qgsmessagelog.h"
#include "qgsspatialindex.h"
#include "qgsprocessing.h"

class QgsProject;
class QgsProcessingContext;
Expand Down Expand Up @@ -60,8 +61,9 @@ class CORE_EXPORT QgsProcessingUtils
* Returns a list of vector layers from a \a project which are compatible with the processing
* framework.
*
* If the \a geometryTypes list is non-empty then the layers will be sorted so that only
* layers with geometry types included in the list will be returned. Leaving the \a geometryTypes
* The \a sourceTypes list should be filled with a list of QgsProcessing::SourceType values.
* If the \a sourceTypes list is non-empty then the layers will be sorted so that only
* layers with the specified source type included in the list will be returned. Leaving the \a sourceTypes
* list empty will cause all vector layers, regardless of their geometry type, to be returned.
*
* If the \a sort argument is true then the layers will be sorted by their QgsMapLayer::name()
Expand All @@ -70,7 +72,7 @@ class CORE_EXPORT QgsProcessingUtils
* \see compatibleLayers()
*/
static QList< QgsVectorLayer * > compatibleVectorLayers( QgsProject *project,
const QList< QgsWkbTypes::GeometryType > &geometryTypes = QList< QgsWkbTypes::GeometryType >(),
const QList< int > &sourceTypes = QList< int >(),
bool sort = true );

/**
Expand Down Expand Up @@ -251,7 +253,7 @@ class CORE_EXPORT QgsProcessingUtils

static bool canUseLayer( const QgsRasterLayer *layer );
static bool canUseLayer( const QgsVectorLayer *layer,
const QList< QgsWkbTypes::GeometryType > &geometryTypes = QList< QgsWkbTypes::GeometryType >() );
const QList< int > &sourceTypes = QList< int >() );

/**
* Interprets a \a string as a map layer from a store.
Expand Down
21 changes: 16 additions & 5 deletions tests/src/analysis/testqgsprocessing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -693,34 +693,45 @@ void TestQgsProcessing::compatibleLayers()

// unsorted
lIds.clear();
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<QgsWkbTypes::GeometryType>(), false ) )
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<int>(), false ) )
lIds << vl->name();
QCOMPARE( lIds, QStringList() << "V4" << "v1" << "v3" << "vvvv4" );

// point only
lIds.clear();
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<QgsWkbTypes::GeometryType>() << QgsWkbTypes::PointGeometry ) )
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<int>() << QgsProcessing::TypeVectorPoint ) )
lIds << vl->name();
QCOMPARE( lIds, QStringList() << "v1" );

// polygon only
lIds.clear();
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<QgsWkbTypes::GeometryType>() << QgsWkbTypes::PolygonGeometry ) )
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<int>() << QgsProcessing::TypeVectorPolygon ) )
lIds << vl->name();
QCOMPARE( lIds, QStringList() << "V4" );

// line only
lIds.clear();
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<QgsWkbTypes::GeometryType>() << QgsWkbTypes::LineGeometry ) )
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<int>() << QgsProcessing::TypeVectorLine ) )
lIds << vl->name();
QCOMPARE( lIds, QStringList() << "v3" );

// point and line only
lIds.clear();
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<QgsWkbTypes::GeometryType>() << QgsWkbTypes::PointGeometry << QgsWkbTypes::LineGeometry ) )
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<int>() << QgsProcessing::TypeVectorPoint << QgsProcessing::TypeVectorLine ) )
lIds << vl->name();
QCOMPARE( lIds, QStringList() << "v1" << "v3" );

// any vector w geometry
lIds.clear();
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<int>() << QgsProcessing::TypeVectorAnyGeometry ) )
lIds << vl->name();
QCOMPARE( lIds, QStringList() << "v1" << "v3" << "V4" );

// any vector
lIds.clear();
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<int>() << QgsProcessing::TypeVector ) )
lIds << vl->name();
QCOMPARE( lIds, QStringList() << "v1" << "v3" << "V4" << "vvvv4" );

// all layers
QVERIFY( QgsProcessingUtils::compatibleLayers( nullptr ).isEmpty() );
Expand Down

0 comments on commit f6416a1

Please sign in to comment.