Viktigt
Översättning är en gemenskapsinsats du kan gå med i. Den här sidan är för närvarande översatt till 100.00%.
11. Uttryck, filtrering och beräkning av värden
Råd
Kodsnuttarna på den här sidan behöver följande import om du befinner dig utanför pyqgis-konsolen:
1from qgis.core import (
2 edit,
3 QgsExpression,
4 QgsExpressionContext,
5 QgsFeature,
6 QgsFeatureRequest,
7 QgsField,
8 QgsFields,
9 QgsVectorLayer,
10 QgsPointXY,
11 QgsGeometry,
12 QgsProject,
13 QgsExpressionContextUtils
14)
QGIS har visst stöd för parsning av SQL-liknande uttryck. Endast en liten delmängd av SQL-syntaxen stöds. Uttrycken kan utvärderas antingen som booleska predikat (returnerar True
eller False
) eller som funktioner (returnerar ett skalärt värde). Se Uttryck i användarhandboken för en fullständig lista över tillgängliga funktioner.
Tre grundläggande typer stöds:
tal — både heltal och decimaltal, t.ex.
123
,3,14
sträng — måste de omslutas av enkla citattecken:
'hej världen'`
kolumnreferens — vid utvärdering ersätts referensen med fältets faktiska värde. Namnen är inte escapade.
Följande funktioner är tillgängliga:
aritmetiska operatorer:
+
,-
,*
,/
,^
parenteser: för att förstärka operatörens företräde:
(1 + 1) * 3
unär plus och minus:
-12
,+5
matematiska funktioner:
qrt
,sin
,cos
,tan
,asin
,acos
,atan
omvandlingsfunktioner:
to_int
,to_real
,to_string
,to_date
geometrifunktioner:
$area
,$längd
funktioner för geometrihantering:
$x
,$y
,$geometri
,num_geometrier
,centroid
Och följande predikat stöds:
jämförelse:
=
,!=
,>
,>=
,<
,<=
mönstermatchning:
LIKE
(använder % and _),~
(reguljära uttryck)logiska predikat:
OCH
,ELLER
,INTE
Kontroll av NULL-värde:
IS NULL
,IS NOT NULL
Exempel på predikat:
1 + 2 = 3
sin(vinkel) > 0
'Hello' LIKE 'He%'`
(x > 10 OCH y > 10) ELLER z = 0`
Exempel på skalära uttryck:
2 ^ 10
sqrt(val)
$längd + 1
11.1. Parsning av uttryck
I följande exempel visas hur man kontrollerar om ett visst uttryck kan analyseras korrekt:
1exp = QgsExpression('1 + 1 = 2')
2assert(not exp.hasParserError())
3
4exp = QgsExpression('1 + 1 = ')
5assert(exp.hasParserError())
6
7assert(exp.parserErrorString() == '\nsyntax error, unexpected end of file')
11.2. Utvärdering av uttryck
Uttryck kan användas i olika sammanhang, t.ex. för att filtrera funktioner eller för att beräkna nya fältvärden. I vilket fall som helst måste uttrycket utvärderas. Det innebär att dess värde beräknas genom att utföra de angivna beräkningsstegen, som kan variera från enkel aritmetik till aggregerade uttryck.
11.2.1. Grundläggande uttryck
Detta grundläggande uttryck utvärderar en enkel aritmetisk operation:
exp = QgsExpression('2 * 3')
print(exp)
print(exp.evaluate())
<QgsExpression: '2 * 3'>
6
Uttrycket kan också användas för jämförelse och utvärderas till 1 (True
) eller 0 (False
)
exp = QgsExpression('1 + 1 = 2')
exp.evaluate()
# 1
11.2.2. Uttryck med funktioner
För att utvärdera ett uttryck mot en funktion måste ett QgsExpressionContext
-objekt skapas och skickas till evaluate-funktionen för att uttrycket ska få tillgång till funktionens fältvärden.
I följande exempel visas hur man skapar en funktion med ett fält som heter ”Column” och hur man lägger till denna funktion i uttryckskontexten.
1fields = QgsFields()
2field = QgsField('Column')
3fields.append(field)
4feature = QgsFeature()
5feature.setFields(fields)
6feature.setAttribute(0, 99)
7
8exp = QgsExpression('"Column"')
9context = QgsExpressionContext()
10context.setFeature(feature)
11exp.evaluate(context)
12# 99
Följande är ett mer komplett exempel på hur man använder uttryck i samband med ett vektorlager för att beräkna nya fältvärden:
1from qgis.PyQt.QtCore import QMetaType
2
3# create a vector layer
4vl = QgsVectorLayer("Point", "Companies", "memory")
5pr = vl.dataProvider()
6pr.addAttributes([QgsField("Name", QMetaType.Type.QString),
7 QgsField("Employees", QMetaType.Type.Int),
8 QgsField("Revenue", QMetaType.Type.Double),
9 QgsField("Rev. per employee", QMetaType.Type.Double),
10 QgsField("Sum", QMetaType.Type.Double),
11 QgsField("Fun", QMetaType.Type.Double)])
12vl.updateFields()
13
14# add data to the first three fields
15my_data = [
16 {'x': 0, 'y': 0, 'name': 'ABC', 'emp': 10, 'rev': 100.1},
17 {'x': 1, 'y': 1, 'name': 'DEF', 'emp': 2, 'rev': 50.5},
18 {'x': 5, 'y': 5, 'name': 'GHI', 'emp': 100, 'rev': 725.9}]
19
20for rec in my_data:
21 f = QgsFeature()
22 pt = QgsPointXY(rec['x'], rec['y'])
23 f.setGeometry(QgsGeometry.fromPointXY(pt))
24 f.setAttributes([rec['name'], rec['emp'], rec['rev']])
25 pr.addFeature(f)
26
27vl.updateExtents()
28QgsProject.instance().addMapLayer(vl)
29
30# The first expression computes the revenue per employee.
31# The second one computes the sum of all revenue values in the layer.
32# The final third expression doesn’t really make sense but illustrates
33# the fact that we can use a wide range of expression functions, such
34# as area and buffer in our expressions:
35expression1 = QgsExpression('"Revenue"/"Employees"')
36expression2 = QgsExpression('sum("Revenue")')
37expression3 = QgsExpression('area(buffer($geometry,"Employees"))')
38
39# QgsExpressionContextUtils.globalProjectLayerScopes() is a convenience
40# function that adds the global, project, and layer scopes all at once.
41# Alternatively, those scopes can also be added manually. In any case,
42# it is important to always go from “most generic” to “most specific”
43# scope, i.e. from global to project to layer
44context = QgsExpressionContext()
45context.appendScopes(QgsExpressionContextUtils.globalProjectLayerScopes(vl))
46
47with edit(vl):
48 for f in vl.getFeatures():
49 context.setFeature(f)
50 f['Rev. per employee'] = expression1.evaluate(context)
51 f['Sum'] = expression2.evaluate(context)
52 f['Fun'] = expression3.evaluate(context)
53 vl.updateFeature(f)
54
55print(f['Sum'])
876.5
11.2.3. Filtrera ett lager med uttryck
Följande exempel kan användas för att filtrera ett lager och returnera alla funktioner som matchar ett predikat.
1layer = QgsVectorLayer("Point?field=Test:integer",
2 "addfeat", "memory")
3
4layer.startEditing()
5
6for i in range(10):
7 feature = QgsFeature()
8 feature.setAttributes([i])
9 assert(layer.addFeature(feature))
10layer.commitChanges()
11
12expression = 'Test >= 3'
13request = QgsFeatureRequest().setFilterExpression(expression)
14
15matches = 0
16for f in layer.getFeatures(request):
17 matches += 1
18
19print(matches)
7
11.3. Hantering av uttrycksfel
Uttrycksrelaterade fel kan uppstå under parsning eller utvärdering av uttryck:
1exp = QgsExpression("1 + 1 = 2")
2if exp.hasParserError():
3 raise Exception(exp.parserErrorString())
4
5value = exp.evaluate()
6if exp.hasEvalError():
7 raise ValueError(exp.evalErrorString())