[QGIS-Developer] Expressions with aggregate in PyQGIS

Nyall Dawson nyall.dawson at gmail.com
Sun May 19 17:37:06 PDT 2019


On Mon, 20 May 2019 at 01:21, Anita Graser <anitagraser at gmx.at> wrote:
>
> Hi,
>
> I'd like to add an example of an aggregate expression to my recent PyQGIS 101 tutorial on expressions [0]. I got expressions for individual features working but cannot figure out how to set the context for aggregate expressions correctly.
>
> As far as I can tell, the PyQGIS Cookbook doesn't contain any information on this either [1].

You aren't correctly constructing your expression context:

context = QgsExpressionContext()
scope = QgsExpressionContextScope()
context.appendScope(scope)

This is effectively doing nothing -- you're creating a context, but
not putting anything in that context.

What you need to do is populate the context with relevant scopes,
depending on what's available at the time you're evaluating the
expression. You get "prebuilt" scopes by using the methods from
QgsExpressionContextUtils. E.g.

context = QgsExpressionContext()
context.append(QgsExpressionContextUtils.globalScope())
context.append(QgsExpressionContextUtils.projectScope(QgsProject.instance()))

That's effectively the **minimum** you'd ever populate a context using
-- every expression evaluated anywhere should have access to global
and project information.

But usually, you'd also want to be adding a map layer scope:

context.append(QgsExpressionContextUtils.layerScope( my_layer ))

This is what's missing from your examples, and it's required for
calculation of aggregate based expressions (and other expressions,
e.g. those which use field references from the layer).

This global/project/layer scope is used so often there's even a shortcut for it:

context=QgsExpressionContext()
context.appendScopes(
QgsExpressionContextUtils.globalProjectLayerScopes( my_layer ) )

( this expands out to the same as adding the global, project, layer
scopes individually by hand)

***IMPORTANT***

Keep in mind the order of scopes when you're adding them. You always
want to go from "most generic" to "most specific". I.e., you want
global variables to be overridden by project variables, to be
overridden by layer variables (and not the opposite).

A documentation update covering this would be most welcome ;)

Nyall





>
> I'd appreciate any examples!
>
> Regards,
> Anita
>
> [0] https://anitagraser.com/pyqgis-101-introduction-to-qgis-python-programming-for-non-programmers/pyqgis-101-using-expressions-to-compute-new-field-values/
> [1] https://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/expressions.html#evaluating-expressions
> _______________________________________________
> QGIS-Developer mailing list
> QGIS-Developer at lists.osgeo.org
> List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
> Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer


More information about the QGIS-Developer mailing list