QGIS API Documentation  2.9.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
qgsexpression.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsexpression.h
3  -------------------
4  begin : August 2011
5  copyright : (C) 2011 Martin Dobias
6  email : wonder.sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #ifndef QGSEXPRESSION_H
17 #define QGSEXPRESSION_H
18 
19 #include <QMetaType>
20 #include <QStringList>
21 #include <QVariant>
22 #include <QList>
23 #include <QDomDocument>
24 
25 class QgsFeature;
26 class QgsGeometry;
27 class QgsOgcUtils;
28 class QgsVectorLayer;
30 class QgsField;
31 class QgsFields;
32 class QgsDistanceArea;
33 class QDomElement;
34 
86 class CORE_EXPORT QgsExpression
87 {
88  public:
89  QgsExpression( const QString& expr );
90  ~QgsExpression();
91 
93  bool hasParserError() const { return !mParserErrorString.isNull(); }
95  QString parserErrorString() const { return mParserErrorString; }
96 
97  class Node;
98 
100  const Node* rootNode() const { return mRootNode; }
101 
103  bool prepare( const QgsFields &fields );
104 
111  QStringList referencedColumns() const;
112 
114  bool needsGeometry() const;
115 
116  // evaluation
117 
120  QVariant evaluate( const QgsFeature* f = NULL );
121 
125  inline QVariant evaluate( const QgsFeature& f ) { return evaluate( &f ); }
126 
129  QVariant evaluate( const QgsFeature* f, const QgsFields& fields );
130 
134  inline QVariant evaluate( const QgsFeature& f, const QgsFields& fields ) { return evaluate( &f, fields ); }
135 
137  bool hasEvalError() const { return !mEvalErrorString.isNull(); }
139  QString evalErrorString() const { return mEvalErrorString; }
141  void setEvalErrorString( QString str ) { mEvalErrorString = str; }
142 
144  void setCurrentRowNumber( int rowNumber ) { mRowNumber = rowNumber; }
146  int currentRowNumber() { return mRowNumber; }
147 
149  static void setSpecialColumn( const QString& name, QVariant value );
151  static void unsetSpecialColumn( const QString& name );
153  static QVariant specialColumn( const QString& name );
156  static bool hasSpecialColumn( const QString& name );
157 
158  static bool isValid( const QString& text, const QgsFields& fields, QString &errorMessage );
159 
160  void setScale( double scale ) { mScale = scale; }
161 
162  double scale() { return mScale; }
163 
165  const QString expression() const
166  {
167  if ( !mExp.isNull() )
168  return mExp;
169  else
170  return dump();
171  }
172 
174  QString dump() const;
175 
178  QgsDistanceArea *geomCalculator() { initGeomCalculator(); return mCalc; }
179 
181  // instead of the default.
182  void setGeomCalculator( const QgsDistanceArea &calc );
183 
197  static QString replaceExpressionText( const QString &action, const QgsFeature *feat,
198  QgsVectorLayer *layer,
199  const QMap<QString, QVariant> *substitutionMap = 0,
200  const QgsDistanceArea* distanceArea = 0
201  );
202 
210  static double evaluateToDouble( const QString& text, const double fallbackValue );
211 
217  {
220  };
221 
227  {
228  // logical
231 
232  // comparison
233  boEQ, // =
234  boNE, // <>
235  boLE, // <=
236  boGE, // >=
237  boLT, // <
238  boGT, // >
246 
247  // math
255 
256  // strings
258  };
260  {
270  };
271 
272  static const char* BinaryOperatorText[];
273  static const char* UnaryOperatorText[];
274 
275  typedef QVariant( *FcnEval )( const QVariantList& values, const QgsFeature* f, QgsExpression* parent );
276 
277 
281  class CORE_EXPORT Function
282  {
283  public:
284  Function( QString fnname, int params, QString group, QString helpText = QString(), bool usesGeometry = false, QStringList referencedColumns = QStringList(), bool lazyEval = false )
285  : mName( fnname ), mParams( params ), mUsesGeometry( usesGeometry ), mGroup( group ), mHelpText( helpText ), mReferencedColumns( referencedColumns ), mLazyEval( lazyEval ) {}
287  QString name() { return mName; }
289  int params() { return mParams; }
291  bool usesgeometry() { return mUsesGeometry; }
292 
296  bool lazyEval() { return mLazyEval; }
297 
298  virtual QStringList referencedColumns() const { return mReferencedColumns; }
299 
301  QString group() { return mGroup; }
303  QString helptext() { return mHelpText.isEmpty() ? QgsExpression::helptext( mName ) : mHelpText; }
304 
305  virtual QVariant func( const QVariantList& values, const QgsFeature* f, QgsExpression* parent ) = 0;
306 
307  bool operator==( const Function& other ) const
308  {
309  if ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 )
310  return true;
311 
312  return false;
313  }
314 
315  private:
316  QString mName;
317  int mParams;
318  bool mUsesGeometry;
319  QString mGroup;
320  QString mHelpText;
321  QStringList mReferencedColumns;
322  bool mLazyEval;
323  };
324 
325  class StaticFunction : public Function
326  {
327  public:
328  StaticFunction( QString fnname, int params, FcnEval fcn, QString group, QString helpText = QString(), bool usesGeometry = false, QStringList referencedColumns = QStringList(), bool lazyEval = false )
329  : Function( fnname, params, group, helpText, usesGeometry, referencedColumns, lazyEval ), mFnc( fcn ) {}
330 
331  virtual QVariant func( const QVariantList& values, const QgsFeature* f, QgsExpression* parent ) override
332  {
333  return mFnc( values, f, parent );
334  }
335 
336  private:
337  FcnEval mFnc;
338  };
339 
340  static const QList<Function*> &Functions();
341  static QList<Function*> gmFunctions;
342 
343  static QStringList gmBuiltinFunctions;
344  static const QStringList &BuiltinFunctions();
345 
346  static bool registerFunction( Function* function );
347  static bool unregisterFunction( QString name );
348 
349  // tells whether the identifier is a name of existing function
350  static bool isFunctionName( QString name );
351 
352  // return index of the function in Functions array
353  static int functionIndex( QString name );
354 
358  static int functionCount();
359 
363  static QList<Function*> specialColumns();
364 
366  static QString quotedColumnRef( QString name );
368  static QString quotedString( QString text );
369 
371 
372  class Visitor; // visitor interface is defined below
373 
374  enum NodeType
375  {
382  ntCondition
383  };
384 
385  class CORE_EXPORT Node
386  {
387  public:
388  virtual ~Node() {}
389  virtual NodeType nodeType() const = 0;
390  // abstract virtual eval function
391  // errors are reported to the parent
392  virtual QVariant eval( QgsExpression* parent, const QgsFeature* f ) = 0;
393 
394  // abstract virtual preparation function
395  // errors are reported to the parent
396  virtual bool prepare( QgsExpression* parent, const QgsFields &fields ) = 0;
397 
398  virtual QString dump() const = 0;
399 
400  virtual QStringList referencedColumns() const = 0;
401  virtual bool needsGeometry() const = 0;
402 
403  // support for visitor pattern
404  virtual void accept( Visitor& v ) const = 0;
405  };
406 
407  class CORE_EXPORT NodeList
408  {
409  public:
410  NodeList() {}
411  virtual ~NodeList() { qDeleteAll( mList ); }
412  void append( Node* node ) { mList.append( node ); }
413  int count() { return mList.count(); }
414  QList<Node*> list() { return mList; }
415 
416  virtual QString dump() const;
417 
418  protected:
419  QList<Node*> mList;
420  };
421 
422  class CORE_EXPORT Interval
423  {
424  // YEAR const value taken from postgres query
425  // SELECT EXTRACT(EPOCH FROM interval '1 year')
426  static const int YEARS = 31557600;
427  static const int MONTHS = 60 * 60 * 24 * 30;
428  static const int WEEKS = 60 * 60 * 24 * 7;
429  static const int DAY = 60 * 60 * 24;
430  static const int HOUR = 60 * 60;
431  static const int MINUTE = 60;
432  public:
433  Interval( double seconds = 0 ) : mSeconds( seconds ), mValid( true ) { }
434  ~Interval();
435  double years() { return mSeconds / YEARS;}
436  double months() { return mSeconds / MONTHS; }
437  double weeks() { return mSeconds / WEEKS;}
438  double days() { return mSeconds / DAY;}
439  double hours() { return mSeconds / HOUR;}
440  double minutes() { return mSeconds / MINUTE;}
441  double seconds() { return mSeconds; }
442  bool isValid() { return mValid; }
443  void setValid( bool valid ) { mValid = valid; }
444  bool operator==( const QgsExpression::Interval& other ) const;
445  static QgsExpression::Interval invalidInterVal();
446  static QgsExpression::Interval fromString( QString string );
447  private:
448  double mSeconds;
449  bool mValid;
450  };
451 
452  class CORE_EXPORT NodeUnaryOperator : public Node
453  {
454  public:
455  NodeUnaryOperator( UnaryOperator op, Node* operand ) : mOp( op ), mOperand( operand ) {}
456  ~NodeUnaryOperator() { delete mOperand; }
457 
458  UnaryOperator op() const { return mOp; }
459  Node* operand() const { return mOperand; }
460 
461  virtual NodeType nodeType() const override { return ntUnaryOperator; }
462  virtual bool prepare( QgsExpression* parent, const QgsFields &fields ) override;
463  virtual QVariant eval( QgsExpression* parent, const QgsFeature* f ) override;
464  virtual QString dump() const override;
465 
466  virtual QStringList referencedColumns() const override { return mOperand->referencedColumns(); }
467  virtual bool needsGeometry() const override { return mOperand->needsGeometry(); }
468  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
469 
470  protected:
473  };
474 
475  class CORE_EXPORT NodeBinaryOperator : public Node
476  {
477  public:
478  NodeBinaryOperator( BinaryOperator op, Node* opLeft, Node* opRight ) : mOp( op ), mOpLeft( opLeft ), mOpRight( opRight ) {}
479  ~NodeBinaryOperator() { delete mOpLeft; delete mOpRight; }
480 
481  BinaryOperator op() const { return mOp; }
482  Node* opLeft() const { return mOpLeft; }
483  Node* opRight() const { return mOpRight; }
484 
485  virtual NodeType nodeType() const override { return ntBinaryOperator; }
486  virtual bool prepare( QgsExpression* parent, const QgsFields &fields ) override;
487  virtual QVariant eval( QgsExpression* parent, const QgsFeature* f ) override;
488  virtual QString dump() const override;
489 
490  virtual QStringList referencedColumns() const override { return mOpLeft->referencedColumns() + mOpRight->referencedColumns(); }
491  virtual bool needsGeometry() const override { return mOpLeft->needsGeometry() || mOpRight->needsGeometry(); }
492  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
493 
494  int precedence() const;
495 
496  protected:
497  bool compare( double diff );
498  int computeInt( int x, int y );
499  double computeDouble( double x, double y );
500  QDateTime computeDateTimeFromInterval( QDateTime d, QgsExpression::Interval *i );
501 
505  };
506 
507  class CORE_EXPORT NodeInOperator : public Node
508  {
509  public:
510  NodeInOperator( Node* node, NodeList* list, bool notin = false ) : mNode( node ), mList( list ), mNotIn( notin ) {}
511  virtual ~NodeInOperator() { delete mNode; delete mList; }
512 
513  Node* node() const { return mNode; }
514  bool isNotIn() const { return mNotIn; }
515  NodeList* list() const { return mList; }
516 
517  virtual NodeType nodeType() const override { return ntInOperator; }
518  virtual bool prepare( QgsExpression* parent, const QgsFields &fields ) override;
519  virtual QVariant eval( QgsExpression* parent, const QgsFeature* f ) override;
520  virtual QString dump() const override;
521 
522  virtual QStringList referencedColumns() const override { QStringList lst( mNode->referencedColumns() ); foreach ( Node* n, mList->list() ) lst.append( n->referencedColumns() ); return lst; }
523  virtual bool needsGeometry() const override { bool needs = false; foreach ( Node* n, mList->list() ) needs |= n->needsGeometry(); return needs; }
524  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
525 
526  protected:
529  bool mNotIn;
530  };
531 
532  class CORE_EXPORT NodeFunction : public Node
533  {
534  public:
535  NodeFunction( int fnIndex, NodeList* args ) : mFnIndex( fnIndex ), mArgs( args ) {}
536  //NodeFunction( QString name, NodeList* args ) : mName(name), mArgs(args) {}
537  virtual ~NodeFunction() { delete mArgs; }
538 
539  int fnIndex() const { return mFnIndex; }
540  NodeList* args() const { return mArgs; }
541 
542  virtual NodeType nodeType() const override { return ntFunction; }
543  virtual bool prepare( QgsExpression* parent, const QgsFields &fields ) override;
544  virtual QVariant eval( QgsExpression* parent, const QgsFeature* f ) override;
545  virtual QString dump() const override;
546 
547  virtual QStringList referencedColumns() const override;
548  virtual bool needsGeometry() const override { bool needs = Functions()[mFnIndex]->usesgeometry(); if ( mArgs ) { foreach ( Node* n, mArgs->list() ) needs |= n->needsGeometry(); } return needs; }
549  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
550 
551  protected:
552  //QString mName;
553  int mFnIndex;
555  };
556 
557  class CORE_EXPORT NodeLiteral : public Node
558  {
559  public:
560  NodeLiteral( QVariant value ) : mValue( value ) {}
561 
562  QVariant value() const { return mValue; }
563 
564  virtual NodeType nodeType() const override { return ntLiteral; }
565  virtual bool prepare( QgsExpression* parent, const QgsFields &fields ) override;
566  virtual QVariant eval( QgsExpression* parent, const QgsFeature* f ) override;
567  virtual QString dump() const override;
568 
569  virtual QStringList referencedColumns() const override { return QStringList(); }
570  virtual bool needsGeometry() const override { return false; }
571  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
572 
573  protected:
574  QVariant mValue;
575  };
576 
577  class CORE_EXPORT NodeColumnRef : public Node
578  {
579  public:
580  NodeColumnRef( QString name ) : mName( name ), mIndex( -1 ) {}
581 
582  QString name() const { return mName; }
583 
584  virtual NodeType nodeType() const override { return ntColumnRef; }
585  virtual bool prepare( QgsExpression* parent, const QgsFields &fields ) override;
586  virtual QVariant eval( QgsExpression* parent, const QgsFeature* f ) override;
587  virtual QString dump() const override;
588 
589  virtual QStringList referencedColumns() const override { return QStringList( mName ); }
590  virtual bool needsGeometry() const override { return false; }
591 
592  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
593 
594  protected:
595  QString mName;
596  int mIndex;
597  };
598 
599  class CORE_EXPORT WhenThen
600  {
601  public:
602  WhenThen( Node* whenExp, Node* thenExp ) : mWhenExp( whenExp ), mThenExp( thenExp ) {}
603  ~WhenThen() { delete mWhenExp; delete mThenExp; }
604 
605  //protected:
608  };
609  typedef QList<WhenThen*> WhenThenList;
610 
611  class CORE_EXPORT NodeCondition : public Node
612  {
613  public:
614  NodeCondition( WhenThenList* conditions, Node* elseExp = NULL ) : mConditions( *conditions ), mElseExp( elseExp ) { delete conditions; }
615  ~NodeCondition() { delete mElseExp; qDeleteAll( mConditions ); }
616 
617  virtual NodeType nodeType() const override { return ntCondition; }
618  virtual QVariant eval( QgsExpression* parent, const QgsFeature* f ) override;
619  virtual bool prepare( QgsExpression* parent, const QgsFields &fields ) override;
620  virtual QString dump() const override;
621 
622  virtual QStringList referencedColumns() const override;
623  virtual bool needsGeometry() const override;
624  virtual void accept( Visitor& v ) const override { v.visit( *this ); }
625 
626  protected:
627  WhenThenList mConditions;
629  };
630 
632 
635  class CORE_EXPORT Visitor
636  {
637  public:
638  virtual ~Visitor() {}
639  virtual void visit( const NodeUnaryOperator& n ) = 0;
640  virtual void visit( const NodeBinaryOperator& n ) = 0;
641  virtual void visit( const NodeInOperator& n ) = 0;
642  virtual void visit( const NodeFunction& n ) = 0;
643  virtual void visit( const NodeLiteral& n ) = 0;
644  virtual void visit( const NodeColumnRef& n ) = 0;
645  virtual void visit( const NodeCondition& n ) = 0;
646  };
647 
649  void acceptVisitor( Visitor& v ) const;
650 
651  static QString helptext( QString name );
652  static QString group( QString group );
653 
654  protected:
658  QgsExpression() : mRootNode( 0 ), mRowNumber( 0 ), mScale( 0.0 ), mCalc( 0 ) {}
659 
660  void initGeomCalculator();
661 
663 
666 
668  double mScale;
669  QString mExp;
670 
672 
673  static QMap<QString, QVariant> gmSpecialColumns;
674  static QMap<QString, QString> gmSpecialColumnGroups;
675 
676  static QHash<QString, QString> gFunctionHelpTexts;
677  static QHash<QString, QString> gGroups;
678 
679  static void initFunctionHelp();
680 
681  friend class QgsOgcUtils;
682 
683  private:
684  Q_DISABLE_COPY( QgsExpression ) // for now - until we have proper copy constructor / implicit sharing
685 };
686 
689 
690 #endif // QGSEXPRESSION_H
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:86
virtual QStringList referencedColumns() const =0
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
QVariant evaluate(const QgsFeature &f, const QgsFields &fields)
Evaluate the feature and return the result.
UnaryOperator
list of unary operators
virtual bool needsGeometry() const override
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
Definition: qgsexpression.h:93
virtual QStringList referencedColumns() const override
virtual NodeType nodeType() const override
bool lazyEval()
True if this function should use lazy evaluation.
const QString expression() const
Alias for dump()
Node is a class used by Line3D.
Definition: Node.h:23
A abstract base class for defining QgsExpression functions.
bool operator==(const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2)
virtual NodeType nodeType() const override
virtual QString dump() const =0
NodeCondition(WhenThenList *conditions, Node *elseExp=NULL)
static QString helptext(QString name)
QgsExpression()
Used by QgsOgcUtils to create an empty.
Container of fields for a vector layer.
Definition: qgsfield.h:172
Interval(double seconds=0)
virtual QStringList referencedColumns() const override
virtual bool prepare(QgsExpression *parent, const QgsFields &fields)=0
NodeList * list() const
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:113
QVariant value() const
virtual NodeType nodeType() const override
virtual QVariant func(const QVariantList &values, const QgsFeature *f, QgsExpression *parent) override
int currentRowNumber()
Return the number used for $rownum special column.
virtual void accept(Visitor &v) const override
QString mEvalErrorString
virtual bool needsGeometry() const override
NodeBinaryOperator(BinaryOperator op, Node *opLeft, Node *opRight)
QString mParserErrorString
virtual NodeType nodeType() const override
static const QList< Function * > & Functions()
static QHash< QString, QString > gFunctionHelpTexts
virtual QStringList referencedColumns() const override
QgsDistanceArea * geomCalculator()
Return calculator used for distance and area calculations (used by internal functions) ...
NodeList * args() const
virtual void accept(Visitor &v) const override
QgsDistanceArea * mCalc
QList< Node * > mList
static QHash< QString, QString > gGroups
const Node * rootNode() const
Returns root node of the expression. Root node is null is parsing has failed.
NodeInOperator(Node *node, NodeList *list, bool notin=false)
double scale()
QString helptext()
The help text for the function.
static QList< Function * > gmFunctions
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:33
virtual void accept(Visitor &v) const override
QString name()
The name of the function.
void setCurrentRowNumber(int rowNumber)
Set the number for $rownum special column.
WhenThen(Node *whenExp, Node *thenExp)
NodeLiteral(QVariant value)
StaticFunction(QString fnname, int params, FcnEval fcn, QString group, QString helpText=QString(), bool usesGeometry=false, QStringList referencedColumns=QStringList(), bool lazyEval=false)
NodeUnaryOperator(UnaryOperator op, Node *operand)
BinaryOperator op() const
virtual void accept(Visitor &v) const override
virtual QVariant eval(QgsExpression *parent, const QgsFeature *f)=0
virtual NodeType nodeType() const override
virtual QStringList referencedColumns() const override
virtual QStringList referencedColumns() const
virtual void accept(Visitor &v) const override
void setEvalErrorString(QString str)
Set evaluation error (used internally by evaluation functions)
NodeFunction(int fnIndex, NodeList *args)
General purpose distance and area calculator.
static QMap< QString, QString > gmSpecialColumnGroups
virtual bool needsGeometry() const override
virtual void accept(Visitor &v) const override
virtual NodeType nodeType() const override
virtual bool needsGeometry() const override
BinaryOperator
list of binary operators
QString group()
The group the function belongs to.
Function(QString fnname, int params, QString group, QString helpText=QString(), bool usesGeometry=false, QStringList referencedColumns=QStringList(), bool lazyEval=false)
QList< WhenThen * > WhenThenList
virtual void visit(const NodeUnaryOperator &n)=0
QVariant evaluate(const QgsFeature &f)
Evaluate the feature and return the result.
int params()
The number of parameters this function takes.
support for visitor pattern - algorithms dealing with the expressions may be implemented without modi...
virtual bool needsGeometry() const =0
bool operator==(const Function &other) const
static QStringList gmBuiltinFunctions
virtual bool needsGeometry() const override
void append(Node *node)
UnaryOperator op() const
virtual void accept(Visitor &v) const override
void setValid(bool valid)
virtual NodeType nodeType() const override
This is the base class for vector data providers.
void setScale(double scale)
Represents a vector layer which manages a vector based data sets.
QString parserErrorString() const
Returns parser error.
Definition: qgsexpression.h:95
Q_DECLARE_METATYPE(QgsExpression::Interval)
The QgsOgcUtils class provides various utility functions for conversion between OGC (Open Geospatial ...
Definition: qgsogcutils.h:28
QString evalErrorString() const
Returns evaluation error.
bool usesgeometry()
Does this function use a geometry object.
virtual bool needsGeometry() const override
QList< Node * > list()
virtual QStringList referencedColumns() const override
static QMap< QString, QVariant > gmSpecialColumns