The code snippets on this page needs the following imports if you’re outside the pyqgis console:

from qgis.core import (
   edit,
   QgsExpression,
   QgsExpressionContext,
   QgsFeature,
   QgsFeatureRequest,
   QgsField,
   QgsFields,
   QgsVectorLayer,
   QgsPointXY,
   QgsGeometry,
   QgsProject,
   QgsExpressionContextUtils
)

Expressões, filtragem e cálculo dos valores

O QGIS possui alguns recursos para análise de expressões semelhantes à SQL. Apenas um pequeno subconjunto da sintaxe SQL é suportado. As expressões podem ser avaliadas tanto como predicados booleanos (retornando Verdadeiro ou Falso) ou como funções (retornando um valor escalar) . Veja Expressões no Manual do Usuário para uma lista completa das funções disponíveis.

Três tipos básicos são suportados:

  • número — ambos os números inteiros e números decimais, por exemplo, 123, 3.14

  • texto — eles devem estar entre aspas simples: ‘Olá world’`

  • coluna referência — ao avaliar, a referência é substituída com o valor real do campo. Os nomes não alteram.

As seguintes operações estão disponíveis:

  • operadores aritméticos: +, -, *, /, ^

  • parênteses: para fazer cumprir a precedência do operador: (1 + 1) * 3

  • Sinal mais e menos: -12, +5

  • funções matemáticas: sqrt, sen, cos, tan, asen, acos, atan

  • Funções de conversão: “to_int”, “to_real”, “to_string”, “to_date”

  • funções geométricas: $area, $length

  • funções de manipulação de geometria: “$x”, “$y”, “$geometry”, “num_geometries”, “centroid”

E os seguintes predicados são suportados:

  • comparação: =, !=, >, >=, <, <=

  • correspondência padrão: LIKE (usando % e _), ~ (expressões regulares)

  • predicados lógicos: AND, OR, NOT

  • verificação de valor nulo: IS NULL, IS NOT NULL

Exemplos de predicados:

  • 1 + 2 = 3

  • sen(ângulo) > 0

  • 'Hello' LIKE 'He%'

  • (x > 10 AND y > 10) OR z = 0

Exemplos de expressões escalares:

  • 2 ^ 10

  • sqrt(val)

  • $length + 1

Expressões de Análise

The following example shows how to check if a given expression can be parsed correctly:

exp = QgsExpression('1 + 1 = 2')
assert(not exp.hasParserError())

exp = QgsExpression('1 + 1 = ')
assert(exp.hasParserError())

assert(exp.parserErrorString() == '\nsyntax error, unexpected $end')

Expressões de Avaliação

Expressions can be used in different contexts, for example to filter features or to compute new field values. In any case, the expression has to be evaluated. That means that its value is computed by performing the specified computational steps, which can range from simple arithmetic to aggregate expressions.

Expressões Básicas

This basic expression evaluates to 1, meaning it is true:

exp = QgsExpression('1 + 1 = 2')
assert(exp.evaluate())

Expressões com características

To evaluate an expression against a feature, a QgsExpressionContext object has to be created and passed to the evaluate function in order to allow the expression to access the feature’s field values.

The following example shows how to create a feature with a field called “Column” and how to add this feature to the expression context.

fields = QgsFields()
field = QgsField('Column')
fields.append(field)
feature = QgsFeature()
feature.setFields(fields)
feature.setAttribute(0, 99)

exp = QgsExpression('"Column"')
context = QgsExpressionContext()
context.setFeature(feature)
assert(exp.evaluate(context) == 99)

The following is a more complete example of how to use expressions in the context of a vector layer, in order to compute new field values:

from qgis.PyQt.QtCore import QVariant

# create a vector layer
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()

# add data to the first three fields
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)

# 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"))')

# 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
context = QgsExpressionContext()
context.appendScopes(QgsExpressionContextUtils.globalProjectLayerScopes(vl))

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)

print( f['Sum'])

Filtering a layer with expressions

O exemplo seguinte pode ser usado para filtrar uma camada e devolver qualquer característica que corresponda a um predicado.

layer = QgsVectorLayer("Point?field=Test:integer",
                           "addfeat", "memory")

layer.startEditing()

for i in range(10):
    feature = QgsFeature()
    feature.setAttributes([i])
    assert(layer.addFeature(feature))
layer.commitChanges()

expression = 'Test >= 3'
request = QgsFeatureRequest().setFilterExpression(expression)

matches = 0
for f in layer.getFeatures(request):
   matches += 1

assert(matches == 7)

Handling expression errors

Expression-related errors can occur during expression parsing or evaluation:

exp = QgsExpression("1 + 1 = 2")
if exp.hasParserError():
   raise Exception(exp.parserErrorString())

value = exp.evaluate()
if exp.hasEvalError():
   raise ValueError(exp.evalErrorString())