[processing] Start porting Aggregates parameters to C++

Port parameter type to c++
This commit is contained in:
Nyall Dawson 2020-06-02 16:12:14 +10:00
parent 2f36e18d11
commit 4fdfa949cf
8 changed files with 427 additions and 44 deletions

View File

@ -0,0 +1,109 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/processing/qgsprocessingparameteraggregate.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsProcessingParameterAggregate : QgsProcessingParameterDefinition
{
%Docstring
A parameter for "aggregate" configurations, which consist of a definition
of desired output fields, types, and aggregate used to populate then.
Designed for use with the "Aggregate" algorithm.
.. versionadded:: 3.14
%End
%TypeHeaderCode
#include "qgsprocessingparameteraggregate.h"
%End
public:
QgsProcessingParameterAggregate( const QString &name, const QString &description = QString(), const QString &parentLayerParameterName = QString(), bool optional = false );
%Docstring
Constructor for QgsProcessingParameterAggregate.
%End
virtual QgsProcessingParameterDefinition *clone() const;
virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
virtual QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const;
virtual QString asPythonString( QgsProcessing::PythonOutputType outputType = QgsProcessing::PythonQgsProcessingAlgorithmSubclass ) const;
virtual QVariantMap toVariantMap() const;
virtual bool fromVariantMap( const QVariantMap &map );
virtual QStringList dependsOnOtherParameters() const;
static QString typeName();
%Docstring
Returns the type name for the parameter class.
%End
QString parentLayerParameterName() const;
%Docstring
Returns the name of the parent layer parameter, or an empty string if this is not set.
.. seealso:: :py:func:`setParentLayerParameterName`
%End
void setParentLayerParameterName( const QString &name );
%Docstring
Sets the ``name`` of the parent layer parameter. Use an empty string if this is not required.
.. seealso:: :py:func:`parentLayerParameterName`
%End
};
class QgsProcessingParameterTypeAggregate : QgsProcessingParameterType
{
%Docstring
Parameter type definition for QgsProcessingParameterAggregate.
.. note::
This class is not a part of public API.
.. versionadded:: 3.14
%End
%TypeHeaderCode
#include "qgsprocessingparameteraggregate.h"
%End
public:
virtual QgsProcessingParameterDefinition *create( const QString &name ) const /Factory/;
virtual QString description() const;
virtual QString name() const;
virtual QString id() const;
virtual QString pythonImportString() const;
virtual QString className() const;
virtual QStringList acceptedPythonTypes() const;
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/processing/qgsprocessingparameteraggregate.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -451,6 +451,7 @@
%Include auto_generated/processing/qgsprocessingcontext.sip
%Include auto_generated/processing/qgsprocessingfeedback.sip
%Include auto_generated/processing/qgsprocessingoutputs.sip
%Include auto_generated/processing/qgsprocessingparameteraggregate.sip
%Include auto_generated/processing/qgsprocessingparameterfieldmap.sip
%Include auto_generated/processing/qgsprocessingparameters.sip
%Include auto_generated/processing/qgsprocessingparametertype.sip

View File

@ -35,6 +35,7 @@ from qgis.core import (
QgsProcessingParameterExpression,
QgsProcessingParameterFeatureSink,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterAggregate,
QgsProcessingException,
QgsProcessingUtils,
QgsWkbTypes,
@ -72,50 +73,8 @@ class Aggregate(QgisAlgorithm):
optional=False,
parentLayerParameterName=self.INPUT))
class ParameterAggregates(QgsProcessingParameterDefinition):
def __init__(self, name, description, parentLayerParameterName='INPUT'):
super().__init__(name, description)
self._parentLayerParameter = parentLayerParameterName
def clone(self):
copy = ParameterAggregates(self.name(), self.description(), self._parentLayerParameter)
return copy
def type(self):
return 'aggregates'
def checkValueIsAcceptable(self, value, context=None):
if not isinstance(value, list):
return False
for field_def in value:
if not isinstance(field_def, dict):
return False
if not field_def.get('input', False):
return False
if not field_def.get('aggregate', False):
return False
if not field_def.get('name', False):
return False
if not field_def.get('type', False):
return False
return True
def valueAsPythonString(self, value, context):
return str(value)
def asScriptCode(self):
raise NotImplementedError()
@classmethod
def fromScriptCode(cls, name, description, isOptional, definition):
raise NotImplementedError()
def parentLayerParameter(self):
return self._parentLayerParameter
self.addParameter(ParameterAggregates(self.AGGREGATES,
description=self.tr('Aggregates')))
self.addParameter(QgsProcessingParameterAggregate(self.AGGREGATES,
description=self.tr('Aggregates'), parentLayerParameterName='INPUT'))
self.parameterDefinition(self.AGGREGATES).setMetadata({
'widget_wrapper': 'processing.algs.qgis.ui.AggregatesPanel.AggregatesWidgetWrapper'
})

View File

@ -147,6 +147,7 @@ SET(QGIS_CORE_SRCS
processing/qgsprocessingcontext.cpp
processing/qgsprocessingfeedback.cpp
processing/qgsprocessingoutputs.cpp
processing/qgsprocessingparameteraggregate.cpp
processing/qgsprocessingparameterfieldmap.cpp
processing/qgsprocessingparameters.cpp
processing/qgsprocessingparametertype.cpp
@ -1270,6 +1271,7 @@ SET(QGIS_CORE_HDRS
processing/qgsprocessingcontext.h
processing/qgsprocessingfeedback.h
processing/qgsprocessingoutputs.h
processing/qgsprocessingparameteraggregate.h
processing/qgsprocessingparameterfieldmap.h
processing/qgsprocessingparameters.h
processing/qgsprocessingparametertype.h

View File

@ -0,0 +1,121 @@
/***************************************************************************
qgsprocessingparameteraggregate.cpp
-------------------------
begin : June 2020
copyright : (C) 2020 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsprocessingparameteraggregate.h"
#include "qgsvectorlayer.h"
QgsProcessingParameterAggregate::QgsProcessingParameterAggregate( const QString &name, const QString &description, const QString &parentLayerParameterName, bool optional )
: QgsProcessingParameterDefinition( name, description, QVariant(), optional )
, mParentLayerParameterName( parentLayerParameterName )
{
}
QgsProcessingParameterDefinition *QgsProcessingParameterAggregate::clone() const
{
return new QgsProcessingParameterAggregate( *this );
}
QString QgsProcessingParameterAggregate::type() const
{
return typeName();
}
bool QgsProcessingParameterAggregate::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
if ( !input.isValid() )
return mFlags & FlagOptional;
if ( input.type() != QVariant::List )
return false;
const QVariantList inputList = input.toList();
for ( const QVariant &inputItem : inputList )
{
if ( inputItem.type() != QVariant::Map )
return false;
const QVariantMap inputItemMap = inputItem.toMap();
if ( !inputItemMap.contains( "name" ) )
return false;
if ( !inputItemMap.contains( "type" ) )
return false;
if ( !inputItemMap.contains( "input" ) )
return false;
if ( !inputItemMap.contains( "aggregate" ) )
return false;
}
return true;
}
QString QgsProcessingParameterAggregate::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
{
return QgsProcessingUtils::variantToPythonLiteral( value );
}
QString QgsProcessingParameterAggregate::asPythonString( QgsProcessing::PythonOutputType outputType ) const
{
switch ( outputType )
{
case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
{
QString code = QStringLiteral( "QgsProcessingParameterAggregate('%1', '%2'" ).arg( name(), description() );
if ( !mParentLayerParameterName.isEmpty() )
code += QStringLiteral( ", parentLayerParameterName=%1" ).arg( QgsProcessingUtils::stringToPythonLiteral( mParentLayerParameterName ) );
if ( mFlags & FlagOptional )
code += QStringLiteral( ", optional=True" );
code += ')';
return code;
}
}
return QString();
}
QVariantMap QgsProcessingParameterAggregate::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameterName );
return map;
}
bool QgsProcessingParameterAggregate::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mParentLayerParameterName = map.value( QStringLiteral( "parent_layer" ) ).toString();
return true;
}
QStringList QgsProcessingParameterAggregate::dependsOnOtherParameters() const
{
QStringList depends;
if ( !mParentLayerParameterName.isEmpty() )
depends << mParentLayerParameterName;
return depends;
}
QString QgsProcessingParameterAggregate::parentLayerParameterName() const
{
return mParentLayerParameterName;
}
void QgsProcessingParameterAggregate::setParentLayerParameterName( const QString &name )
{
mParentLayerParameterName = name;
}

View File

@ -0,0 +1,117 @@
/***************************************************************************
qgsprocessingparameteraggregate.h
-------------------------
begin : June 2020
copyright : (C) 2020 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSPROCESSINGPARAMETERAGGREGATE_H
#define QGSPROCESSINGPARAMETERAGGREGATE_H
#include "qgsprocessingparameters.h"
#include "qgsprocessingparametertype.h"
/**
* \ingroup core
* A parameter for "aggregate" configurations, which consist of a definition
* of desired output fields, types, and aggregate used to populate then.
*
* Designed for use with the "Aggregate" algorithm.
*
* \since QGIS 3.14
*/
class CORE_EXPORT QgsProcessingParameterAggregate : public QgsProcessingParameterDefinition
{
public:
//! Constructor for QgsProcessingParameterAggregate.
QgsProcessingParameterAggregate( const QString &name, const QString &description = QString(), const QString &parentLayerParameterName = QString(), bool optional = false );
QgsProcessingParameterDefinition *clone() const override;
QString type() const override;
bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = nullptr ) const override;
QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const override;
QString asPythonString( QgsProcessing::PythonOutputType outputType = QgsProcessing::PythonQgsProcessingAlgorithmSubclass ) const override;
QVariantMap toVariantMap() const override;
bool fromVariantMap( const QVariantMap &map ) override;
QStringList dependsOnOtherParameters() const override;
//! Returns the type name for the parameter class.
static QString typeName() { return QStringLiteral( "aggregates" ); }
/**
* Returns the name of the parent layer parameter, or an empty string if this is not set.
* \see setParentLayerParameterName()
*/
QString parentLayerParameterName() const;
/**
* Sets the \a name of the parent layer parameter. Use an empty string if this is not required.
* \see parentLayerParameterName()
*/
void setParentLayerParameterName( const QString &name );
private:
QString mParentLayerParameterName;
};
///@cond PRIVATE
/**
* Parameter type definition for QgsProcessingParameterAggregate.
*
* \ingroup core
* \note This class is not a part of public API.
* \since QGIS 3.14
*/
class CORE_EXPORT QgsProcessingParameterTypeAggregate : public QgsProcessingParameterType
{
public:
QgsProcessingParameterDefinition *create( const QString &name ) const override SIP_FACTORY
{
return new QgsProcessingParameterAggregate( name );
}
QString description() const override
{
return QCoreApplication::translate( "Processing", "A mapping of field names and aggregate type. Used for the Aggregate algorithm." );
}
QString name() const override
{
return QCoreApplication::translate( "Processing", "Field Aggregates" );
}
QString id() const override
{
return QgsProcessingParameterAggregate::typeName();
}
QString pythonImportString() const override
{
return QStringLiteral( "from qgis.core import QgsProcessingParameterAggregate" );
}
QString className() const override
{
return QStringLiteral( "QgsProcessingParameterAggregate" );
}
QStringList acceptedPythonTypes() const override
{
return QStringList() << QObject::tr( "list[dict]: list of aggregate definitions as dictionaries" );
}
};
///@endcond
#endif // QGSPROCESSINGPARAMETERAGGREGATE_H

View File

@ -20,6 +20,7 @@
#include "qgsprocessingparametertypeimpl.h"
#include "qgsprocessingparametervectortilewriterlayers.h"
#include "qgsprocessingparameterfieldmap.h"
#include "qgsprocessingparameteraggregate.h"
QgsProcessingRegistry::QgsProcessingRegistry( QObject *parent SIP_TRANSFERTHIS )
: QObject( parent )
@ -64,6 +65,7 @@ QgsProcessingRegistry::QgsProcessingRegistry( QObject *parent SIP_TRANSFERTHIS )
addParameterType( new QgsProcessingParameterTypeDatabaseTable() );
addParameterType( new QgsProcessingParameterTypeVectorTileWriterLayers() );
addParameterType( new QgsProcessingParameterTypeFieldMapping() );
addParameterType( new QgsProcessingParameterTypeAggregate() );
}
QgsProcessingRegistry::~QgsProcessingRegistry()

View File

@ -49,6 +49,7 @@
#include "qgscoordinatetransformcontext.h"
#include "qgsrasterfilewriter.h"
#include "qgsprocessingparameterfieldmap.h"
#include "qgsprocessingparameteraggregate.h"
class DummyAlgorithm : public QgsProcessingAlgorithm
{
@ -598,6 +599,7 @@ class TestQgsProcessing: public QObject
void parameterDatabaseSchema();
void parameterDatabaseTable();
void parameterFieldMapping();
void parameterAggregate();
void checkParamValues();
void combineLayerExtent();
void processingFeatureSource();
@ -7661,6 +7663,76 @@ void TestQgsProcessing::parameterFieldMapping()
QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterFieldMapping('non_optional', '', parentLayerParameterName='parent', optional=True)" ) );
}
void TestQgsProcessing::parameterAggregate()
{
QgsProcessingContext context;
// not optional!
std::unique_ptr< QgsProcessingParameterAggregate > def( new QgsProcessingParameterAggregate( "non_optional", QString(), QStringLiteral( "parent" ), false ) );
QVERIFY( !def->checkValueIsAcceptable( 1 ) );
QVERIFY( !def->checkValueIsAcceptable( "test" ) );
QVERIFY( !def->checkValueIsAcceptable( "" ) );
QVERIFY( def->checkValueIsAcceptable( QVariantList() ) );
QVariantMap map;
QVERIFY( !def->checkValueIsAcceptable( QVariantList() << map ) );
map.insert( QStringLiteral( "name" ), QStringLiteral( "n" ) );
QVERIFY( !def->checkValueIsAcceptable( QVariantList() << map ) );
map.insert( QStringLiteral( "type" ), QStringLiteral( "t" ) );
QVERIFY( !def->checkValueIsAcceptable( QVariantList() << map ) );
map.insert( QStringLiteral( "aggregate" ), QStringLiteral( "e" ) );
QVERIFY( !def->checkValueIsAcceptable( QVariantList() << map ) );
map.insert( QStringLiteral( "input" ), QStringLiteral( "i" ) );
QVERIFY( def->checkValueIsAcceptable( QVariantList() << map ) );
QVariantMap map2;
map2.insert( QStringLiteral( "name" ), QStringLiteral( "n2" ) );
map2.insert( QStringLiteral( "type" ), QStringLiteral( "t2" ) );
map2.insert( QStringLiteral( "aggregate" ), QStringLiteral( "e2" ) );
map2.insert( QStringLiteral( "input" ), QStringLiteral( "i2" ) );
QVERIFY( def->checkValueIsAcceptable( QVariantList() << map << map2 ) );
QVariantMap params;
params.insert( "non_optional", QVariantList() << map << map2 );
QCOMPARE( def->valueAsPythonString( QVariant(), context ), QStringLiteral( "None" ) );
QCOMPARE( def->valueAsPythonString( 5, context ), QStringLiteral( "5" ) );
QCOMPARE( def->valueAsPythonString( QStringLiteral( "abc" ), context ), QStringLiteral( "'abc'" ) );
QCOMPARE( def->valueAsPythonString( QStringLiteral( "abc\ndef" ), context ), QStringLiteral( "'abc\\ndef'" ) );
QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) );
QCOMPARE( def->valueAsPythonString( QVariant( QVariantList() << map << map2 ), context ), QStringLiteral( "[{'aggregate': 'e','input': 'i','name': 'n','type': 't'},{'aggregate': 'e2','input': 'i2','name': 'n2','type': 't2'}]" ) );
QString pythonCode = def->asPythonString();
QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterAggregate('non_optional', '', parentLayerParameterName='parent')" ) );
QVariantMap mapDef = def->toVariantMap();
QgsProcessingParameterAggregate fromMap( "x" );
QVERIFY( fromMap.fromVariantMap( mapDef ) );
QCOMPARE( fromMap.name(), def->name() );
QCOMPARE( fromMap.description(), def->description() );
QCOMPARE( fromMap.flags(), def->flags() );
QCOMPARE( fromMap.defaultValue(), def->defaultValue() );
QCOMPARE( fromMap.parentLayerParameterName(), def->parentLayerParameterName() );
def.reset( dynamic_cast< QgsProcessingParameterAggregate *>( QgsProcessingParameters::parameterFromVariantMap( mapDef ) ) );
QVERIFY( dynamic_cast< QgsProcessingParameterAggregate *>( def.get() ) );
def->setParentLayerParameterName( QString() );
QVERIFY( def->dependsOnOtherParameters().isEmpty() );
def->setParentLayerParameterName( QStringLiteral( "test_layer" ) );
QCOMPARE( def->dependsOnOtherParameters(), QStringList() << QStringLiteral( "test_layer" ) );
// optional
def.reset( new QgsProcessingParameterAggregate( "non_optional", QString(), QStringLiteral( "parent" ), true ) );
QVERIFY( !def->checkValueIsAcceptable( 1 ) );
QVERIFY( !def->checkValueIsAcceptable( "test" ) );
QVERIFY( !def->checkValueIsAcceptable( "" ) );
QVERIFY( def->checkValueIsAcceptable( QVariantList() ) );
QVERIFY( def->checkValueIsAcceptable( QVariantList() << map << map2 ) );
QVERIFY( def->checkValueIsAcceptable( QVariant() ) );
pythonCode = def->asPythonString();
QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterAggregate('non_optional', '', parentLayerParameterName='parent', optional=True)" ) );
}
void TestQgsProcessing::parameterDateTime()
{
QgsProcessingContext context;