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
)
Expresii, filtrarea și calculul valorilor¶
QGIS are un oarecare suport pentru analiza expresiilor, cum ar fi SQL. Doar un mic subset al sintaxei SQL este acceptat. Expresiile pot fi evaluate fie ca predicate booleene (returnând True sau False), fie ca funcții (care întorc o valoare scalară). Parcurgeți Expresii din Manualul Utilizatorului, pentru o listă completă a funcțiilor disponibile.
Trei tipuri de bază sunt acceptate:
— număr atât numere întregi cât și numere zecimale, de exemplu,
123
,3.14
șir — acesta trebuie să fie cuprins între ghilimele simple:
'hello world'
referință către coloană — atunci când se evaluează, referința este substituită cu valoarea reală a câmpului. Numele nu sunt protejate.
Următoarele operațiuni sunt disponibile:
operatori aritmetici:
+
,-
,*
,/
,^
paranteze: pentru forțarea priorității operatorului:
(1 + 1) * 3
plus și minus unari:
-12
,+5
funcții matematice:
sqrt
,sin
,cos
,tan
,asin
,acos
,atan
funcții de conversie:
to_int
,to_real
,to_string
,to_date
funcții geometrice:
$area
,$length
funcții de manipulare a geometriei:
$x
,$y
,$geometry
,num_geometries
,centroid
Și următoarele predicate sunt suportate:
comparație:
=
,!=
,>
,>=
,<
,<=
potrivirea paternurilor:
LIKE
(folosind % și _),~
(expresii regulate)predicate logice:
AND
,OR
,NOT
verificarea valorii NULL:
IS NULL
,IS NOT NULL
Exemple de predicate:
1 + 2 = 3
sin(angle) > 0
'Hello' LIKE 'He%'
(x > 10 AND y > 10) OR z = 0
Exemple de expresii scalare:
2 ^ 10
sqrt(val)
$length + 1
Parsarea expresiilor¶
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')
Evaluarea expresiilor¶
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.
Expresii de bază¶
This basic expression evaluates to 1, meaning it is true:
exp = QgsExpression('1 + 1 = 2')
assert(exp.evaluate())
Expresii cu entități¶
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¶
Următorul exemplu poate fi folosit pentru a filtra un strat și pentru a întoarce orice entitate care se potrivește unui predicat.
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())