|
@@ -83,7 +83,7 @@ bool QgsAggregateAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, Qgs |
|
|
mGeometryExpression = createExpression( QStringLiteral( "collect($geometry, %1)" ).arg( mGroupBy ), context ); |
|
|
|
|
|
const QVariantList aggregates = parameters.value( QStringLiteral( "AGGREGATES" ) ).toList(); |
|
|
|
|
|
int currentAttributeIndex = 0; |
|
|
for ( const QVariant &aggregate : aggregates ) |
|
|
{ |
|
|
const QVariantMap aggregateDef = aggregate.toMap(); |
|
@@ -109,6 +109,11 @@ bool QgsAggregateAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, Qgs |
|
|
{ |
|
|
expression = source; |
|
|
} |
|
|
else if ( aggregateType == QLatin1String( "last_value" ) ) |
|
|
{ |
|
|
expression = source; |
|
|
mAttributesRequireLastFeature << currentAttributeIndex; |
|
|
} |
|
|
else if ( aggregateType == QLatin1String( "concatenate" ) || aggregateType == QLatin1String( "concatenate_unique" ) ) |
|
|
{ |
|
|
expression = QStringLiteral( "%1(%2, %3, %4, \'%5\')" ).arg( aggregateType, |
|
@@ -122,6 +127,7 @@ bool QgsAggregateAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, Qgs |
|
|
expression = QStringLiteral( "%1(%2, %3)" ).arg( aggregateType, source, mGroupBy ); |
|
|
} |
|
|
mExpressions.append( createExpression( expression, context ) ); |
|
|
currentAttributeIndex++; |
|
|
} |
|
|
|
|
|
return true; |
|
@@ -157,8 +163,8 @@ QVariantMap QgsAggregateAlgorithm::processAlgorithm( const QVariantMap ¶mete |
|
|
// upgrade group by value to a list, so that we get correct behavior with the QHash |
|
|
const QVariantList key = groupByValue.type() == QVariant::List ? groupByValue.toList() : ( QVariantList() << groupByValue ); |
|
|
|
|
|
auto groupIt = groups.constFind( key ); |
|
|
if ( groupIt == groups.constEnd() ) |
|
|
auto groupIt = groups.find( key ); |
|
|
if ( groupIt == groups.end() ) |
|
|
{ |
|
|
QString id = QStringLiteral( "memory:" ); |
|
|
std::unique_ptr< QgsFeatureSink > sink( QgsProcessingUtils::createFeatureSink( id, |
|
@@ -176,13 +182,14 @@ QVariantMap QgsAggregateAlgorithm::processAlgorithm( const QVariantMap ¶mete |
|
|
//store ownership of sink in groupSinks, so that these get deleted automatically if an exception is raised later.. |
|
|
groupSinks.emplace_back( std::move( sink ) ); |
|
|
group.layer = layer; |
|
|
group.feature = feature; |
|
|
group.firstFeature = feature; |
|
|
groups[key] = group; |
|
|
keys.append( key ); |
|
|
} |
|
|
else |
|
|
{ |
|
|
groupIt->sink->addFeature( feature, QgsFeatureSink::FastInsert ); |
|
|
groupIt->lastFeature = feature; |
|
|
} |
|
|
|
|
|
current++; |
|
@@ -210,7 +217,7 @@ QVariantMap QgsAggregateAlgorithm::processAlgorithm( const QVariantMap ¶mete |
|
|
|
|
|
QgsExpressionContext exprContext = createExpressionContext( parameters, context ); |
|
|
exprContext.appendScope( QgsExpressionContextUtils::layerScope( group.layer ) ); |
|
|
exprContext.setFeature( group.feature ); |
|
|
exprContext.setFeature( group.firstFeature ); |
|
|
|
|
|
QgsGeometry geometry = mGeometryExpression.evaluate( &exprContext ).value< QgsGeometry >(); |
|
|
if ( mGeometryExpression.hasEvalError() ) |
|
@@ -234,8 +241,10 @@ QVariantMap QgsAggregateAlgorithm::processAlgorithm( const QVariantMap ¶mete |
|
|
|
|
|
QgsAttributes attributes; |
|
|
attributes.reserve( mExpressions.size() ); |
|
|
int currentAttributeIndex = 0; |
|
|
for ( auto it = mExpressions.begin(); it != mExpressions.end(); ++it ) |
|
|
{ |
|
|
exprContext.setFeature( mAttributesRequireLastFeature.contains( currentAttributeIndex ) ? group.lastFeature : group.firstFeature ); |
|
|
if ( it->isValid() ) |
|
|
{ |
|
|
const QVariant value = it->evaluate( &exprContext ); |
|
@@ -249,6 +258,7 @@ QVariantMap QgsAggregateAlgorithm::processAlgorithm( const QVariantMap ¶mete |
|
|
{ |
|
|
attributes.append( QVariant() ); |
|
|
} |
|
|
currentAttributeIndex++; |
|
|
} |
|
|
|
|
|
// Write output feature |
|
|