mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-12 00:06:43 -04:00
Fix aggregate expression calculation when used with virtual fields
The layer expression context (which is required for aggregate calculation to work) was not being added to the context used by vector layer feature iterators. Fix #15930
This commit is contained in:
parent
0639264a4a
commit
3f4d6de54b
@ -61,6 +61,7 @@ class QgsVectorLayerFeatureSource : QgsAbstractFeatureSource
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -79,6 +79,9 @@ QgsVectorLayerFeatureSource::QgsVectorLayerFeatureSource( const QgsVectorLayer *
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
std::unique_ptr< QgsExpressionContextScope > layerScope( QgsExpressionContextUtils::layerScope( layer ) );
|
||||
mLayerScope = *layerScope;
|
||||
}
|
||||
|
||||
QgsVectorLayerFeatureSource::~QgsVectorLayerFeatureSource()
|
||||
@ -644,7 +647,7 @@ void QgsVectorLayerFeatureIterator::prepareFields()
|
||||
mExpressionContext.reset( new QgsExpressionContext() );
|
||||
mExpressionContext->appendScope( QgsExpressionContextUtils::globalScope() );
|
||||
mExpressionContext->appendScope( QgsExpressionContextUtils::projectScope( QgsProject::instance() ) );
|
||||
mExpressionContext->setFields( mSource->mFields );
|
||||
mExpressionContext->appendScope( new QgsExpressionContextScope( mSource->mLayerScope ) );
|
||||
|
||||
mFieldsToPrepare = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) ? mRequest.subsetOfAttributes() : mSource->mFields.allAttributesList();
|
||||
|
||||
|
@ -84,6 +84,8 @@ class CORE_EXPORT QgsVectorLayerFeatureSource : public QgsAbstractFeatureSource
|
||||
|
||||
QgsFields mFields;
|
||||
|
||||
QgsExpressionContextScope mLayerScope;
|
||||
|
||||
bool mHasEditBuffer;
|
||||
|
||||
// A deep-copy is only performed, if the original maps change
|
||||
|
@ -1829,6 +1829,27 @@ class TestQgsVectorLayer(unittest.TestCase, FeatureSourceTestCase):
|
||||
self.assertTrue(ok)
|
||||
self.assertEqual(val, 'this is a test')
|
||||
|
||||
def testAggregateInVirtualField(self):
|
||||
"""
|
||||
Test aggregates in a virtual field
|
||||
"""
|
||||
layer = QgsVectorLayer("Point?field=fldint:integer", "layer", "memory")
|
||||
pr = layer.dataProvider()
|
||||
|
||||
int_values = [4, 2, 3, 2, 5, None, 8]
|
||||
features = []
|
||||
for i in int_values:
|
||||
f = QgsFeature()
|
||||
f.setFields(layer.fields())
|
||||
f.setAttributes([i])
|
||||
features.append(f)
|
||||
assert pr.addFeatures(features)
|
||||
|
||||
field = QgsField('virtual', QVariant.Double)
|
||||
layer.addExpressionField('sum(fldint*2)', field)
|
||||
vals = [f['virtual'] for f in layer.getFeatures()]
|
||||
self.assertEqual(vals, [48, 48, 48, 48, 48, 48, 48])
|
||||
|
||||
def onLayerOpacityChanged(self, tr):
|
||||
self.opacityTest = tr
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user