Skip to content

Commit 32fbf0a

Browse files
committedMar 13, 2019
[processing][FEATURE] New parameter type for map scales
This adds a new parameter type specifically for map scales, QgsProcessingParameterScale. The values are evaluated using self.parameterAsDouble, which returns the map scale denominator (matching the standard in other parts of the QGIS API). Scale parameters are displayed to users using the standard QgsScaleWidget, which includes the combo box of predefined scales and a shortcut button to match the current map scale.
1 parent ca7008c commit 32fbf0a

13 files changed

+514
-14
lines changed
 

‎python/core/auto_generated/processing/qgsprocessingparameters.sip.in

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ their acceptable ranges, defaults, etc.
151151
sipType = sipType_QgsProcessingParameterNumber;
152152
else if ( sipCpp->type() == QgsProcessingParameterDistance::typeName() )
153153
sipType = sipType_QgsProcessingParameterDistance;
154+
else if ( sipCpp->type() == QgsProcessingParameterScale::typeName() )
155+
sipType = sipType_QgsProcessingParameterScale;
154156
else if ( sipCpp->type() == QgsProcessingParameterRange::typeName() )
155157
sipType = sipType_QgsProcessingParameterRange;
156158
else if ( sipCpp->type() == QgsProcessingParameterRasterLayer::typeName() )
@@ -1653,6 +1655,49 @@ Sets the default distance ``unit`` for the parameter.
16531655
virtual bool fromVariantMap( const QVariantMap &map );
16541656

16551657

1658+
};
1659+
1660+
class QgsProcessingParameterScale : QgsProcessingParameterNumber
1661+
{
1662+
%Docstring
1663+
A double numeric parameter for map scale values.
1664+
1665+
QgsProcessingParameterScale should be evaluated by calling QgsProcessingAlgorithm.parameterAsDouble(),
1666+
which will return a numeric value representing the scale denominator.
1667+
1668+
.. versionadded:: 3.8
1669+
%End
1670+
1671+
%TypeHeaderCode
1672+
#include "qgsprocessingparameters.h"
1673+
%End
1674+
public:
1675+
1676+
explicit QgsProcessingParameterScale( const QString &name, const QString &description = QString(),
1677+
const QVariant &defaultValue = QVariant(),
1678+
bool optional = false );
1679+
%Docstring
1680+
Constructor for QgsProcessingParameterScale.
1681+
%End
1682+
1683+
static QString typeName();
1684+
%Docstring
1685+
Returns the type name for the parameter class.
1686+
%End
1687+
1688+
virtual QgsProcessingParameterScale *clone() const /Factory/;
1689+
1690+
1691+
virtual QString type() const;
1692+
1693+
virtual QString asPythonString( QgsProcessing::PythonOutputType outputType = QgsProcessing::PythonQgsProcessingAlgorithmSubclass ) const;
1694+
1695+
1696+
static QgsProcessingParameterScale *fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition ) /Factory/;
1697+
%Docstring
1698+
Creates a new parameter using the definition from a script code.
1699+
%End
1700+
16561701
};
16571702

16581703
class QgsProcessingParameterRange : QgsProcessingParameterDefinition

‎python/plugins/processing/core/parameters.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666

6767
PARAMETER_NUMBER = 'number'
6868
PARAMETER_DISTANCE = 'distance'
69+
PARAMETER_SCALE = 'scale'
6970
PARAMETER_RASTER = 'raster'
7071
PARAMETER_TABLE = 'vector'
7172
PARAMETER_VECTOR = 'source'

‎python/plugins/processing/modeler/ModelerParameterDefinitionDialog.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
QgsProcessingParameterMultipleLayers,
5656
QgsProcessingParameterNumber,
5757
QgsProcessingParameterDistance,
58+
QgsProcessingParameterScale,
5859
QgsProcessingParameterRange,
5960
QgsProcessingParameterRasterLayer,
6061
QgsProcessingParameterEnum,
@@ -224,8 +225,8 @@ def setupUi(self):
224225
if self.param is not None:
225226
self.datatypeCombo.setCurrentIndex(self.datatypeCombo.findData(self.param.layerType()))
226227
self.verticalLayout.addWidget(self.datatypeCombo)
227-
elif (self.paramType == parameters.PARAMETER_NUMBER or self.paramType == parameters.PARAMETER_DISTANCE or
228-
isinstance(self.param, (QgsProcessingParameterNumber, QgsProcessingParameterDistance))):
228+
elif (self.paramType in (parameters.PARAMETER_NUMBER, parameters.PARAMETER_DISTANCE, parameters.PARAMETER_SCALE) or
229+
isinstance(self.param, (QgsProcessingParameterNumber, QgsProcessingParameterDistance, QgsProcessingParameterScale))):
229230

230231
if (self.paramType == parameters.PARAMETER_DISTANCE or
231232
isinstance(self.param, QgsProcessingParameterDistance)):
@@ -245,7 +246,8 @@ def setupUi(self):
245246
self.parentCombo.setCurrentIndex(idx)
246247
idx += 1
247248
self.verticalLayout.addWidget(self.parentCombo)
248-
else:
249+
elif (self.paramType != parameters.PARAMETER_SCALE and not
250+
isinstance(self.param, QgsProcessingParameterScale)):
249251
self.verticalLayout.addWidget(QLabel(self.tr('Number type')))
250252
self.type_combo = QComboBox()
251253
self.type_combo.addItem(self.tr('Float'), QgsProcessingParameterNumber.Double)
@@ -254,15 +256,17 @@ def setupUi(self):
254256
self.type_combo.setCurrentIndex(self.type_combo.findData(self.param.dataType()))
255257
self.verticalLayout.addWidget(self.type_combo)
256258

257-
self.verticalLayout.addWidget(QLabel(self.tr('Min value')))
258-
self.minTextBox = QLineEdit()
259-
self.verticalLayout.addWidget(self.minTextBox)
260-
self.verticalLayout.addWidget(QLabel(self.tr('Max value')))
261-
self.maxTextBox = QLineEdit()
262-
self.verticalLayout.addWidget(self.maxTextBox)
263-
if self.param is not None:
264-
self.minTextBox.setText(str(self.param.minimum()))
265-
self.maxTextBox.setText(str(self.param.maximum()))
259+
if (self.paramType != parameters.PARAMETER_SCALE and not
260+
isinstance(self.param, QgsProcessingParameterScale)):
261+
self.verticalLayout.addWidget(QLabel(self.tr('Min value')))
262+
self.minTextBox = QLineEdit()
263+
self.verticalLayout.addWidget(self.minTextBox)
264+
self.verticalLayout.addWidget(QLabel(self.tr('Max value')))
265+
self.maxTextBox = QLineEdit()
266+
self.verticalLayout.addWidget(self.maxTextBox)
267+
if self.param is not None:
268+
self.minTextBox.setText(str(self.param.minimum()))
269+
self.maxTextBox.setText(str(self.param.maximum()))
266270
self.verticalLayout.addWidget(QLabel(self.tr('Default value')))
267271
self.defaultTextBox = QLineEdit()
268272
self.defaultTextBox.setText(self.tr('0'))
@@ -475,6 +479,10 @@ def accept(self):
475479
parent = self.parentCombo.currentData()
476480
if parent:
477481
self.param.setParentParameterName(parent)
482+
elif (self.paramType == parameters.PARAMETER_SCALE or
483+
isinstance(self.param, QgsProcessingParameterScale)):
484+
self.param = QgsProcessingParameterScale(name, description,
485+
self.defaultTextBox.text())
478486
elif (self.paramType == parameters.PARAMETER_NUMBER or
479487
isinstance(self.param, QgsProcessingParameterNumber)):
480488

‎src/core/processing/models/qgsprocessingmodelalgorithm.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,7 @@ QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> QgsProcessingMode
641641
// "static"/single value sources
642642
QgsProcessingModelChildParameterSources sources = availableSourcesForChild( childId, QStringList() << QgsProcessingParameterNumber::typeName()
643643
<< QgsProcessingParameterDistance::typeName()
644+
<< QgsProcessingParameterScale::typeName()
644645
<< QgsProcessingParameterBoolean::typeName()
645646
<< QgsProcessingParameterExpression::typeName()
646647
<< QgsProcessingParameterField::typeName()

‎src/core/processing/qgsprocessingparameters.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1626,6 +1626,10 @@ QgsProcessingParameterDefinition *QgsProcessingParameters::parameterFromScriptCo
16261626
return QgsProcessingParameterMultipleLayers::fromScriptCode( name, description, isOptional, definition );
16271627
else if ( type == QStringLiteral( "number" ) )
16281628
return QgsProcessingParameterNumber::fromScriptCode( name, description, isOptional, definition );
1629+
else if ( type == QStringLiteral( "distance" ) )
1630+
return QgsProcessingParameterDistance::fromScriptCode( name, description, isOptional, definition );
1631+
else if ( type == QStringLiteral( "scale" ) )
1632+
return QgsProcessingParameterScale::fromScriptCode( name, description, isOptional, definition );
16291633
else if ( type == QStringLiteral( "range" ) )
16301634
return QgsProcessingParameterRange::fromScriptCode( name, description, isOptional, definition );
16311635
else if ( type == QStringLiteral( "raster" ) )
@@ -5259,6 +5263,50 @@ bool QgsProcessingParameterDistance::fromVariantMap( const QVariantMap &map )
52595263
}
52605264

52615265

5266+
//
5267+
// QgsProcessingParameterScale
5268+
//
5269+
5270+
QgsProcessingParameterScale::QgsProcessingParameterScale( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
5271+
: QgsProcessingParameterNumber( name, description, Double, defaultValue, optional )
5272+
{
5273+
5274+
}
5275+
5276+
QgsProcessingParameterScale *QgsProcessingParameterScale::clone() const
5277+
{
5278+
return new QgsProcessingParameterScale( *this );
5279+
}
5280+
5281+
QString QgsProcessingParameterScale::type() const
5282+
{
5283+
return typeName();
5284+
}
5285+
5286+
QString QgsProcessingParameterScale::asPythonString( const QgsProcessing::PythonOutputType outputType ) const
5287+
{
5288+
switch ( outputType )
5289+
{
5290+
case QgsProcessing::PythonQgsProcessingAlgorithmSubclass:
5291+
{
5292+
QString code = QStringLiteral( "QgsProcessingParameterScale('%1', '%2'" ).arg( name(), description() );
5293+
if ( mFlags & FlagOptional )
5294+
code += QStringLiteral( ", optional=True" );
5295+
QgsProcessingContext c;
5296+
code += QStringLiteral( ", defaultValue=%1)" ).arg( valueAsPythonString( mDefault, c ) );
5297+
return code;
5298+
}
5299+
}
5300+
return QString();
5301+
}
5302+
5303+
QgsProcessingParameterScale *QgsProcessingParameterScale::fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition )
5304+
{
5305+
return new QgsProcessingParameterScale( name, description, definition.isEmpty() ? QVariant()
5306+
: ( definition.toLower().trimmed() == QStringLiteral( "none" ) ? QVariant() : definition ), isOptional );
5307+
}
5308+
5309+
52625310
//
52635311
// QgsProcessingParameterLayout
52645312
//

‎src/core/processing/qgsprocessingparameters.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@ class CORE_EXPORT QgsProcessingParameterDefinition
228228
sipType = sipType_QgsProcessingParameterNumber;
229229
else if ( sipCpp->type() == QgsProcessingParameterDistance::typeName() )
230230
sipType = sipType_QgsProcessingParameterDistance;
231+
else if ( sipCpp->type() == QgsProcessingParameterScale::typeName() )
232+
sipType = sipType_QgsProcessingParameterScale;
231233
else if ( sipCpp->type() == QgsProcessingParameterRange::typeName() )
232234
sipType = sipType_QgsProcessingParameterRange;
233235
else if ( sipCpp->type() == QgsProcessingParameterRasterLayer::typeName() )
@@ -1628,6 +1630,44 @@ class CORE_EXPORT QgsProcessingParameterDistance : public QgsProcessingParameter
16281630

16291631
};
16301632

1633+
/**
1634+
* \class QgsProcessingParameterDistance
1635+
* \ingroup core
1636+
* A double numeric parameter for map scale values.
1637+
*
1638+
* QgsProcessingParameterScale should be evaluated by calling QgsProcessingAlgorithm::parameterAsDouble(),
1639+
* which will return a numeric value representing the scale denominator.
1640+
*
1641+
* \since QGIS 3.8
1642+
*/
1643+
class CORE_EXPORT QgsProcessingParameterScale : public QgsProcessingParameterNumber
1644+
{
1645+
public:
1646+
1647+
/**
1648+
* Constructor for QgsProcessingParameterScale.
1649+
*/
1650+
explicit QgsProcessingParameterScale( const QString &name, const QString &description = QString(),
1651+
const QVariant &defaultValue = QVariant(),
1652+
bool optional = false );
1653+
1654+
/**
1655+
* Returns the type name for the parameter class.
1656+
*/
1657+
static QString typeName() { return QStringLiteral( "scale" ); }
1658+
1659+
QgsProcessingParameterScale *clone() const override SIP_FACTORY;
1660+
1661+
QString type() const override;
1662+
QString asPythonString( QgsProcessing::PythonOutputType outputType = QgsProcessing::PythonQgsProcessingAlgorithmSubclass ) const override;
1663+
1664+
/**
1665+
* Creates a new parameter using the definition from a script code.
1666+
*/
1667+
static QgsProcessingParameterScale *fromScriptCode( const QString &name, const QString &description, bool isOptional, const QString &definition ) SIP_FACTORY;
1668+
1669+
};
1670+
16311671
/**
16321672
* \class QgsProcessingParameterRange
16331673
* \ingroup core

‎src/core/processing/qgsprocessingparametertypeimpl.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,6 +1340,61 @@ class CORE_EXPORT QgsProcessingParameterTypeDistance : public QgsProcessingParam
13401340
}
13411341

13421342

1343+
};
1344+
1345+
1346+
/**
1347+
* A scale parameter for processing algorithms.
1348+
*
1349+
* \ingroup core
1350+
* \note No Python bindings available. Get your copy from QgsApplication.processingRegistry().parameterType('scale')
1351+
* \since QGIS 3.8
1352+
*/
1353+
class CORE_EXPORT QgsProcessingParameterTypeScale : public QgsProcessingParameterType
1354+
{
1355+
QgsProcessingParameterDefinition *create( const QString &name ) const override SIP_FACTORY
1356+
{
1357+
return new QgsProcessingParameterScale( name );
1358+
}
1359+
1360+
QString description() const override
1361+
{
1362+
return QCoreApplication::translate( "Processing", "A numeric parameter representing a map scale." );
1363+
}
1364+
1365+
QString name() const override
1366+
{
1367+
return QCoreApplication::translate( "Processing", "Scale" );
1368+
}
1369+
1370+
QString id() const override
1371+
{
1372+
return QStringLiteral( "scale" );
1373+
}
1374+
1375+
QString pythonImportString() const override
1376+
{
1377+
return QStringLiteral( "from qgis.core import QgsProcessingParameterScale" );
1378+
}
1379+
1380+
QString className() const override
1381+
{
1382+
return QStringLiteral( "QgsProcessingParameterScale" );
1383+
}
1384+
1385+
QStringList acceptedPythonTypes() const override
1386+
{
1387+
return QStringList() << QStringLiteral( "int: scale denominator" )
1388+
<< QStringLiteral( "float: scale denominator" )
1389+
<< QStringLiteral( "QgsProperty" );
1390+
}
1391+
1392+
QStringList acceptedStringValues() const override
1393+
{
1394+
return QStringList() << QObject::tr( "A numeric value representing the scale denominator" );
1395+
}
1396+
1397+
13431398
};
13441399

13451400
/**

‎src/core/processing/qgsprocessingregistry.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ QgsProcessingRegistry::QgsProcessingRegistry( QObject *parent SIP_TRANSFERTHIS )
4646
addParameterType( new QgsProcessingParameterTypeFeatureSource() );
4747
addParameterType( new QgsProcessingParameterTypeNumber() );
4848
addParameterType( new QgsProcessingParameterTypeDistance() );
49+
addParameterType( new QgsProcessingParameterTypeScale() );
4950
addParameterType( new QgsProcessingParameterTypeBand() );
5051
addParameterType( new QgsProcessingParameterTypeFeatureSink() );
5152
addParameterType( new QgsProcessingParameterTypeLayout() );

‎src/gui/processing/qgsprocessingguiregistry.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ QgsProcessingGuiRegistry::QgsProcessingGuiRegistry()
3232
addParameterWidgetFactory( new QgsProcessingStringWidgetWrapper() );
3333
addParameterWidgetFactory( new QgsProcessingNumericWidgetWrapper() );
3434
addParameterWidgetFactory( new QgsProcessingDistanceWidgetWrapper() );
35+
addParameterWidgetFactory( new QgsProcessingScaleWidgetWrapper() );
3536
addParameterWidgetFactory( new QgsProcessingRangeWidgetWrapper() );
3637
addParameterWidgetFactory( new QgsProcessingAuthConfigWidgetWrapper() );
3738
addParameterWidgetFactory( new QgsProcessingMatrixWidgetWrapper() );

0 commit comments

Comments
 (0)