16 #ifndef QGSEXPRESSIONSORTER_H
17 #define QGSEXPRESSIONSORTER_H
25 class QgsExpressionSorter
28 explicit QgsExpressionSorter(
const QList<QgsFeatureRequest::OrderByClause> &preparedOrderBys )
29 : mPreparedOrderBys( preparedOrderBys )
33 , mUseCaseInsensitiveComparison( QLocale().name() == QLocale::
c().name() )
41 const QVariant &v1 = f1.
mIndexes.at( i );
42 const QVariant &v2 = f2.
mIndexes.at( i );
46 if ( v1.isNull() && v2.isNull() )
50 if ( v1.isNull() != v2.isNull() )
52 if ( orderBy.nullsFirst() )
63 case QVariant::LongLong:
64 case QVariant::ULongLong:
65 if ( v1.toLongLong() == v2.toLongLong() )
67 if ( orderBy.ascending() )
68 return v1.toLongLong() < v2.toLongLong();
70 return v1.toLongLong() > v2.toLongLong();
72 case QVariant::Double:
75 if ( orderBy.ascending() )
76 return v1.toDouble() < v2.toDouble();
78 return v1.toDouble() > v2.toDouble();
81 if ( v1.toDate() == v2.toDate() )
83 if ( orderBy.ascending() )
84 return v1.toDate() < v2.toDate();
86 return v1.toDate() > v2.toDate();
89 if ( v1.toTime() == v2.toTime() )
91 if ( orderBy.ascending() )
92 return v1.toTime() < v2.toTime();
94 return v1.toTime() > v2.toTime();
96 case QVariant::DateTime:
97 if ( v1.toDateTime() == v2.toDateTime() )
99 if ( orderBy.ascending() )
100 return v1.toDateTime() < v2.toDateTime();
102 return v1.toDateTime() > v2.toDateTime();
105 if ( v1.toBool() == v2.toBool() )
107 if ( orderBy.ascending() )
113 if ( 0 == v1.toString().localeAwareCompare( v2.toString() ) )
115 if ( mUseCaseInsensitiveComparison )
117 if ( orderBy.ascending() )
118 return v1.toString().compare( v2.toString(), Qt::CaseInsensitive ) < 0;
120 return v1.toString().compare( v2.toString(), Qt::CaseInsensitive ) > 0;
124 if ( orderBy.ascending() )
125 return v1.toString().localeAwareCompare( v2.toString() ) < 0;
127 return v1.toString().localeAwareCompare( v2.toString() ) > 0;
142 QVector<QgsIndexedFeature> indexedFeatures;
146 for (
const QgsFeature &f : std::as_const( features ) )
148 indexedFeatureToAppend.
mIndexes.resize( mPreparedOrderBys.size() );
149 indexedFeatureToAppend.
mFeature = f;
156 indexedFeatureToAppend.
mIndexes.replace( i++, orderBy.expression().evaluate( expressionContext ) );
158 indexedFeatures.append( indexedFeatureToAppend );
161 delete expressionContext->
popScope();
163 std::sort( indexedFeatures.begin(), indexedFeatures.end(), *
this );
167 for (
const QgsIndexedFeature &indexedFeature : std::as_const( indexedFeatures ) )
168 features.append( indexedFeature.mFeature );
172 QList<QgsFeatureRequest::OrderByClause> mPreparedOrderBys;
173 bool mUseCaseInsensitiveComparison;
Single scope for storing variables and functions for use within a QgsExpressionContext.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
The OrderByClause class represents an order by clause for a QgsFeatureRequest.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Temporarily used structure to cache order by information.
QVector< QVariant > mIndexes
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)