[QGIS-Developer] Expressions with aggregate in PyQGIS

Mathieu Pellerin nirvn.asia at gmail.com
Sun May 19 17:44:24 PDT 2019


This is such an instructive reply it should be added to stackexchange
straight away! :)

On Mon, May 20, 2019, 07:37 Nyall Dawson <nyall.dawson at gmail.com> wrote:

> 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
> _______________________________________________
> 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20190520/40465507/attachment.html>


More information about the QGIS-Developer mailing list