QGIS API Documentation  3.4.15-Madeira (e83d02e274)
qgsalgorithmorderbyexpression.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsalgorithmorderbyexpression.h
3  ---------------------
4  begin : November 2017
5  copyright : (C) 2017 by Etienne Trimaille
6  email : etienne dot trimaille 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 
20 #include "qgsfeaturerequest.h"
21 
22 
24 
25 QString QgsOrderByExpressionAlgorithm::name() const
26 {
27  return QStringLiteral( "orderbyexpression" );
28 }
29 
30 QString QgsOrderByExpressionAlgorithm::displayName() const
31 {
32  return QObject::tr( "Order by expression" );
33 }
34 
35 QStringList QgsOrderByExpressionAlgorithm::tags() const
36 {
37  return QObject::tr( "orderby,sort,expression,field" ).split( ',' );
38 }
39 
40 QString QgsOrderByExpressionAlgorithm::group() const
41 {
42  return QObject::tr( "Vector general" );
43 }
44 
45 QString QgsOrderByExpressionAlgorithm::groupId() const
46 {
47  return QStringLiteral( "vectorgeneral" );
48 }
49 
50 void QgsOrderByExpressionAlgorithm::initAlgorithm( const QVariantMap & )
51 {
52  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ), QList< int >() << QgsProcessing::TypeVector ) );
53  addParameter( new QgsProcessingParameterExpression( QStringLiteral( "EXPRESSION" ), QObject::tr( "Expression" ), QVariant(), QStringLiteral( "INPUT" ) ) );
54  addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "ASCENDING" ), QObject::tr( "Sort ascending" ), true ) );
55  addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "NULLS_FIRST" ), QObject::tr( "Sort nulls first" ), false ) );
56 
57  addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Ordered" ) ) );
58 }
59 
60 QString QgsOrderByExpressionAlgorithm::shortHelpString() const
61 {
62  return QObject::tr( "This algorithm sorts a vector layer according to an expression. Be careful, it might not work as expected with some providers, the order might not be kept every time." );
63 }
64 
65 QgsOrderByExpressionAlgorithm *QgsOrderByExpressionAlgorithm::createInstance() const
66 {
67  return new QgsOrderByExpressionAlgorithm();
68 }
69 
70 QVariantMap QgsOrderByExpressionAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
71 {
72  std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
73  if ( !source )
74  throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
75 
76  QString expressionString = parameterAsExpression( parameters, QStringLiteral( "EXPRESSION" ), context );
77 
78  bool ascending = parameterAsBool( parameters, QStringLiteral( "ASCENDING" ), context );
79  bool nullsFirst = parameterAsBool( parameters, QStringLiteral( "NULLS_FIRST" ), context );
80 
81  QString sinkId;
82  std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, sinkId, source->fields(), source->wkbType(), source->sourceCrs() ) );
83  if ( !sink )
84  throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
85 
86  long count = source->featureCount();
87  double step = count > 0 ? 100.0 / count : 1;
88  int current = 0;
89 
90  QgsFeatureRequest request;
91  request.addOrderBy( expressionString, ascending, nullsFirst );
92 
93  QgsFeature inFeature;
94  QgsFeatureIterator features = source->getFeatures( request, QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks );
95  while ( features.nextFeature( inFeature ) )
96  {
97  if ( feedback->isCanceled() )
98  {
99  break;
100  }
101  sink->addFeature( inFeature );
102  feedback->setProgress( current * step );
103  current++;
104  }
105 
106  QVariantMap outputs;
107  outputs.insert( QStringLiteral( "OUTPUT" ), sinkId );
108  return outputs;
109 }
110 
A boolean parameter for processing algorithms.
Wrapper for iterator of features from vector data provider or vector layer.
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:54
Base class for providing feedback from a processing algorithm.
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
An expression parameter for processing algorithms.
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:63
QgsFeatureRequest & addOrderBy(const QString &expression, bool ascending=true)
Adds a new OrderByClause, appending it as the least important one.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
A feature sink output for processing algorithms.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
Custom exception class for processing related exceptions.
Definition: qgsexception.h:82
An input feature source (such as vector layers) parameter for processing algorithms.
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition: qgsprocessing.h:53
bool nextFeature(QgsFeature &f)
Contains information about the context in which a processing algorithm is executed.