Advertisements

 

Previously, we already covered how to create vector layers, how to add fields to their attribute table, and how to set the field values. This time, instead of setting the fields to some preset values, we’ll be using QGIS expressions to compute the values.

First, let’s create a vector layer with three features! The layer creation code reuses things we’ve already covered in previous examples:

from qgis.PyQt.QtCore import QVariant

vl = QgsVectorLayer("Point", "Companies", "memory")

pr = vl.dataProvider()
pr.addAttributes([QgsField("Name", QVariant.String),
                  QgsField("Employees",  QVariant.Int),
                  QgsField("Revenue", QVariant.Double),
                  QgsField("Rev. per employee", QVariant.Double),
                  QgsField("Sum", QVariant.Double),
                  QgsField("Fun", QVariant.Double)])
vl.updateFields()

my_data = [
    {'x': 0, 'y': 0, 'name': 'ABC', 'emp': 10, 'rev': 100.1},
    {'x': 1, 'y': 1, 'name': 'DEF', 'emp': 2, 'rev': 50.5},
    {'x': 5, 'y': 5, 'name': 'GHI', 'emp': 100, 'rev': 725.9}]
           
for rec in my_data:
    f = QgsFeature()
    pt = QgsPointXY(rec['x'], rec['y'])
    f.setGeometry(QgsGeometry.fromPointXY(pt))
    f.setAttributes([rec['name'], rec['emp'], rec['rev']])
    pr.addFeature(f)

vl.updateExtents() 
QgsProject.instance().addMapLayer(vl)

Open the attribute table and you’ll see that the last three fields are empty.

Let’s fill them with expressions!

The expression syntax is exactly the same as in the field calculator GUI. So you can test them in the GIU first, before copying them into your PyQGIS script.

The first expression computes the revenue per employee. The second one computes the sum of all revenue values in the layer. The final third expression doesn’t really make sense but illustrates the fact that we can use a wide range of expression functions, such as area and buffer in our expressions:

expression1 = QgsExpression('Revenue/Employees')
expression2 = QgsExpression('sum(Revenue)')
expression3 = QgsExpression('area(buffer($geometry,Employees))')

To execute our expressions, we need to provide an appropriate QgsExpressionContext. To set it up, use:

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

(QgsExpressionContextUtils.globalProjectLayerScopes() is a convenience function that adds the global, project, and layer scopes all at once. Alternatively, those scopes can also be added manually. In any case, it is important to always go from “most generic” to “most specific” scope, i.e. from global to project to layer.)

Now we’re ready! We can loop through the layer features and apply the expressions by calling their evaluate() function:

with edit(vl):
    for f in vl.getFeatures():
        context.setFeature(f)
        f['Rev. per employee'] = expression1.evaluate(context)
        f['Sum'] = expression2.evaluate(context)
        f['Fun'] = expression3.evaluate(context)
        vl.updateFeature(f)

However, this is not the only way to compute field values. Alternatively, you can also use pure Python, for example:

with edit(vl):
    for f in vl.getFeatures():
        f['Rev. per employee'] = f['Revenue'] / f['Employees']
        vl.updateFeature(f)

These are the basics of using QGIS expressions as well as pure Python to compute field values in PyQGIS. You can use both of these options depending on your preferences and specific requirements of your project.

Next


PyQGIS 101 is a work in progress. I’d appreciate any feedback, particularly from beginners!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: