Expressions are one of the most powerful features of QGIS. In this hands-on workshop, we will start from the basics of expression syntax and you will learn how to solve complex problems by combining the basic building blocks.
This workshop requires basic working knowledge of QGIS.
This workshop requires QGIS LTR version 3.40.
Please review QGIS-LTR Installation Guide for step-by-step instructions.
The code examples in this workshop use a variety of datasets. All the
required layers, project files etc. are supplied to you in the zip file
qgis-expressions.zip
. Unzip this file to the
Downloads
directory.
The data package also comes with a solutions
folder that
contains model solutions for each section.
Download qgis-expressions.zip.
In this section, we will learn about operators and conditions used in QGIS expressions and learn how to use them to select and extract features from layers.
power_plants
containing locations of all power plants in the world and a polygon
layer named admin1
with states/province boundaries for all
countries.power_plants
layer and click Open
Attribute Table button. You will see that the layer as a column
named primary_fuel
describing the primary energy source
used in electricity generation. We can use this to select different
types of power plants."primary_fuel" = 'Coal'
"primary_fuel" IN ('Biomass', 'Geothermal', 'Hydro', 'Solar', 'Wind', 'Storage', 'Wave and Tidal')
power_plants
as the Input layer. Click the
Expression button.hydro_power_plants.gpkg
and click Run.hydro_power_plants
will be added to the Layers
panel. Open the attribute table and verify that all the power plants
have Hydro as the primary_fuel
. Next, we will
learn how to classify these power plants based on their capacity. The
column capacity_mw
has electrical generating capacity in
megawatts. You may now turn off the visibility of the
power_plants
layer.hydro_power_plants
layer. From the
Processing Toolbox, search and locate the algorithm Vector table
→ Field calculator and double-click to launch it.hydro_power_plants
as the Input Layer. Enter
classification as the Field name. Keep
Text (string) as the Result field type.CASE
statement to assign different values based on
different conditions. Enter the following expression.CASE
WHEN "capacity_mw" < 25 THEN 'Small'
WHEN "capacity_mw" >= 25 AND "capacity_mw" <= 100 THEN 'Medium'
WHEN "capacity_mw" > 100 THEN 'Large'
END
hydro_power_plants_classification.gpkg
and click
Run.hydro_power_plants_classification
will be added to the
Layers panel. Open the attribute table and see the assigned
values in the classification column.We have now finished the first part of this exercise. You can load
the Power_Plants_CheckPoint1.qgz
project in the
solutions
folder to catch up to this point and do the
challenge.
Create a new layer containing only the Large hydro
power plants in your country. The country
column contains
3-digit ISO codes for each country. Pick a country and build an
expression to extract the features.
We will now learn how to use the expression functions for spatial analysis. Our goal will be to get a list of hydro power plants and the total installed capacity for each admin1 region in a country.
admin1
and hydro_power_plants_classification
layers. We will now apply a filter to each of these layers to keep only
the features for our chosen country. Right=click the
hydro_power_plants_classification
layer and choose
Filter…."country" = 'SWE'
admin1
layer and select
Filter…."adm0_a3" = 'SWE'
hydro_power_plants_classification
layer and open the
Attribute Table. Note that the column name
contains the
name of the power plant and the column capacity_mw
contains
the power generation capacity.admin1
layer and open the Processing Toolbox
from Processing → Toolbox. Search and locate the
algorithm Vector table → Field calculator and
double-click to launch it.admin1
as the Input Layer. Enter
power_plants_list as the Field name. Select
String List as the Result field type.overlay_intersect()
function
allows you to locate intersecting features from another layer. Enter the
following expression.overlay_intersects(
layer:='hydro_power_plants_classification',
expression:="name"
)
hydro_power_plant_list.gpkg
and click Run.hydro_power_plant_list
will be added to the Layers
panel. Open the attribute table and verify that the
power_plants_list has the list of intersecting power plant
names. Next, we will add another column with the total capacity for each
region. Open the Vector table → Field calculator
algorithm from the Processing Toolbox.admin1_power_plant_list
as the Input Layer. Enter
total_hydro_capacity as the Field name. Select
Decimal (double) as the Result field
type.overlay_intersects()
function to get a list of values for
the capacity_mw attribute for all intersecting power plant
features. As we want to calculate the total capacity, we can use the
array_sum()
function to calculate the total. Enter the
following expression.array_sum(
overlay_intersects(
layer:='hydro_power_plants_classification',
expression:="capacity_mw"
)
)
hydro_power_plant_capacity.gpkg
and click
Run.hydro_power_plant_capacity
will be added to the
Layers panel. Open the attribute table and you will notice that
the total_hydro_capacity has the sum of the capacities of all
hydro power plants within each region.name
,
power_plants_list
and total_hydro_capacity
fields. Click the … next to Refactored and select
Save to File….admin1_hydro_power_plant_data
and click Save.You can load the Power_Plants_CheckPoint2.qgz
project in
the solutions
folder to catch up to this point and do the
challenge.
Add a new column power_plant_count with the total number of hydro power plants in each admin1 region.
Hint: Look under the array_
section to find a suitable
function for calculating number of items in a list.
In this section, we will learn how to create and manipulate feature geometry using expressions. The QGIS expression engine comes with a large number of functions that can be used to create, update, transform geometries of features.
schools
has the
locations schools and the layer colleges
has locations of
all the colleges in the state of Kerala, India. Our goal for this
section is to connect each school point to the nearest college point
with a line.schools
layer and click the Open the
Layer Styling Panel button. The layer is styled using the
Simple Marker symbol layer. Click the Add symbol
layer / + button.overlay_nearest()
function allows us to find nearest
features from another layer. We build an expression to find the
@geometry
of the nearest college and then use the
make_line()
function to create a line from the school point
to the nearest college point. Enter the following expression and click
OK.make_line(
@geometry,
overlay_nearest(
layer:='colleges',
expression:=@geometry,
limit:=1
)
)
overlay_nearest()
function has an optional
parameter max_distance
that allows us to specify the
maximum search distance and only return the feature from another layer
within the specified distance. Let’s update the expression to find the
nearest college within 5km (5000 meters) distance.make_line(
@geometry,
overlay_nearest(
layer:='colleges',
expression:=@geometry,
limit:=1,
max_distance:=5000
)
)
We have now finished this section. You can load the
Nearest_Neighbor_CheckPoint1.qgz
project in the
solutions
folder to catch up to this point and do the
challenge.
The Processing Toolbox comes with a handy tool called Geometry by
expression. This algorithm allows you to take an input layer and
create a new layer by transforming the geometries using expression. Use
this tool to create a new layer
schools_with_nearest_college.gpkg
showing the connections
from school points to the nearest college.
The QGIS expression engine has array functions that allow you to
iterate and process each item from the array using expressions. This
enables some very powerful use-cases. In this section we will explore
the array_foreach()
and array_filter()
functions.
schools
layer and open the Vector table → Field
calculator algorithm from the Processing Toolbox.schools
as the Input Layer. Enter
colleges as the Field name. Select
String List as the Result field type.overlay_nearest(
layer:='colleges',
expression:="collegename",
max_distance:=5000,
limit:=-1
)
array_foreach()
function which allows us to run an
expression on each item. Within the function, you refer to each item in
the array with the variable @element
. Update the expression
as below.array_foreach(
overlay_nearest(
layer:='colleges',
expression:="collegename",
max_distance:=5000,
limit:=-1
),
title(@element)
)
nearest_colleges.gpkg
and click Run.nearest_colleges
will be added to the Layers
panel. Open the attribute table and you will notice that the
colleges column has the list of colleges in title case. Open
the Vector table → Field calculator algorithm
again.nearest_colleges
as the Input Layer. Enter
science_colleges as the Field name. Select
String List as the Result field type.array_filter()
function to iterate through each
item and check if the text is present. This can be achieved using the
regexp_match()
function. Enter the expression as
below.array_filter(
array_foreach(
overlay_nearest(
layer:='colleges',
expression:="collegename",
max_distance:=5000,
limit:=-1
),
title(@element)
),
regexp_match(@element, 'Science')
)
nearest_science_colleges.gpkg
and click Run.nearest_science_colleges
will be added to the
Layers panel. Open the attribute table and you will notice that
the science_colleges column has the list of colleges containing
the keyword Science.nearest_colleges
and
nearest_science_colleges
layers. Right-click and select
Remove Layer.schools
layer and click the Open the Layer Styling
Panel button. Select the Geometry Generator symbol
layer.overlay_nearest()
function to return
us the list of @feature
instead of @geometry
.
This will allow us to run the filter on the attributes. We then use
array_filter()
to select all college features where the
value of district is the same as the value of district
for the school. Finally we select the first matching feature using
[0]
and use geometry()
to extract the geometry
of the feature. The final expression for creating a line from the school
to the nearest college in the same district is as follows.make_line(
@geometry,
geometry(array_filter(
overlay_nearest(
layer:='colleges',
expression:=@feature,
max_distance:=5000,
limit:=-1
),
"district"=attribute(@element, 'district'))[0])
)
You can now load the Nearest_Neighbor_CheckPoint2.qgz
project in the solutions
folder to catch up to this point
and do the challenge.
You will notice that there are many schools with no connection to colleges. The challenge is select all schools which have no nearby college in the same district. You can use the Select by expression algorithm in the Processing Toolbox to select features using an expression.
This workshop material is licensed under a Creative Commons Attribution 4.0 International (CC BY 4.0). You are free to re-use and adapt the material but are required to give appropriate credit to the original author as below:
QGIS Expressions Masterclass by Ujaval Gandhi www.spatialthoughts.com
If you want to report any issues with this page, please comment below.