[processing] Fix missing vector inputs when run in batch mode

Fix incorrect definition of compatibleVectorLayers, which was
using layer WKB type values instead of processing source types.
This commit is contained in:
Nyall Dawson 2018-06-01 14:20:04 +10:00
parent d1bcfbfef3
commit f6416a1990
6 changed files with 40 additions and 19 deletions

View File

@ -39,14 +39,15 @@ value.
%End %End
static QList< QgsVectorLayer * > compatibleVectorLayers( QgsProject *project, static QList< QgsVectorLayer * > compatibleVectorLayers( QgsProject *project,
const QList< QgsWkbTypes::GeometryType > &geometryTypes = QList< QgsWkbTypes::GeometryType >(), const QList< int > &sourceTypes = QList< int >(),
bool sort = true ); bool sort = true );
%Docstring %Docstring
Returns a list of vector layers from a ``project`` which are compatible with the processing Returns a list of vector layers from a ``project`` which are compatible with the processing
framework. framework.
If the ``geometryTypes`` list is non-empty then the layers will be sorted so that only The ``sourceTypes`` list should be filled with a list of QgsProcessing.SourceType values.
layers with geometry types included in the list will be returned. Leaving the ``geometryTypes`` 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. 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()` If the ``sort`` argument is true then the layers will be sorted by their :py:func:`QgsMapLayer.name()`

View File

@ -20,7 +20,6 @@
#include "qgis_core.h" #include "qgis_core.h"
#include "qgis.h" #include "qgis.h"
#include "qgsprocessingparameters.h"
// //
// Output definitions // Output definitions

View File

@ -23,8 +23,8 @@
#include "qgsprocessingparameters.h" #include "qgsprocessingparameters.h"
#include "qgsprocessingoutputs.h" #include "qgsprocessingoutputs.h"
#include "qgsprocessingcontext.h" #include "qgsprocessingcontext.h"
#include "qgsprocessingutils.h"
#include "qgsfeaturesource.h" #include "qgsfeaturesource.h"
#include "qgsprocessingutils.h"
#include <QString> #include <QString>
#include <QVariant> #include <QVariant>
#include <QIcon> #include <QIcon>

View File

@ -51,7 +51,7 @@ QList<QgsRasterLayer *> QgsProcessingUtils::compatibleRasterLayers( QgsProject *
return layers; 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 ) if ( !project )
return QList<QgsVectorLayer *>(); return QList<QgsVectorLayer *>();
@ -81,7 +81,7 @@ QList<QgsMapLayer *> QgsProcessingUtils::compatibleLayers( QgsProject *project,
QList<QgsMapLayer *> layers; QList<QgsMapLayer *> layers;
Q_FOREACH ( QgsRasterLayer *rl, compatibleRasterLayers( project, false ) ) Q_FOREACH ( QgsRasterLayer *rl, compatibleRasterLayers( project, false ) )
layers << rl; layers << rl;
Q_FOREACH ( QgsVectorLayer *vl, compatibleVectorLayers( project, QList< QgsWkbTypes::GeometryType >(), false ) ) Q_FOREACH ( QgsVectorLayer *vl, compatibleVectorLayers( project, QList< int >(), false ) )
layers << vl; layers << vl;
if ( sort ) if ( sort )
@ -288,10 +288,16 @@ bool QgsProcessingUtils::canUseLayer( const QgsRasterLayer *layer )
return layer && layer->providerType() == QStringLiteral( "gdal" ); 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 && 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 ) QString QgsProcessingUtils::normalizeLayerSource( const QString &source )
@ -330,7 +336,7 @@ void QgsProcessingUtils::parseDestinationString( QString &destination, QString &
if ( !dsUri.table().isEmpty() ) if ( !dsUri.table().isEmpty() )
{ {
layerName = dsUri.table(); layerName = dsUri.table();
options.insert( "layerName", layerName ); options.insert( QStringLiteral( "layerName" ), layerName );
} }
uri = dsUri.database(); uri = dsUri.database();
} }
@ -654,6 +660,7 @@ QList<int> QgsProcessingUtils::fieldNamesToIndices( const QStringList &fieldName
QList<int> indices; QList<int> indices;
if ( !fieldNames.isEmpty() ) if ( !fieldNames.isEmpty() )
{ {
indices.reserve( fieldNames.count() );
for ( const QString &f : fieldNames ) for ( const QString &f : fieldNames )
{ {
int idx = fields.lookupField( f ); int idx = fields.lookupField( f );
@ -663,6 +670,7 @@ QList<int> QgsProcessingUtils::fieldNamesToIndices( const QStringList &fieldName
} }
else else
{ {
indices.reserve( fields.count() );
for ( int i = 0; i < fields.count(); ++i ) for ( int i = 0; i < fields.count(); ++i )
indices.append( i ); indices.append( i );
} }

View File

@ -24,6 +24,7 @@
#include "qgsvectorlayer.h" #include "qgsvectorlayer.h"
#include "qgsmessagelog.h" #include "qgsmessagelog.h"
#include "qgsspatialindex.h" #include "qgsspatialindex.h"
#include "qgsprocessing.h"
class QgsProject; class QgsProject;
class QgsProcessingContext; class QgsProcessingContext;
@ -60,8 +61,9 @@ class CORE_EXPORT QgsProcessingUtils
* Returns a list of vector layers from a \a project which are compatible with the processing * Returns a list of vector layers from a \a project which are compatible with the processing
* framework. * framework.
* *
* If the \a geometryTypes list is non-empty then the layers will be sorted so that only * The \a sourceTypes list should be filled with a list of QgsProcessing::SourceType values.
* layers with geometry types included in the list will be returned. Leaving the \a geometryTypes * 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. * 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() * If the \a sort argument is true then the layers will be sorted by their QgsMapLayer::name()
@ -70,7 +72,7 @@ class CORE_EXPORT QgsProcessingUtils
* \see compatibleLayers() * \see compatibleLayers()
*/ */
static QList< QgsVectorLayer * > compatibleVectorLayers( QgsProject *project, static QList< QgsVectorLayer * > compatibleVectorLayers( QgsProject *project,
const QList< QgsWkbTypes::GeometryType > &geometryTypes = QList< QgsWkbTypes::GeometryType >(), const QList< int > &sourceTypes = QList< int >(),
bool sort = true ); bool sort = true );
/** /**
@ -251,7 +253,7 @@ class CORE_EXPORT QgsProcessingUtils
static bool canUseLayer( const QgsRasterLayer *layer ); static bool canUseLayer( const QgsRasterLayer *layer );
static bool canUseLayer( const QgsVectorLayer *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. * Interprets a \a string as a map layer from a store.

View File

@ -693,34 +693,45 @@ void TestQgsProcessing::compatibleLayers()
// unsorted // unsorted
lIds.clear(); 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(); lIds << vl->name();
QCOMPARE( lIds, QStringList() << "V4" << "v1" << "v3" << "vvvv4" ); QCOMPARE( lIds, QStringList() << "V4" << "v1" << "v3" << "vvvv4" );
// point only // point only
lIds.clear(); 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(); lIds << vl->name();
QCOMPARE( lIds, QStringList() << "v1" ); QCOMPARE( lIds, QStringList() << "v1" );
// polygon only // polygon only
lIds.clear(); 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(); lIds << vl->name();
QCOMPARE( lIds, QStringList() << "V4" ); QCOMPARE( lIds, QStringList() << "V4" );
// line only // line only
lIds.clear(); 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(); lIds << vl->name();
QCOMPARE( lIds, QStringList() << "v3" ); QCOMPARE( lIds, QStringList() << "v3" );
// point and line only // point and line only
lIds.clear(); 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(); lIds << vl->name();
QCOMPARE( lIds, QStringList() << "v1" << "v3" ); 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 // all layers
QVERIFY( QgsProcessingUtils::compatibleLayers( nullptr ).isEmpty() ); QVERIFY( QgsProcessingUtils::compatibleLayers( nullptr ).isEmpty() );