Выражения, фильтрация и вычисление значений

QGIS может выполнять разбор и анализ SQL-подобных выражений. Поддерживается ограниченное подмножество языка SQL. Выражения могут рассматриваться как логические предикаты (возвращающие True или False) или как функции (возвращающие скалярное значение).

Поддерживается три основных типа данных:

  • число — как целые, так и десятичные, например, 123, 3.14

  • строка — должна заключаться в одинарные кавычки: 'hello world'

  • ссылка на столбец — при вычислении ссылка заменяется на значение поля. Имена полей не экранируются.

Доступны следующие операции:

  • арифметические операторы: +, -, *, /, ^

  • скобки: для изменения приоритета операций: (1 + 1) * 3

  • унарный плюс и минус: -12, +5

  • математические функции: sqrt, sin, cos, tan, asin, acos, atan

  • геометрические функции: $area, $length

  • функции преобразования типа: to int, to real, to string

Поддерживаются предикаты:

  • сравнение: =, !=, >, >=, <, <=

  • соответствие образцу: LIKE (using % and _), ~ (регулярные выражения)

  • огические операторы: AND, OR, NOT

  • проверка на NULL: IS NULL, IS NOT NULL

Примечание по совместимости: математические и геометрические функции, функции преобразования типа и оператор возведения в степень ^ доступны начиная с QGIS 1.4.

Примеры предикатов:

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

Примеры скалярных выражений:

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

Разбор выражений

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

Вычисление выражений

Простые выражения

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

Выражения с объектами

В этих примерах выражение проверяется относительно объекта. “Column” это имя поля атрибутивной таблицы слоя.

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

Если необходимо проверить несколько объектов, стоит использовать функцию QgsExpression.prepare(). Использование QgsExpression.prepare() повысит скорость анализа выражений.

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

Обработка ошибок

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

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

value.toInt()

Примеры

Следующие примеры могут использоваться для фильтрации слоя и возвращения объектов, удовлетворяющих условию.

def where(layer, exp):
  print "Where"
  exp = QgsExpression(exp)
  if exp.hasParserError():
    raise Expection(exp.parserErrorString())
  exp.prepare(layer.pendingFields())
  feature = QgsFeature()
  layer.select(layer.pendingAllAttributesList())
  while layer.nextFeature(feature):
    value = exp.evaluate(feature)
  if exp.hasEvalError():
    raise ValueError(exp.evalErrorString())
    if value.toBool():
      yield feature

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