표현식을 이용한 속성값의 필터링 및 계산

QGIS has some support for parsing of SQL-like expressions. Only a small subset of SQL syntax is supported. The expressions can be evaluated either as boolean predicates (returning True or False) or as functions (returning a scalar value).

다음 3가지 기본 유형이 지원됩니다.

  • 숫자 — 정수와 십진수, 예를 들면 123, 3.14

  • 문자열 — 'hello world' 처럼 작은 따옴표로 둘러싸야 함

  • 컬럼 참조 — 표현식을 평가할 때, 참조가 필드의 실제 값으로 대체됩니다. 이름이 그대로 남지 않습니다.

다음과 같은 연산자들이 있습니다.

  • 산술 연산자: +, -, *, /, ^

  • 괄호: (1 + 1) * 3 처럼 연산의 우선 순위를 강제합니다.

  • 단항 플러스 및 마이너스: -12, +5

  • 수학 함수: sqrt, sin, cos, tan, asin, acos, atan

  • 도형 함수: $area, $length

  • conversion functions: to int, to real, to string

다음과 같은 서술어들를 지원합니다.

  • 비교: =, !=, >, >=, <, <=

  • 패턴 매칭: 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

표현식 파싱하기

>>> 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
1

피처와 표현식

다음은 어떤 피처에 대해 주어진 표현식으로 평가하는 예시 코드입니다. “Column”은 레이어의 필드명입니다.

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

피처를 하나 이상 확인해야 할 경우 QgsExpression.prepare() 함수를 사용할 수도 있습니다. QgsExpression.prepare() 함수를 사용하면 평가를 실행하는 데 걸리는 시간이 단축될 것입니다.

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

오류 처리

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

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

print value

예제

다음 예시 코드는 레이어를 필터링해서 서술어와 일치하는 모든 피처를 반환하는 작업에 사용할 수 있습니다.

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"