Re: [QGIS-Developer] Expressions with aggregate in PyQGIS

2019-05-25 Thread Anita Graser
Hi,

I've started a PR with the aggregate expression example here:
https://github.com/qgis/QGIS-Documentation/pull/3769

Regards,
Anita




On Tue, May 21, 2019 at 12:15 AM Nyall Dawson 
wrote:

> On Tue, 21 May 2019 at 05:53, Anita Graser  wrote:
> >
> > Dear Nyall,
> >
> > for f in vl.getFeatures():
> > scope[-1].setFeature(f)
>
> This works, but isn't very nice. Better to use
>
> context.setFeature(f)
>
> (behind the scenes it's doing the same, but is more descriptive and
> has some extra checks, e.g. starting with an empty context:
> context = QgsExpressionContext()
> context.setFeature(f)
> will automatically add an initial scope in which to set the feature)
>
> > scope = QgsExpressionContextUtils.globalProjectLayerScopes(vl)
>
> Being pedantic, this should be "scopes = ...", since the call returns
> a list of scopes.
>
> Nyall
>
___
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

Re: [QGIS-Developer] Expressions with aggregate in PyQGIS

2019-05-20 Thread Nyall Dawson
On Tue, 21 May 2019 at 05:53, Anita Graser  wrote:
>
> Dear Nyall,
>
> for f in vl.getFeatures():
> scope[-1].setFeature(f)

This works, but isn't very nice. Better to use

context.setFeature(f)

(behind the scenes it's doing the same, but is more descriptive and
has some extra checks, e.g. starting with an empty context:
context = QgsExpressionContext()
context.setFeature(f)
will automatically add an initial scope in which to set the feature)

> scope = QgsExpressionContextUtils.globalProjectLayerScopes(vl)

Being pedantic, this should be "scopes = ...", since the call returns
a list of scopes.

Nyall
___
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

Re: [QGIS-Developer] Expressions with aggregate in PyQGIS

2019-05-20 Thread Anita Graser
Dear Nyall,

On Mon, May 20, 2019 at 9:01 AM Anita Graser  wrote:

> Thank you Nyall, that's really helpful! The expression system is awesome
> and powerful but I don't think anyone could guess how to use it correctly
> in PyQGIS.
> I'll write it up into a tutorial and the documentation team is always
> welcome to reuse the content in the official documentation.
>

The following code works for me. However, I'm uncertain if the
scope.setFeature approach below is how it's meant to be used. Is there
something I should change?

context = QgsExpressionContext()
scope = QgsExpressionContextUtils.globalProjectLayerScopes(vl)
context.appendScopes(scope)

expression1 = QgsExpression('Revenue/Employees')
expression2 = QgsExpression('sum(Revenue)')

vl.startEditing()

for f in vl.getFeatures():
scope[-1].setFeature(f)
f['Rev. per employee'] = expression1.evaluate(context)
f['Sum'] = expression2.evaluate(context)
vl.updateFeature(f)

vl.commitChanges()

Regards,
Anita
___
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

Re: [QGIS-Developer] Expressions with aggregate in PyQGIS

2019-05-20 Thread matteo

> I agree. I'm only hesitant since I don't have a doc writing setup on my
> Windows machine yet and the instructions seem to be Linux only. 

actually there are linux only instructions only if you want to run test
locally. Once you make a pull request, travis runs also for code snippets

> I'll see what I can do. Otherwise, I'll get back to you with the content
> and ask for help integrating it.

yep!

Cheers

Matteo
___
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

Re: [QGIS-Developer] Expressions with aggregate in PyQGIS

2019-05-20 Thread Anita Graser
On Mon, May 20, 2019 at 9:41 AM matteo  wrote:

> Hi Anita,
>
> you hit a good missing topic in the pyqgis documentation. I see very
> often people asking for support on Expressions and their use in pyqgis.
>
> What do you think to add the example also in the pyqgis documentation
> directly? Since the last meeting we also have the test framework ready
> to go [0] that helps a lot to have strong code snippet.
>
> Having all the pieces in one box is the best solution IMHO
>

I agree. I'm only hesitant since I don't have a doc writing setup on my
Windows machine yet and the instructions seem to be Linux only.

I'll see what I can do. Otherwise, I'll get back to you with the content
and ask for help integrating it.

Regards,
Anita




>
> Cheers and thanks
>
> Matteo
>
> [0]
>
> https://docs.qgis.org/testing/en/docs/documentation_guidelines/cookbook_guidelines.html
>
> On 5/20/19 9:01 AM, Anita Graser wrote:
> >
> >
> > On Mon, May 20, 2019 at 2:37 AM Nyall Dawson  > > wrote:
> >
> > On Mon, 20 May 2019 at 01:21, Anita Graser  > > wrote:
> > > 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:
> > ...
> >
> > A documentation update covering this would be most welcome ;)
> >
> >
> > Thank you Nyall, that's really helpful! The expression system is awesome
> > and powerful but I don't think anyone could guess how to use it
> > correctly in PyQGIS.
> >
> > I'll write it up into a tutorial and the documentation team is always
> > welcome to reuse the content in the official documentation.
> >
> > Regards,
> > Anita
> >
> >
> >
> > ___
> > QGIS-Developer mailing list
> > QGIS-Developer@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@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@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

Re: [QGIS-Developer] Expressions with aggregate in PyQGIS

2019-05-20 Thread Anita Graser
On Mon, May 20, 2019 at 2:37 AM Nyall Dawson  wrote:

> On Mon, 20 May 2019 at 01:21, Anita Graser  wrote:
> > 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:
> ...

A documentation update covering this would be most welcome ;)


Thank you Nyall, that's really helpful! The expression system is awesome
and powerful but I don't think anyone could guess how to use it correctly
in PyQGIS.

I'll write it up into a tutorial and the documentation team is always
welcome to reuse the content in the official documentation.

Regards,
Anita
___
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

Re: [QGIS-Developer] Expressions with aggregate in PyQGIS

2019-05-19 Thread Mathieu Pellerin
This is such an instructive reply it should be added to stackexchange
straight away! :)

On Mon, May 20, 2019, 07:37 Nyall Dawson  wrote:

> On Mon, 20 May 2019 at 01:21, Anita Graser  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@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@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@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

Re: [QGIS-Developer] Expressions with aggregate in PyQGIS

2019-05-19 Thread Nyall Dawson
On Mon, 20 May 2019 at 01:21, Anita Graser  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@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@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

[QGIS-Developer] Expressions with aggregate in PyQGIS

2019-05-19 Thread Anita Graser
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].

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@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer