QGIS API Documentation  3.24.2-Tisler (13c1a02865)
qgsexpressioncontext.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsexpressioncontext.cpp
3  ------------------------
4  Date : April 2015
5  Copyright : (C) 2015 by Nyall Dawson
6  Email : nyall dot dawson 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 #include "qgsexpressioncontext.h"
17 #include "qgslogger.h"
18 #include "qgsxmlutils.h"
19 #include "qgsexpression.h"
20 
21 const QString QgsExpressionContext::EXPR_FIELDS( QStringLiteral( "_fields_" ) );
22 const QString QgsExpressionContext::EXPR_ORIGINAL_VALUE( QStringLiteral( "value" ) );
23 const QString QgsExpressionContext::EXPR_SYMBOL_COLOR( QStringLiteral( "symbol_color" ) );
24 const QString QgsExpressionContext::EXPR_SYMBOL_ANGLE( QStringLiteral( "symbol_angle" ) );
25 const QString QgsExpressionContext::EXPR_GEOMETRY_PART_COUNT( QStringLiteral( "geometry_part_count" ) );
26 const QString QgsExpressionContext::EXPR_GEOMETRY_PART_NUM( QStringLiteral( "geometry_part_num" ) );
27 const QString QgsExpressionContext::EXPR_GEOMETRY_RING_NUM( QStringLiteral( "geometry_ring_num" ) );
28 const QString QgsExpressionContext::EXPR_GEOMETRY_POINT_COUNT( QStringLiteral( "geometry_point_count" ) );
29 const QString QgsExpressionContext::EXPR_GEOMETRY_POINT_NUM( QStringLiteral( "geometry_point_num" ) );
30 const QString QgsExpressionContext::EXPR_CLUSTER_SIZE( QStringLiteral( "cluster_size" ) );
31 const QString QgsExpressionContext::EXPR_CLUSTER_COLOR( QStringLiteral( "cluster_color" ) );
32 
33 //
34 // QgsExpressionContextScope
35 //
36 
38  : mName( name )
39 {
40 
41 }
42 
44  : mName( other.mName )
45  , mVariables( other.mVariables )
46  , mHasFeature( other.mHasFeature )
47  , mFeature( other.mFeature )
48  , mHasGeometry( other.mHasGeometry )
49  , mGeometry( other.mGeometry )
50 {
51  QHash<QString, QgsScopedExpressionFunction * >::const_iterator it = other.mFunctions.constBegin();
52  for ( ; it != other.mFunctions.constEnd(); ++it )
53  {
54  mFunctions.insert( it.key(), it.value()->clone() );
55  }
56 }
57 
59 {
60  mName = other.mName;
61  mVariables = other.mVariables;
62  mHasFeature = other.mHasFeature;
63  mFeature = other.mFeature;
64  mHasGeometry = other.mHasGeometry;
65  mGeometry = other.mGeometry;
66 
67  qDeleteAll( mFunctions );
68  mFunctions.clear();
69  QHash<QString, QgsScopedExpressionFunction * >::const_iterator it = other.mFunctions.constBegin();
70  for ( ; it != other.mFunctions.constEnd(); ++it )
71  {
72  mFunctions.insert( it.key(), it.value()->clone() );
73  }
74 
75  return *this;
76 }
77 
79 {
80  qDeleteAll( mFunctions );
81 }
82 
83 void QgsExpressionContextScope::setVariable( const QString &name, const QVariant &value, bool isStatic )
84 {
85  auto it = mVariables.find( name );
86  if ( it != mVariables.end() )
87  {
88  it->value = value;
89  it->isStatic = isStatic;
90  }
91  else
92  {
94  }
95 }
96 
98 {
99  mVariables.insert( variable.name, variable );
100 }
101 
102 bool QgsExpressionContextScope::removeVariable( const QString &name )
103 {
104  return mVariables.remove( name ) > 0;
105 }
106 
107 bool QgsExpressionContextScope::hasVariable( const QString &name ) const
108 {
109  return mVariables.contains( name );
110 }
111 
112 QVariant QgsExpressionContextScope::variable( const QString &name ) const
113 {
114  return hasVariable( name ) ? mVariables.value( name ).value : QVariant();
115 }
116 
118 {
119  QStringList names = mVariables.keys();
120  return names;
121 }
122 
124 class QgsExpressionContextVariableCompare
125 {
126  public:
127  explicit QgsExpressionContextVariableCompare( const QgsExpressionContextScope &scope )
128  : mScope( scope )
129  { }
130 
131  bool operator()( const QString &a, const QString &b ) const
132  {
133  bool aReadOnly = mScope.isReadOnly( a );
134  bool bReadOnly = mScope.isReadOnly( b );
135  if ( aReadOnly != bReadOnly )
136  return aReadOnly;
137  return QString::localeAwareCompare( a, b ) < 0;
138  }
139 
140  private:
141  const QgsExpressionContextScope &mScope;
142 };
144 
146 {
147  QStringList allVariables = mVariables.keys();
148  QStringList filtered;
149  const auto constAllVariables = allVariables;
150  for ( const QString &variable : constAllVariables )
151  {
152  if ( variable.startsWith( '_' ) )
153  continue;
154 
155  filtered << variable;
156  }
157  QgsExpressionContextVariableCompare cmp( *this );
158  std::sort( filtered.begin(), filtered.end(), cmp );
159 
160  return filtered;
161 }
162 
163 bool QgsExpressionContextScope::isReadOnly( const QString &name ) const
164 {
165  return hasVariable( name ) ? mVariables.value( name ).readOnly : false;
166 }
167 
168 bool QgsExpressionContextScope::isStatic( const QString &name ) const
169 {
170  return hasVariable( name ) ? mVariables.value( name ).isStatic : false;
171 }
172 
173 QString QgsExpressionContextScope::description( const QString &name ) const
174 {
175  return hasVariable( name ) ? mVariables.value( name ).description : QString();
176 }
177 
178 bool QgsExpressionContextScope::hasFunction( const QString &name ) const
179 {
180  return mFunctions.contains( name );
181 }
182 
184 {
185  return mFunctions.contains( name ) ? mFunctions.value( name ) : nullptr;
186 }
187 
189 {
190  return mFunctions.keys();
191 }
192 
194 {
195  mFunctions.insert( name, function );
196 }
197 
198 
200 {
201  addVariable( StaticVariable( QgsExpressionContext::EXPR_FIELDS, QVariant::fromValue( fields ), true ) );
202 }
203 
204 void QgsExpressionContextScope::readXml( const QDomElement &element, const QgsReadWriteContext & )
205 {
206  const QDomNodeList variablesNodeList = element.childNodes();
207  for ( int i = 0; i < variablesNodeList.size(); ++i )
208  {
209  const QDomElement variableElement = variablesNodeList.at( i ).toElement();
210  const QString key = variableElement.attribute( QStringLiteral( "name" ) );
211  const QVariant value = QgsXmlUtils::readVariant( variableElement.firstChildElement( QStringLiteral( "Option" ) ) );
212  setVariable( key, value );
213  }
214 }
215 
216 bool QgsExpressionContextScope::writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext & ) const
217 {
218  for ( auto it = mVariables.constBegin(); it != mVariables.constEnd(); ++it )
219  {
220  QDomElement varElem = document.createElement( QStringLiteral( "Variable" ) );
221  varElem.setAttribute( QStringLiteral( "name" ), it.key() );
222  QDomElement valueElem = QgsXmlUtils::writeVariant( it.value().value, document );
223  varElem.appendChild( valueElem );
224  element.appendChild( varElem );
225  }
226  return true;
227 }
228 
229 
230 //
231 // QgsExpressionContext
232 //
233 
234 QgsExpressionContext::QgsExpressionContext( const QList<QgsExpressionContextScope *> &scopes )
235  : mStack( scopes )
236 {
237 }
238 
240 {
241  for ( const QgsExpressionContextScope *scope : std::as_const( other.mStack ) )
242  {
243  mStack << new QgsExpressionContextScope( *scope );
244  }
245  mHighlightedVariables = other.mHighlightedVariables;
246  mHighlightedFunctions = other.mHighlightedFunctions;
247  mCachedValues = other.mCachedValues;
248 }
249 
251 {
252  if ( this != &other )
253  {
254  qDeleteAll( mStack );
255  // move the stack over
256  mStack = other.mStack;
257  other.mStack.clear();
258 
259  mHighlightedVariables = other.mHighlightedVariables;
260  mHighlightedFunctions = other.mHighlightedFunctions;
261  mCachedValues = other.mCachedValues;
262  }
263  return *this;
264 }
265 
267 {
268  if ( &other == this )
269  return *this;
270 
271  qDeleteAll( mStack );
272  mStack.clear();
273  for ( const QgsExpressionContextScope *scope : std::as_const( other.mStack ) )
274  {
275  mStack << new QgsExpressionContextScope( *scope );
276  }
277  mHighlightedVariables = other.mHighlightedVariables;
278  mHighlightedFunctions = other.mHighlightedFunctions;
279  mCachedValues = other.mCachedValues;
280  return *this;
281 }
282 
284 {
285  qDeleteAll( mStack );
286  mStack.clear();
287 }
288 
289 bool QgsExpressionContext::hasVariable( const QString &name ) const
290 {
291  const auto constMStack = mStack;
292  for ( const QgsExpressionContextScope *scope : constMStack )
293  {
294  if ( scope->hasVariable( name ) )
295  return true;
296  }
297  return false;
298 }
299 
300 QVariant QgsExpressionContext::variable( const QString &name ) const
301 {
303  return scope ? scope->variable( name ) : QVariant();
304 }
305 
307 {
308  QStringList names = variableNames();
309  QVariantMap m;
310  const auto constNames = names;
311  for ( const QString &name : constNames )
312  {
313  m.insert( name, variable( name ) );
314  }
315  return m;
316 }
317 
318 bool QgsExpressionContext::isHighlightedVariable( const QString &name ) const
319 {
320  return mHighlightedVariables.contains( name );
321 }
322 
324 {
325  return mHighlightedVariables;
326 }
327 
328 void QgsExpressionContext::setHighlightedVariables( const QStringList &variableNames )
329 {
330  mHighlightedVariables = variableNames;
331 }
332 
333 bool QgsExpressionContext::isHighlightedFunction( const QString &name ) const
334 {
335  return mHighlightedFunctions.contains( name );
336 }
337 
338 void QgsExpressionContext::setHighlightedFunctions( const QStringList &names )
339 {
340  mHighlightedFunctions = names;
341 }
342 
344 {
345  //iterate through stack backwards, so that higher priority variables take precedence
346  QList< QgsExpressionContextScope * >::const_iterator it = mStack.constEnd();
347  while ( it != mStack.constBegin() )
348  {
349  --it;
350  if ( ( *it )->hasVariable( name ) )
351  return ( *it );
352  }
353  return nullptr;
354 }
355 
357 {
358  //iterate through stack backwards, so that higher priority variables take precedence
359  QList< QgsExpressionContextScope * >::const_iterator it = mStack.constEnd();
360  while ( it != mStack.constBegin() )
361  {
362  --it;
363  if ( ( *it )->hasVariable( name ) )
364  return ( *it );
365  }
366  return nullptr;
367 }
368 
370 {
371  if ( index < 0 || index >= mStack.count() )
372  return nullptr;
373 
374  return mStack.at( index );
375 }
376 
378 {
379  if ( mStack.count() < 1 )
380  return nullptr;
381 
382  return mStack.last();
383 }
384 
386 {
387  if ( !scope )
388  return -1;
389 
390  return mStack.indexOf( scope );
391 }
392 
393 int QgsExpressionContext::indexOfScope( const QString &scopeName ) const
394 {
395  int index = 0;
396  const auto constMStack = mStack;
397  for ( const QgsExpressionContextScope *scope : constMStack )
398  {
399  if ( scope->name() == scopeName )
400  return index;
401 
402  index++;
403  }
404  return -1;
405 }
406 
408 {
409  QStringList names;
410  const auto constMStack = mStack;
411  for ( const QgsExpressionContextScope *scope : constMStack )
412  {
413  names << scope->variableNames();
414  }
415  return qgis::setToList( qgis::listToSet( names ) );
416 }
417 
419 {
420  QStringList allVariables = variableNames();
421  QStringList filtered;
422  const auto constAllVariables = allVariables;
423  for ( const QString &variable : constAllVariables )
424  {
425  if ( variable.startsWith( '_' ) )
426  continue;
427 
428  filtered << variable;
429  }
430 
431  filtered.sort();
432  return filtered;
433 }
434 
435 bool QgsExpressionContext::isReadOnly( const QString &name ) const
436 {
437  const auto constMStack = mStack;
438  for ( const QgsExpressionContextScope *scope : constMStack )
439  {
440  if ( scope->isReadOnly( name ) )
441  return true;
442  }
443  return false;
444 }
445 
446 QString QgsExpressionContext::description( const QString &name ) const
447 {
449  return ( scope && !scope->description( name ).isEmpty() ) ? scope->description( name ) : QgsExpression::variableHelpText( name );
450 }
451 
452 bool QgsExpressionContext::hasFunction( const QString &name ) const
453 {
454  const auto constMStack = mStack;
455  for ( const QgsExpressionContextScope *scope : constMStack )
456  {
457  if ( scope->hasFunction( name ) )
458  return true;
459  }
460  return false;
461 }
462 
464 {
465  QStringList result;
466  const auto constMStack = mStack;
467  for ( const QgsExpressionContextScope *scope : constMStack )
468  {
469  result << scope->functionNames();
470  }
471  result = qgis::setToList( qgis::listToSet( result ) );
472  result.sort();
473  return result;
474 }
475 
477 {
478  //iterate through stack backwards, so that higher priority variables take precedence
479  QList< QgsExpressionContextScope * >::const_iterator it = mStack.constEnd();
480  while ( it != mStack.constBegin() )
481  {
482  --it;
483  if ( ( *it )->hasFunction( name ) )
484  return ( *it )->function( name );
485  }
486  return nullptr;
487 }
488 
490 {
491  return mStack.count();
492 }
493 
495 {
496  mStack.append( scope );
497 }
498 
499 void QgsExpressionContext::appendScopes( const QList<QgsExpressionContextScope *> &scopes )
500 {
501  mStack.append( scopes );
502 }
503 
505 {
506  if ( !mStack.isEmpty() )
507  return mStack.takeLast();
508 
509  return nullptr;
510 }
511 
512 QList<QgsExpressionContextScope *> QgsExpressionContext::takeScopes()
513 {
514  QList<QgsExpressionContextScope *> stack = mStack;
515  mStack.clear();
516  return stack;
517 }
518 
520 {
521  mStack.append( scope );
522  return *this;
523 }
524 
526 {
527  if ( mStack.isEmpty() )
528  mStack.append( new QgsExpressionContextScope() );
529 
530  mStack.last()->setFeature( feature );
531 }
532 
534 {
535  for ( const QgsExpressionContextScope *scope : mStack )
536  {
537  if ( scope->hasFeature() )
538  return true;
539  }
540  return false;
541 }
542 
544 {
545  //iterate through stack backwards, so that higher priority variables take precedence
546  QList< QgsExpressionContextScope * >::const_iterator it = mStack.constEnd();
547  while ( it != mStack.constBegin() )
548  {
549  --it;
550  if ( ( *it )->hasFeature() )
551  return ( *it )->feature();
552  }
553  return QgsFeature();
554 }
555 
557 {
558  if ( mStack.isEmpty() )
559  mStack.append( new QgsExpressionContextScope() );
560 
561  mStack.last()->setGeometry( geometry );
562 }
563 
565 {
566  for ( const QgsExpressionContextScope *scope : mStack )
567  {
568  if ( scope->hasGeometry() )
569  return true;
570  }
571  return false;
572 }
573 
575 {
576  //iterate through stack backwards, so that higher priority variables take precedence
577  QList< QgsExpressionContextScope * >::const_iterator it = mStack.constEnd();
578  while ( it != mStack.constBegin() )
579  {
580  --it;
581  if ( ( *it )->hasGeometry() )
582  return ( *it )->geometry();
583  }
584  return QgsGeometry();
585 }
586 
588 {
589  if ( mStack.isEmpty() )
590  mStack.append( new QgsExpressionContextScope() );
591 
592  mStack.last()->setFields( fields );
593 }
594 
596 {
597  return qvariant_cast<QgsFields>( variable( QgsExpressionContext::EXPR_FIELDS ) );
598 }
599 
601 {
602  if ( mStack.isEmpty() )
603  mStack.append( new QgsExpressionContextScope() );
604 
606  value, true ) );
607 }
608 
609 void QgsExpressionContext::setCachedValue( const QString &key, const QVariant &value ) const
610 {
611  mCachedValues.insert( key, value );
612 }
613 
614 bool QgsExpressionContext::hasCachedValue( const QString &key ) const
615 {
616  return mCachedValues.contains( key );
617 }
618 
619 QVariant QgsExpressionContext::cachedValue( const QString &key ) const
620 {
621  return mCachedValues.value( key, QVariant() );
622 }
623 
625 {
626  mCachedValues.clear();
627 }
628 
630 {
631  mFeedback = feedback;
632 }
633 
635 {
636  return mFeedback;
637 }
Single scope for storing variables and functions for use within a QgsExpressionContext.
bool hasVariable(const QString &name) const
Tests whether a variable with the specified name exists in the scope.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the scope.
QString description(const QString &name) const
Returns the translated description for the variable with the specified name (if set).
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads scope variables from an XML element.
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Writes scope variables to an XML element.
QgsExpressionFunction * function(const QString &name) const
Retrieves a function from the scope.
QVariant variable(const QString &name) const
Retrieves a variable's value from the scope.
bool removeVariable(const QString &name)
Removes a variable from the context scope, if found.
bool isReadOnly(const QString &name) const
Tests whether the specified variable is read only and should not be editable by users.
void addFunction(const QString &name, QgsScopedExpressionFunction *function)
Adds a function to the scope.
bool hasFeature() const
Returns true if the scope has a feature associated with it.
bool hasFunction(const QString &name) const
Tests whether a function with the specified name exists in the scope.
QString name() const
Returns the friendly display name of the context scope.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
bool isStatic(const QString &name) const
Tests whether the variable with the specified name is static and can be cached.
bool hasGeometry() const
Returns true if the scope has a geometry associated with it.
QStringList filteredVariableNames() const
Returns a filtered and sorted list of variable names contained within the scope.
QStringList functionNames() const
Retrieves a list of names of functions contained in the scope.
void setVariable(const QString &name, const QVariant &value, bool isStatic=false)
Convenience method for setting a variable in the context scope by name name and value.
QgsExpressionContextScope & operator=(const QgsExpressionContextScope &other)
QgsExpressionContextScope(const QString &name=QString())
Constructor for QgsExpressionContextScope.
QStringList variableNames() const
Returns a list of variable names contained within the scope.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static const QString EXPR_GEOMETRY_PART_COUNT
Inbuilt variable name for geometry part count variable.
bool hasFunction(const QString &name) const
Checks whether a specified function is contained in the context.
QString description(const QString &name) const
Returns a translated description string for the variable with specified name.
static const QString EXPR_GEOMETRY_POINT_COUNT
Inbuilt variable name for point count variable.
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
QStringList highlightedVariables() const
Returns the current list of variables highlighted within the context.
static const QString EXPR_CLUSTER_SIZE
Inbuilt variable name for cluster size variable.
QStringList functionNames() const
Retrieves a list of function names contained in the context.
static const QString EXPR_GEOMETRY_POINT_NUM
Inbuilt variable name for point number variable.
int indexOfScope(QgsExpressionContextScope *scope) const
Returns the index of the specified scope if it exists within the context.
void setCachedValue(const QString &key, const QVariant &value) const
Sets a value to cache within the expression context.
void clearCachedValues() const
Clears all cached values from the context.
void setHighlightedFunctions(const QStringList &names)
Sets the list of function names intended to be highlighted to the user.
QgsGeometry geometry() const
Convenience function for retrieving the geometry for the context, if set.
bool isHighlightedFunction(const QString &name) const
Returns true if the specified function name is intended to be highlighted to the user.
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
QgsExpressionContext & operator=(const QgsExpressionContext &other)
QgsExpressionContext()=default
Constructor for QgsExpressionContext.
static const QString EXPR_FIELDS
Inbuilt variable name for fields storage.
QStringList filteredVariableNames() const
Returns a filtered list of variables names set by all scopes in the context.
void setGeometry(const QgsGeometry &geometry)
Convenience function for setting a geometry for the context.
static const QString EXPR_GEOMETRY_RING_NUM
Inbuilt variable name for geometry ring number variable.
bool isHighlightedVariable(const QString &name) const
Returns true if the specified variable name is intended to be highlighted to the user.
QgsExpressionContextScope * activeScopeForVariable(const QString &name)
Returns the currently active scope from the context for a specified variable name.
static const QString EXPR_GEOMETRY_PART_NUM
Inbuilt variable name for geometry part number variable.
static const QString EXPR_SYMBOL_COLOR
Inbuilt variable name for symbol color variable.
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
QList< QgsExpressionContextScope * > scopes()
Returns a list of scopes contained within the stack.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
bool hasVariable(const QString &name) const
Check whether a variable is specified by any scope within the context.
QList< QgsExpressionContextScope * > takeScopes()
Returns all scopes from this context and remove them, leaving this context without any context.
QgsFeedback * feedback() const
Returns the feedback object that can be queried regularly by the expression to check if evaluation sh...
void setFeedback(QgsFeedback *feedback)
Attach a feedback object that can be queried regularly by the expression engine to check if expressio...
int scopeCount() const
Returns the number of scopes contained in the context.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
static const QString EXPR_SYMBOL_ANGLE
Inbuilt variable name for symbol angle variable.
bool isReadOnly(const QString &name) const
Returns whether a variable is read only, and should not be modifiable by users.
bool hasGeometry() const
Returns true if the context has a geometry associated with it.
QgsExpressionFunction * function(const QString &name) const
Fetches a matching function from the context.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the context.
QVariantMap variablesToMap() const
Returns a map of variable name to value representing all the expression variables contained by the co...
bool hasCachedValue(const QString &key) const
Returns true if the expression context contains a cached value with a matching key.
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
QgsExpressionContext & operator<<(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
static const QString EXPR_ORIGINAL_VALUE
Inbuilt variable name for value original value variable.
static const QString EXPR_CLUSTER_COLOR
Inbuilt variable name for cluster color variable.
QStringList variableNames() const
Returns a list of variables names set by all scopes in the context.
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
QgsExpressionContextScope * scope(int index)
Returns the scope at the specified index within the context.
QVariant cachedValue(const QString &key) const
Returns the matching cached value, if set.
bool hasFeature() const
Returns true if the context has a feature associated with it.
QgsFields fields() const
Convenience function for retrieving the fields for the context, if set.
A abstract base class for defining QgsExpression functions.
static QString variableHelpText(const QString &variableName)
Returns the help text for a specified variable.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:45
Container of fields for a vector layer.
Definition: qgsfields.h:45
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:125
The class is used as a container of context for various read/write operations on other objects.
Expression function for use within a QgsExpressionContextScope.
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.
Single variable definition for use within a QgsExpressionContextScope.