Skip to content

Commit 6283ca6

Browse files
committed
[processing] Add a model-only algorithm for renaming layers
This is required for algorithms with behaviour which depends on the layer names (e.g. the package algorithm uses the layer name as the table name in the geopackage). We need a way for models to be able to explicitly specify a layer name for this algorithm to be useful in models, otherwise the auto-generated temporary layer names are used (which are not very nice!)
1 parent aef0d33 commit 6283ca6

File tree

5 files changed

+196
-0
lines changed

5 files changed

+196
-0
lines changed

src/analysis/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ SET(QGIS_ANALYSIS_SRCS
5050
processing/qgsalgorithmpromotetomultipart.cpp
5151
processing/qgsalgorithmrasterlayeruniquevalues.cpp
5252
processing/qgsalgorithmremovenullgeometry.cpp
53+
processing/qgsalgorithmrenamelayer.cpp
5354
processing/qgsalgorithmsaveselectedfeatures.cpp
5455
processing/qgsalgorithmsimplify.cpp
5556
processing/qgsalgorithmsmooth.cpp
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/***************************************************************************
2+
qgsalgorithmrenamelayer.cpp
3+
---------------------
4+
begin : November 2017
5+
copyright : (C) 2017 by Nyall Dawson
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#include "qgsalgorithmrenamelayer.h"
19+
20+
///@cond PRIVATE
21+
22+
QString QgsRenameLayerAlgorithm::name() const
23+
{
24+
return QStringLiteral( "renamelayer" );
25+
}
26+
27+
QgsProcessingAlgorithm::Flags QgsRenameLayerAlgorithm::flags() const
28+
{
29+
return FlagHideFromToolbox;
30+
}
31+
32+
QString QgsRenameLayerAlgorithm::displayName() const
33+
{
34+
return QObject::tr( "Rename layer" );
35+
}
36+
37+
QStringList QgsRenameLayerAlgorithm::tags() const
38+
{
39+
return QObject::tr( "change,layer,name" ).split( ',' );
40+
}
41+
42+
QString QgsRenameLayerAlgorithm::group() const
43+
{
44+
return QObject::tr( "Modeler tool" );
45+
}
46+
47+
QString QgsRenameLayerAlgorithm::shortHelpString() const
48+
{
49+
return QObject::tr( "This algorithm renames a layer." );
50+
}
51+
52+
QgsRenameLayerAlgorithm *QgsRenameLayerAlgorithm::createInstance() const
53+
{
54+
return new QgsRenameLayerAlgorithm();
55+
}
56+
57+
void QgsRenameLayerAlgorithm::initAlgorithm( const QVariantMap & )
58+
{
59+
addParameter( new QgsProcessingParameterMapLayer( QStringLiteral( "INPUT" ), QObject::tr( "Layer" ) ) );
60+
addParameter( new QgsProcessingParameterString( QStringLiteral( "NAME" ), QObject::tr( "New name" ) ) );
61+
addOutput( new QgsProcessingOutputMapLayer( QStringLiteral( "OUTPUT" ), QObject::tr( "Layer" ) ) );
62+
}
63+
64+
QVariantMap QgsRenameLayerAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
65+
{
66+
QgsMapLayer *layer = parameterAsLayer( parameters, QStringLiteral( "INPUT" ), context );
67+
QString name = parameterAsString( parameters, QStringLiteral( "NAME" ), context );
68+
69+
if ( !layer )
70+
throw QgsProcessingException( QObject::tr( "Invalid input layer" ) );
71+
72+
if ( name.isEmpty() )
73+
throw QgsProcessingException( QObject::tr( "Invalid (empty) layer name" ) );
74+
75+
bool parameterWasLayerName = parameters.value( QStringLiteral( "INPUT" ) ).toString() == layer->name();
76+
77+
layer->setName( name );
78+
QVariantMap results;
79+
if ( parameterWasLayerName )
80+
results.insert( QStringLiteral( "OUTPUT" ), name );
81+
else
82+
results.insert( QStringLiteral( "OUTPUT" ), parameters.value( QStringLiteral( "INPUT" ) ) );
83+
84+
return results;
85+
}
86+
87+
///@endcond
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/***************************************************************************
2+
qgsalgorithmrenamelayer.h
3+
---------------------
4+
begin : November 2017
5+
copyright : (C) 2017 by Nyall Dawson
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#ifndef QGSALGORITHMRENAMELAYER_H
19+
#define QGSALGORITHMRENAMELAYER_H
20+
21+
#define SIP_NO_FILE
22+
23+
#include "qgis.h"
24+
#include "qgsprocessingalgorithm.h"
25+
26+
///@cond PRIVATE
27+
28+
/**
29+
* Native rename layer algorithm.
30+
*/
31+
class QgsRenameLayerAlgorithm : public QgsProcessingAlgorithm
32+
{
33+
public:
34+
QgsRenameLayerAlgorithm() = default;
35+
void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override;
36+
Flags flags() const override;
37+
QString name() const override;
38+
QString displayName() const override;
39+
virtual QStringList tags() const override;
40+
QString group() const override;
41+
QString shortHelpString() const override;
42+
QgsRenameLayerAlgorithm *createInstance() const override SIP_FACTORY;
43+
44+
protected:
45+
46+
virtual QVariantMap processAlgorithm( const QVariantMap &parameters,
47+
QgsProcessingContext &context, QgsProcessingFeedback * ) override;
48+
49+
};
50+
51+
///@endcond PRIVATE
52+
53+
#endif // QGSALGORITHMRENAMELAYER_H

src/analysis/processing/qgsnativealgorithms.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "qgsalgorithmpromotetomultipart.h"
4848
#include "qgsalgorithmrasterlayeruniquevalues.h"
4949
#include "qgsalgorithmremovenullgeometry.h"
50+
#include "qgsalgorithmrenamelayer.h"
5051
#include "qgsalgorithmsaveselectedfeatures.h"
5152
#include "qgsalgorithmsimplify.h"
5253
#include "qgsalgorithmsmooth.h"
@@ -124,6 +125,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
124125
addAlgorithm( new QgsPromoteToMultipartAlgorithm() );
125126
addAlgorithm( new QgsRasterLayerUniqueValuesReportAlgorithm() );
126127
addAlgorithm( new QgsRemoveNullGeometryAlgorithm() );
128+
addAlgorithm( new QgsRenameLayerAlgorithm() );
127129
addAlgorithm( new QgsSaveSelectedFeatures() );
128130
addAlgorithm( new QgsSelectByLocationAlgorithm() );
129131
addAlgorithm( new QgsSimplifyAlgorithm() );

tests/src/analysis/testqgsprocessingalgs.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class TestQgsProcessingAlgs: public QObject
3434
void init() {} // will be called before each testfunction is executed.
3535
void cleanup() {} // will be called after every testfunction.
3636
void packageAlg();
37+
void renameLayerAlg();
3738

3839
private:
3940

@@ -116,6 +117,58 @@ void TestQgsProcessingAlgs::packageAlg()
116117
QCOMPARE( polygonLayer->featureCount(), mPolygonLayer->featureCount() );
117118
}
118119

120+
void TestQgsProcessingAlgs::renameLayerAlg()
121+
{
122+
const QgsProcessingAlgorithm *package( QgsApplication::processingRegistry()->algorithmById( QStringLiteral( "native:renamelayer" ) ) );
123+
QVERIFY( package );
124+
125+
std::unique_ptr< QgsProcessingContext > context = qgis::make_unique< QgsProcessingContext >();
126+
context->setProject( QgsProject::instance() );
127+
128+
QgsVectorLayer *layer = new QgsVectorLayer( QStringLiteral( "Point?field=col1:real" ), QStringLiteral( "layer" ), QStringLiteral( "memory" ) );
129+
QVERIFY( layer->isValid() );
130+
QgsProject::instance()->addMapLayer( layer );
131+
132+
QgsProcessingFeedback feedback;
133+
134+
QVariantMap parameters;
135+
136+
// bad layer
137+
parameters.insert( QStringLiteral( "INPUT" ), QStringLiteral( "bad layer" ) );
138+
parameters.insert( QStringLiteral( "NAME" ), QStringLiteral( "new name" ) );
139+
bool ok = false;
140+
( void )package->run( parameters, *context, &feedback, &ok );
141+
QVERIFY( !ok );
142+
QCOMPARE( layer->name(), QStringLiteral( "layer" ) );
143+
144+
//invalid name
145+
parameters.insert( QStringLiteral( "INPUT" ), QStringLiteral( "layer" ) );
146+
parameters.insert( QStringLiteral( "NAME" ), QString() );
147+
ok = false;
148+
( void )package->run( parameters, *context, &feedback, &ok );
149+
QVERIFY( !ok );
150+
QCOMPARE( layer->name(), QStringLiteral( "layer" ) );
151+
152+
//good params
153+
parameters.insert( QStringLiteral( "INPUT" ), QVariant::fromValue( layer ) );
154+
parameters.insert( QStringLiteral( "NAME" ), QStringLiteral( "new name" ) );
155+
ok = false;
156+
QVariantMap results = package->run( parameters, *context, &feedback, &ok );
157+
QVERIFY( ok );
158+
QCOMPARE( layer->name(), QStringLiteral( "new name" ) );
159+
QCOMPARE( results.value( "OUTPUT" ), QVariant::fromValue( layer ) );
160+
161+
// with input layer name as parameter
162+
parameters.insert( QStringLiteral( "INPUT" ), QStringLiteral( "new name" ) );
163+
parameters.insert( QStringLiteral( "NAME" ), QStringLiteral( "new name2" ) );
164+
ok = false;
165+
results = package->run( parameters, *context, &feedback, &ok );
166+
QVERIFY( ok );
167+
QCOMPARE( layer->name(), QStringLiteral( "new name2" ) );
168+
// result should use new name as value
169+
QCOMPARE( results.value( "OUTPUT" ).toString(), QStringLiteral( "new name2" ) );
170+
}
171+
119172

120173
QGSTEST_MAIN( TestQgsProcessingAlgs )
121174
#include "testqgsprocessingalgs.moc"

0 commit comments

Comments
 (0)