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
)

式、フィルタ適用および値の算出

QGISでは、SQL風の式の構文解析について少しサポートしています。サポートされるのはSQL構文の小さなサブセットのみです。式は、ブール述語(真または偽を返す)または関数(スカラー値を返す)のどちらかとして評価できます。使用可能な関数の完全なリストについては、ユーザーマニュアル中の を参照。

3つの基本的な種別がサポートされています:

  • 数値 --- 実数及び10進数。例. 123, 3.14

  • 文字列 --- 一重引用符で囲む必要があります: 'hello world'

  • 列参照 --- 評価する際に、参照は項目の実際の値で置き換えられます。名前はエスケープされません。

次の演算子が利用可能です:

  • 算術演算子: +, -, *, /, ^

  • 丸括弧: 演算を優先します: (1 + 1) * 3

  • 単項のプラスとマイナス: -12, +5

  • 数学的関数: sqrt, sin, cos, tan, asin, acos, atan

  • 変換関数: to_intto_realto_stringto_date

  • ジオメトリ関数: $area, $length

  • ジオメトリ処理関数: $x$y$geometrynum_geometriescentroid

以下の述語がサポートされています:

  • 比較: =, !=, >, >=, <, <=

  • パターンマッチング: LIKE (% と _ を使用), ~ (正規表現)

  • 論理述語: AND, OR, NOT

  • NULL 値チェック: IS NULL, IS NOT NULL

述語の例:

  • 1 + 2 = 3

  • sin(angle) > 0

  • 'Hello' LIKE 'He%'

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

スカラー式の例:

  • 2 ^ 10

  • sqrt(val)

  • $length + 1

式を構文解析する

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

式を評価する

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.

基本式

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

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

地物に関わる式

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

次の例はレイヤーをフィルタリングして述語に一致する任意の地物を返します。

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())