Expressions, Filtrage et Calcul de valeurs

QGIS propose quelques fonctionnalités pour faire de l’analyse syntaxique d’expressions semblable au SQL. Seulement un petit sous-ensemble des syntaxes SQL est géré. Les expressions peuvent être évaluées comme des prédicats booléens (retournant Vrai ou Faux) ou comme des fonctions (retournant une valeur scalaire).

Trois types basiques sont supportés :

  • nombre — aussi bien les nombres entiers que décimaux, par exemple 123, 3.14

  • texte — ils doivent être entre guillemets simples: 'hello world'

  • référence de colonne — lors de l’évaluation, la référence est remplacée par la valeur réelle du champ. Les noms ne sont pas échappés.

Les opérations suivantes sont disponibles:

  • opérateurs arithmétiques: +, -, *, /, ^

  • parenthèses: pour faire respecter la précédence des opérateurs: (1 + 1) * 3

  • les unaires plus et moins: -12, +5

  • fonctions mathématiques: sqrt, sin, cos, tan, asin, acos, atan

  • fonctions géométriques: $area, $length

  • fonctions de conversion: to int, to real, to string

Et les prédicats suivants sont pris en charge:

  • comparaison: =, !=, >, >=, <, <=

  • comparaison partielle: LIKE (avec % ou _), ~ (expressions régulières)

  • prédicats logiques: AND, OR, NOT

  • Vérification de la valeur NULL: IS NULL, IS NOT NULL

Exemples de prédicats:

  • 1 + 2 = 3
  • sin(angle) > 0
  • 'Hello' LIKE 'He%'
  • (x > 10 AND y > 10) OR z = 0

Exemples d’expressions scalaires:

  • 2 ^ 10
  • sqrt(val)
  • $length + 1

Analyse syntaxique d’expressions

>>> exp = QgsExpression('1 + 1 = 2')
>>> exp.hasParserError()
False
>>> exp = QgsExpression('1 + 1 = ')
>>> exp.hasParserError()
True
>>> exp.parserErrorString()
PyQt4.QtCore.QString(u'syntax error, unexpected $end')

Évaluation des expressions

Expressions basiques

>>> exp = QgsExpression('1 + 1 = 2')
>>> value = exp.evaluate()
>>> value
1

Expressions avec entités

L’exemple suivant évaluera l’expression renseignée sur une entité. “Colonne” est le nom du champ de la couche.

>>> exp = QgsExpression('Column = 99')
>>> value = exp.evaluate(feature, layer.pendingFields())
>>> bool(value)
True

Vous pouvez aussi utiliser QgsExpression.prepare() si vous avez besoin de vérifier plus d’une entité. Utiliser QgsExpression.prepare() accélérera le temps d’évaluation.

>>> exp = QgsExpression('Column = 99')
>>> exp.prepare(layer.pendingFields())
>>> value = exp.evaluate(feature)
>>> bool(value)
True

Gestion des erreurs

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

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

print value

Exemples

L’exemple suivant peut être utilisé pour filtrer une couche et ne renverra que les entités qui correspondent au prédicat.

def where(layer, exp):
  print "Where"
  exp = QgsExpression(exp)
  if exp.hasParserError():
    raise Exception(exp.parserErrorString())
  exp.prepare(layer.pendingFields())
  for feature in layer.getFeatures():
    value = exp.evaluate(feature)
    if exp.hasEvalError():
      raise ValueError(exp.evalErrorString())
    if bool(value):
      yield feature

layer = qgis.utils.iface.activeLayer()
for f in where(layer, 'Test > 1.0'):
  print f + " Matches expression"