QGIS API Documentation  3.21.0-Master (5b68dc587e)
qgsexpressioncontextutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsexpressioncontextutils.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 
17 #include "qgsapplication.h"
18 #include "qgsvectorlayer.h"
19 #include "qgsproject.h"
20 #include "qgsexpression.h"
21 #include "qgsprocessingcontext.h"
22 #include "qgsprocessingmodelalgorithm.h"
23 #include "qgsprocessingalgorithm.h"
24 #include "qgsmapsettings.h"
25 #include "qgssymbollayerutils.h"
26 #include "qgslayout.h"
27 #include "qgslayoutitem.h"
28 #include "qgsexpressionutils.h"
30 #include "qgslayoutatlas.h"
31 #include "qgslayoutmultiframe.h"
32 #include "qgsfeatureid.h"
33 #include "qgslayoutitemmap.h"
34 #include "qgsmaplayerlistutils.h"
35 #include "qgsprojoperation.h"
36 #include "qgsmarkersymbol.h"
37 #include "qgstriangularmesh.h"
38 
40 {
41  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Global" ) );
42 
43  const QVariantMap customVariables = QgsApplication::customVariables();
44 
45  for ( QVariantMap::const_iterator it = customVariables.constBegin(); it != customVariables.constEnd(); ++it )
46  {
47  scope->setVariable( it.key(), it.value(), true );
48  }
49 
50  //add some extra global variables
51  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_version" ), Qgis::version(), true, true ) );
52  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_version_no" ), Qgis::versionInt(), true, true ) );
53  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_short_version" ), QStringLiteral( "%1.%2" ).arg( Qgis::versionInt() / 10000 ).arg( Qgis::versionInt() / 100 % 100 ), true, true ) );
54  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_release_name" ), Qgis::releaseName(), true, true ) );
55  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_platform" ), QgsApplication::platform(), true, true ) );
56  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_os_name" ), QgsApplication::osName(), true, true ) );
57  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_locale" ), QgsApplication::locale(), true, true ) );
58  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "user_account_name" ), QgsApplication::userLoginName(), true, true ) );
59  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "user_full_name" ), QgsApplication::userFullName(), true, true ) );
60 
61  return scope;
62 }
63 
64 void QgsExpressionContextUtils::setGlobalVariable( const QString &name, const QVariant &value )
65 {
66  QgsApplication::setCustomVariable( name, value );
67 }
68 
69 void QgsExpressionContextUtils::setGlobalVariables( const QVariantMap &variables )
70 {
72 }
73 
75 {
76  QVariantMap vars = QgsApplication::customVariables();
77  if ( vars.remove( name ) )
79 }
80 
82 
83 class GetLayoutItemVariables : public QgsScopedExpressionFunction
84 {
85  public:
86  GetLayoutItemVariables( const QgsLayout *c )
87  : QgsScopedExpressionFunction( QStringLiteral( "item_variables" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "Layout" ) )
88  , mLayout( c )
89  {}
90 
91  QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
92  {
93  if ( !mLayout )
94  return QVariant();
95 
96  const QString id = values.at( 0 ).toString();
97 
98  const QgsLayoutItem *item = mLayout->itemById( id );
99  if ( !item )
100  return QVariant();
101 
103 
104  return c.variablesToMap();
105  }
106 
107  QgsScopedExpressionFunction *clone() const override
108  {
109  return new GetLayoutItemVariables( mLayout );
110  }
111 
112  private:
113 
114  const QgsLayout *mLayout = nullptr;
115 
116 };
117 
118 
119 class GetLayoutMapLayerCredits : public QgsScopedExpressionFunction
120 {
121  public:
122  GetLayoutMapLayerCredits( const QgsLayout *c )
123  : QgsScopedExpressionFunction( QStringLiteral( "map_credits" ),
124  QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) )
125  << QgsExpressionFunction::Parameter( QStringLiteral( "include_layer_names" ), true, false )
126  << QgsExpressionFunction::Parameter( QStringLiteral( "layer_name_separator" ), true, QStringLiteral( ": " ) ), QStringLiteral( "Layout" ) )
127  , mLayout( c )
128  {}
129 
130  QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
131  {
132  if ( !mLayout )
133  return QVariant();
134 
135  const QString id = values.value( 0 ).toString();
136 
137  if ( QgsLayoutItemMap *map = qobject_cast< QgsLayoutItemMap * >( mLayout->itemById( id ) ) )
138  {
139  const QgsExpressionContext c = map->createExpressionContext();
140  const QVariantList mapLayers = c.variable( QStringLiteral( "map_layers" ) ).toList();
141 
142  const bool includeLayerNames = values.value( 1 ).toBool();
143  const QString layerNameSeparator = values.value( 2 ).toString();
144 
145  QVariantList res;
146  for ( const QVariant &value : mapLayers )
147  {
148  if ( const QgsMapLayer *layer = qobject_cast< const QgsMapLayer * >( value.value< QObject * >() ) )
149  {
150  const QStringList credits = !layer->metadata().rights().isEmpty() ? layer->metadata().rights() : QStringList() << layer->attribution();
151  for ( const QString &credit : credits )
152  {
153  if ( credit.trimmed().isEmpty() )
154  continue;
155 
156  const QString creditString = includeLayerNames ? layer->name() + layerNameSeparator + credit
157  : credit;
158 
159  if ( !res.contains( creditString ) )
160  res << creditString;
161  }
162  }
163  }
164 
165  return res;
166  }
167  return QVariant();
168  }
169 
170  QgsScopedExpressionFunction *clone() const override
171  {
172  return new GetLayoutMapLayerCredits( mLayout );
173  }
174 
175  private:
176 
177  const QgsLayout *mLayout = nullptr;
178 
179 };
180 
181 class GetCurrentFormFieldValue : public QgsScopedExpressionFunction
182 {
183  public:
184  GetCurrentFormFieldValue( )
185  : QgsScopedExpressionFunction( QStringLiteral( "current_value" ), QgsExpressionFunction::ParameterList() << QStringLiteral( "field_name" ), QStringLiteral( "Form" ) )
186  {}
187 
188  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
189  {
190  const QString fieldName( values.at( 0 ).toString() );
191  const QgsFeature feat( context->variable( QStringLiteral( "current_feature" ) ).value<QgsFeature>() );
192  if ( fieldName.isEmpty() || ! feat.isValid( ) )
193  {
194  return QVariant();
195  }
196  return feat.attribute( fieldName ) ;
197  }
198 
199  QgsScopedExpressionFunction *clone() const override
200  {
201  return new GetCurrentFormFieldValue( );
202  }
203 
204  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
205  {
206  return false;
207  };
208 
209 };
210 
211 class GetCurrentParentFormFieldValue : public QgsScopedExpressionFunction
212 {
213  public:
214  GetCurrentParentFormFieldValue( )
215  : QgsScopedExpressionFunction( QStringLiteral( "current_parent_value" ), QgsExpressionFunction::ParameterList() << QStringLiteral( "field_name" ), QStringLiteral( "Form" ) )
216  {}
217 
218  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
219  {
220  const QString fieldName( values.at( 0 ).toString() );
221  const QgsFeature feat( context->variable( QStringLiteral( "current_parent_feature" ) ).value<QgsFeature>() );
222  if ( fieldName.isEmpty() || ! feat.isValid( ) )
223  {
224  return QVariant();
225  }
226  return feat.attribute( fieldName ) ;
227  }
228 
229  QgsScopedExpressionFunction *clone() const override
230  {
231  return new GetCurrentParentFormFieldValue( );
232  }
233 
234  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
235  {
236  return false;
237  };
238 
239 };
240 
241 
242 class GetProcessingParameterValue : public QgsScopedExpressionFunction
243 {
244  public:
245  GetProcessingParameterValue( const QVariantMap &params )
246  : QgsScopedExpressionFunction( QStringLiteral( "parameter" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "name" ) ), QStringLiteral( "Processing" ) )
247  , mParams( params )
248  {}
249 
250  QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
251  {
252  return mParams.value( values.at( 0 ).toString() );
253  }
254 
255  QgsScopedExpressionFunction *clone() const override
256  {
257  return new GetProcessingParameterValue( mParams );
258  }
259 
260  private:
261 
262  const QVariantMap mParams;
263 
264 };
265 
267 
268 
269 QgsExpressionContextScope *QgsExpressionContextUtils::formScope( const QgsFeature &formFeature, const QString &formMode )
270 {
271  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Form" ) );
272  scope->addFunction( QStringLiteral( "current_value" ), new GetCurrentFormFieldValue( ) );
273  scope->setVariable( QStringLiteral( "current_geometry" ), formFeature.geometry( ), true );
274  scope->setVariable( QStringLiteral( "current_feature" ), formFeature, true );
275  scope->setVariable( QStringLiteral( "form_mode" ), formMode, true );
276  return scope;
277 }
278 
279 
280 QgsExpressionContextScope *QgsExpressionContextUtils::parentFormScope( const QgsFeature &parentFormFeature, const QString &parentFormMode )
281 {
282  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Parent Form" ) );
283  scope->addFunction( QStringLiteral( "current_parent_value" ), new GetCurrentParentFormFieldValue( ) );
284  scope->setVariable( QStringLiteral( "current_parent_geometry" ), parentFormFeature.geometry( ), true );
285  scope->setVariable( QStringLiteral( "current_parent_feature" ), parentFormFeature, true );
286  scope->setVariable( QStringLiteral( "parent_form_mode" ), parentFormMode, true );
287  return scope;
288 }
289 
291 {
292  if ( !project )
293  {
294  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Project" ) );
295  return scope;
296  }
297  else
298  return project->createExpressionContextScope();
299 }
300 
301 void QgsExpressionContextUtils::setProjectVariable( QgsProject *project, const QString &name, const QVariant &value )
302 {
303  if ( !project )
304  return;
305 
306  QVariantMap vars = project->customVariables();
307 
308  vars.insert( name, value );
309 
310  project->setCustomVariables( vars );
311 }
312 
313 void QgsExpressionContextUtils::setProjectVariables( QgsProject *project, const QVariantMap &variables )
314 {
315  if ( !project )
316  return;
317 
318  project->setCustomVariables( variables );
319 }
320 
322 {
323  if ( !project )
324  {
325  return;
326  }
327 
328  QVariantMap vars = project->customVariables();
329  if ( vars.remove( name ) )
330  project->setCustomVariables( vars );
331 }
332 
334 {
335  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Layer" ) );
336 
337  if ( !layer )
338  return scope;
339 
340  //add variables defined in layer properties
341  const QStringList variableNames = layer->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
342  const QStringList variableValues = layer->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
343 
344  int varIndex = 0;
345  for ( const QString &variableName : variableNames )
346  {
347  if ( varIndex >= variableValues.length() )
348  {
349  break;
350  }
351 
352  const QVariant varValue = variableValues.at( varIndex );
353  varIndex++;
354  scope->setVariable( variableName, varValue, true );
355  }
356 
357  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_name" ), layer->name(), true, true ) );
358  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_id" ), layer->id(), true, true ) );
359  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "_layer_crs" ), QVariant::fromValue<QgsCoordinateReferenceSystem>( layer->crs() ), true, true ) );
360  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_crs" ), layer->crs().authid(), true, true ) );
361  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer" ), QVariant::fromValue<QgsWeakMapLayerPointer >( QgsWeakMapLayerPointer( const_cast<QgsMapLayer *>( layer ) ) ), true, true ) );
362 
363  const QgsVectorLayer *vLayer = qobject_cast< const QgsVectorLayer * >( layer );
364  if ( vLayer )
365  {
366  scope->setFields( vLayer->fields() );
367  }
368 
369  //TODO - add functions. Possibilities include:
370  //is_selected
371  //field summary stats
372 
373  return scope;
374 }
375 
376 QList<QgsExpressionContextScope *> QgsExpressionContextUtils::globalProjectLayerScopes( const QgsMapLayer *layer )
377 {
378  QList<QgsExpressionContextScope *> scopes;
379  scopes << globalScope();
380 
381  QgsProject *project = QgsProject::instance(); // TODO: use project associated with layer
382  if ( project )
383  scopes << projectScope( project );
384 
385  if ( layer )
386  scopes << layerScope( layer );
387  return scopes;
388 }
389 
390 
391 void QgsExpressionContextUtils::setLayerVariable( QgsMapLayer *layer, const QString &name, const QVariant &value )
392 {
393  if ( !layer )
394  return;
395 
396  //write variable to layer
397  QStringList variableNames = layer->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
398  QStringList variableValues = layer->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
399 
400  variableNames << name;
401  variableValues << value.toString();
402 
403  layer->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
404  layer->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
405 }
406 
407 void QgsExpressionContextUtils::setLayerVariables( QgsMapLayer *layer, const QVariantMap &variables )
408 {
409  if ( !layer )
410  return;
411 
412  QStringList variableNames;
413  QStringList variableValues;
414 
415  QVariantMap::const_iterator it = variables.constBegin();
416  for ( ; it != variables.constEnd(); ++it )
417  {
418  variableNames << it.key();
419  variableValues << it.value().toString();
420  }
421 
422  layer->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
423  layer->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
424 }
425 
427 {
428  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
429  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
430 
431  // and because people don't read that ^^, I'm going to blast it all over this function
432 
433  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Map Settings" ) );
434 
435  //add known map settings context variables
436  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_id" ), "canvas", true ) );
437  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_rotation" ), mapSettings.rotation(), true ) );
438  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_scale" ), mapSettings.scale(), true ) );
439 
440  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
441  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
442 
443  const QgsGeometry extent = QgsGeometry::fromRect( mapSettings.visibleExtent() );
444  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent" ), QVariant::fromValue( extent ), true ) );
445  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_width" ), mapSettings.visibleExtent().width(), true ) );
446  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_height" ), mapSettings.visibleExtent().height(), true ) );
447 
448  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
449  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
450 
451  const QgsGeometry centerPoint = QgsGeometry::fromPointXY( mapSettings.visibleExtent().center() );
452  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_center" ), QVariant::fromValue( centerPoint ), true ) );
453 
454  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
455  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
456 
457  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs" ), mapSettings.destinationCrs().authid(), true ) );
458  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_definition" ), mapSettings.destinationCrs().toProj(), true ) );
459  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_units" ), QgsUnitTypes::toString( mapSettings.mapUnits() ), true ) );
460  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_description" ), mapSettings.destinationCrs().description(), true ) );
461  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_acronym" ), mapSettings.destinationCrs().projectionAcronym(), true ) );
462  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_projection" ), mapSettings.destinationCrs().operation().description(), true ) );
463  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_ellipsoid" ), mapSettings.destinationCrs().ellipsoidAcronym(), true ) );
464  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_proj4" ), mapSettings.destinationCrs().toProj(), true ) );
465  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_wkt" ), mapSettings.destinationCrs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ), true ) );
466 
467  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
468  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
469 
470  QVariantList layersIds;
471  QVariantList layers;
472  const QList<QgsMapLayer *> layersInMap = mapSettings.layers();
473  layersIds.reserve( layersInMap.count() );
474  layers.reserve( layersInMap.count() );
475  for ( QgsMapLayer *layer : layersInMap )
476  {
477  layersIds << layer->id();
478  layers << QVariant::fromValue<QgsWeakMapLayerPointer>( QgsWeakMapLayerPointer( layer ) );
479  }
480 
481  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
482  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
483 
484  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_layer_ids" ), layersIds, true ) );
485  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_layers" ), layers, true ) );
486 
487  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
488  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
489 
490  scope->addFunction( QStringLiteral( "is_layer_visible" ), new GetLayerVisibility( mapSettings.layers(), mapSettings.scale() ) );
491 
492  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
493  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
494 
495  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_start_time" ), mapSettings.isTemporal() ? mapSettings.temporalRange().begin() : QVariant(), true ) );
496  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_end_time" ), mapSettings.isTemporal() ? mapSettings.temporalRange().end() : QVariant(), true ) );
497  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_interval" ), mapSettings.isTemporal() ? ( mapSettings.temporalRange().end() - mapSettings.temporalRange().begin() ) : QVariant(), true ) );
498 
499  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
500  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
501 
502  return scope;
503 }
504 
505 QgsExpressionContextScope *QgsExpressionContextUtils::mapToolCaptureScope( const QList<QgsPointLocator::Match> &matches )
506 {
507  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Map Tool Capture" ) );
508 
509  QVariantList matchList;
510 
511  for ( const QgsPointLocator::Match &match : matches )
512  {
513  QVariantMap matchMap;
514 
515  matchMap.insert( QStringLiteral( "valid" ), match.isValid() );
516  matchMap.insert( QStringLiteral( "layer" ), QVariant::fromValue<QgsWeakMapLayerPointer>( QgsWeakMapLayerPointer( match.layer() ) ) );
517  matchMap.insert( QStringLiteral( "feature_id" ), match.featureId() );
518  matchMap.insert( QStringLiteral( "vertex_index" ), match.vertexIndex() );
519  matchMap.insert( QStringLiteral( "distance" ), match.distance() );
520 
521  matchList.append( matchMap );
522  }
523 
524  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "snapping_results" ), matchList ) );
525 
526  return scope;
527 }
528 
530 {
531  if ( !symbolScope )
532  return nullptr;
533 
534  symbolScope->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_SYMBOL_COLOR, symbol ? symbol->color() : QColor(), true ) );
535 
536  double angle = 0.0;
537  const QgsMarkerSymbol *markerSymbol = dynamic_cast< const QgsMarkerSymbol * >( symbol );
538  if ( markerSymbol )
539  {
540  angle = markerSymbol->angle();
541  }
543 
544  return symbolScope;
545 }
546 
548 {
549  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope( QObject::tr( "Layout" ) ) );
550  if ( !layout )
551  return scope.release();
552 
553  //add variables defined in layout properties
554  const QStringList variableNames = layout->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
555  const QStringList variableValues = layout->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
556 
557  int varIndex = 0;
558 
559  for ( const QString &variableName : variableNames )
560  {
561  if ( varIndex >= variableValues.length() )
562  {
563  break;
564  }
565 
566  const QVariant varValue = variableValues.at( varIndex );
567  varIndex++;
568  scope->setVariable( variableName, varValue );
569  }
570 
571  //add known layout context variables
572  if ( const QgsMasterLayoutInterface *l = dynamic_cast< const QgsMasterLayoutInterface * >( layout ) )
573  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_name" ), l->name(), true ) );
574 
575  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_numpages" ), layout->pageCollection()->pageCount(), true ) );
576  if ( layout->pageCollection()->pageCount() > 0 )
577  {
578  // just take first page size
579  const QSizeF s = layout->pageCollection()->page( 0 )->sizeWithUnits().toQSizeF();
580  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), s.height(), true ) );
581  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), s.width(), true ) );
582  }
583 
584  QVariantList offsets;
585  for ( int i = 0; i < layout->pageCollection()->pageCount(); i++ )
586  {
587  const QPointF p = layout->pageCollection()->pagePositionToLayoutPosition( i, QgsLayoutPoint( 0, 0 ) );
588  offsets << p.y();
589  }
590  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageoffsets" ), offsets, true ) );
591 
592  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_dpi" ), layout->renderContext().dpi(), true ) );
593 
594  scope->addFunction( QStringLiteral( "item_variables" ), new GetLayoutItemVariables( layout ) );
595  scope->addFunction( QStringLiteral( "map_credits" ), new GetLayoutMapLayerCredits( layout ) );
596 
597  if ( layout->reportContext().layer() )
598  {
599  scope->setFields( layout->reportContext().layer()->fields() );
600  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layerid" ), layout->reportContext().layer()->id(), true ) );
601  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layername" ), layout->reportContext().layer()->name(), true ) );
602  }
603 
604  if ( layout->reportContext().feature().isValid() )
605  {
606  const QgsFeature atlasFeature = layout->reportContext().feature();
607  scope->setFeature( atlasFeature );
608  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( atlasFeature ), true ) );
609  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), FID_IS_NULL( atlasFeature.id() ) ? QVariant() : atlasFeature.id(), true ) );
610  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( atlasFeature.geometry() ), true ) );
611  }
612 
613  return scope.release();
614 }
615 
616 void QgsExpressionContextUtils::setLayoutVariable( QgsLayout *layout, const QString &name, const QVariant &value )
617 {
618  if ( !layout )
619  return;
620 
621  //write variable to layout
622  QStringList variableNames = layout->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
623  QStringList variableValues = layout->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
624 
625  variableNames << name;
626  variableValues << value.toString();
627 
628  layout->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
629  layout->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
630 }
631 
632 void QgsExpressionContextUtils::setLayoutVariables( QgsLayout *layout, const QVariantMap &variables )
633 {
634  if ( !layout )
635  return;
636 
637  QStringList variableNames;
638  QStringList variableValues;
639 
640  QVariantMap::const_iterator it = variables.constBegin();
641  for ( ; it != variables.constEnd(); ++it )
642  {
643  variableNames << it.key();
644  variableValues << it.value().toString();
645  }
646 
647  layout->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
648  layout->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
649 }
650 
652 {
653  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Atlas" ) );
654  if ( !atlas )
655  {
656  //add some dummy atlas variables. This is done so that as in certain contexts we want to show
657  //users that these variables are available even if they have no current value
658  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_pagename" ), QString(), true, true ) );
659  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( QgsFeature() ), true, true ) );
660  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), QVariant(), true, true ) );
661  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( QgsGeometry() ), true, true ) );
662  return scope;
663  }
664 
665  //add known atlas variables
666  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_totalfeatures" ), atlas->count(), true, true ) );
667  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featurenumber" ), atlas->currentFeatureNumber() + 1, true, true ) );
668  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_filename" ), atlas->currentFilename(), true, true ) );
669  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_pagename" ), atlas->nameForPage( atlas->currentFeatureNumber() ), true, true ) );
670 
671  if ( atlas->enabled() && atlas->coverageLayer() )
672  {
673  scope->setFields( atlas->coverageLayer()->fields() );
674  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layerid" ), atlas->coverageLayer()->id(), true ) );
675  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layername" ), atlas->coverageLayer()->name(), true ) );
676  }
677 
678  if ( atlas->enabled() )
679  {
680  const QgsFeature atlasFeature = atlas->layout()->reportContext().feature();
681  scope->setFeature( atlasFeature );
682  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( atlasFeature ), true ) );
683  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), FID_IS_NULL( atlasFeature.id() ) ? QVariant() : atlasFeature.id(), true ) );
684  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( atlasFeature.geometry() ), true ) );
685  }
686 
687  return scope;
688 }
689 
691 {
692  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Layout Item" ) );
693  if ( !item )
694  return scope;
695 
696  //add variables defined in layout item properties
697  const QStringList variableNames = item->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
698  const QStringList variableValues = item->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
699 
700  int varIndex = 0;
701  for ( const QString &variableName : variableNames )
702  {
703  if ( varIndex >= variableValues.length() )
704  {
705  break;
706  }
707 
708  const QVariant varValue = variableValues.at( varIndex );
709  varIndex++;
710  scope->setVariable( variableName, varValue );
711  }
712 
713  //add known layout item context variables
714  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "item_id" ), item->id(), true ) );
715  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "item_uuid" ), item->uuid(), true ) );
716  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_page" ), item->page() + 1, true ) );
717 
718  if ( item->layout() )
719  {
720  const QgsLayoutItemPage *page = item->layout()->pageCollection()->page( item->page() );
721  if ( page )
722  {
723  const QSizeF s = page->sizeWithUnits().toQSizeF();
724  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), s.height(), true ) );
725  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), s.width(), true ) );
726  }
727  else
728  {
729  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), QVariant(), true ) );
730  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), QVariant(), true ) );
731  }
732  }
733 
734  return scope;
735 }
736 
737 void QgsExpressionContextUtils::setLayoutItemVariable( QgsLayoutItem *item, const QString &name, const QVariant &value )
738 {
739  if ( !item )
740  return;
741 
742  //write variable to layout item
743  QStringList variableNames = item->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
744  QStringList variableValues = item->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
745 
746  variableNames << name;
747  variableValues << value.toString();
748 
749  item->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
750  item->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
751 }
752 
753 void QgsExpressionContextUtils::setLayoutItemVariables( QgsLayoutItem *item, const QVariantMap &variables )
754 {
755  if ( !item )
756  return;
757 
758  QStringList variableNames;
759  QStringList variableValues;
760 
761  QVariantMap::const_iterator it = variables.constBegin();
762  for ( ; it != variables.constEnd(); ++it )
763  {
764  variableNames << it.key();
765  variableValues << it.value().toString();
766  }
767 
768  item->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
769  item->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
770 }
771 
773 {
774  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Multiframe Item" ) );
775  if ( !frame )
776  return scope;
777 
778  //add variables defined in layout item properties
779  const QStringList variableNames = frame->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
780  const QStringList variableValues = frame->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
781 
782  int varIndex = 0;
783  for ( const QString &variableName : variableNames )
784  {
785  if ( varIndex >= variableValues.length() )
786  {
787  break;
788  }
789 
790  const QVariant varValue = variableValues.at( varIndex );
791  varIndex++;
792  scope->setVariable( variableName, varValue );
793  }
794 
795  return scope;
796 }
797 
798 void QgsExpressionContextUtils::setLayoutMultiFrameVariable( QgsLayoutMultiFrame *frame, const QString &name, const QVariant &value )
799 {
800  if ( !frame )
801  return;
802 
803  //write variable to layout multiframe
804  QStringList variableNames = frame->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
805  QStringList variableValues = frame->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
806 
807  variableNames << name;
808  variableValues << value.toString();
809 
810  frame->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
811  frame->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
812 }
813 
815 {
816  if ( !frame )
817  return;
818 
819  QStringList variableNames;
820  QStringList variableValues;
821 
822  QVariantMap::const_iterator it = variables.constBegin();
823  for ( ; it != variables.constEnd(); ++it )
824  {
825  variableNames << it.key();
826  variableValues << it.value().toString();
827  }
828 
829  frame->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
830  frame->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
831 }
832 
834 {
836  scope->setFeature( feature );
837  scope->setFields( fields );
838  return QgsExpressionContext() << scope;
839 }
840 
842 {
843  // set aside for future use
844  Q_UNUSED( context )
845 
846  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope( QObject::tr( "Algorithm" ) ) );
847  scope->addFunction( QStringLiteral( "parameter" ), new GetProcessingParameterValue( parameters ) );
848 
849  if ( !algorithm )
850  return scope.release();
851 
852  //add standard algorithm variables
853  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "algorithm_id" ), algorithm->id(), true ) );
854 
855  return scope.release();
856 }
857 
858 QgsExpressionContextScope *QgsExpressionContextUtils::processingModelAlgorithmScope( const QgsProcessingModelAlgorithm *model, const QVariantMap &, QgsProcessingContext &context )
859 {
860  std::unique_ptr< QgsExpressionContextScope > modelScope( new QgsExpressionContextScope( QObject::tr( "Model" ) ) );
861  QString modelPath;
862  if ( !model->sourceFilePath().isEmpty() )
863  {
864  modelPath = model->sourceFilePath();
865  }
866  else if ( context.project() )
867  {
868  // fallback to project path -- the model may be embedded in a project, OR an unsaved model. In either case the
869  // project path is a logical value to fall back to
870  modelPath = context.project()->projectStorage() ? context.project()->fileName() : context.project()->absoluteFilePath();
871  }
872 
873  const QString modelFolder = !modelPath.isEmpty() ? QFileInfo( modelPath ).path() : QString();
874  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_path" ), QDir::toNativeSeparators( modelPath ), true ) );
875  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_folder" ), QDir::toNativeSeparators( modelFolder ), true, true ) );
876  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_name" ), model->displayName(), true ) );
877  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_group" ), model->group(), true ) );
878 
879  // custom variables
880  const QVariantMap customVariables = model->variables();
881  for ( auto it = customVariables.constBegin(); it != customVariables.constEnd(); ++it )
882  {
883  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( it.key(), it.value(), true ) );
884  }
885 
886  return modelScope.release();
887 }
888 
890 {
891  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope() );
892  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "notification_message" ), message, true ) );
893  return scope.release();
894 }
895 
897 {
898  QgsExpression::registerFunction( new GetNamedProjectColor( nullptr ) );
899  QgsExpression::registerFunction( new GetLayoutItemVariables( nullptr ) );
900  QgsExpression::registerFunction( new GetLayoutMapLayerCredits( nullptr ) );
901  QgsExpression::registerFunction( new GetLayerVisibility( QList<QgsMapLayer *>(), 0.0 ) );
902  QgsExpression::registerFunction( new GetProcessingParameterValue( QVariantMap() ) );
903  QgsExpression::registerFunction( new GetCurrentFormFieldValue( ) );
904  QgsExpression::registerFunction( new GetCurrentParentFormFieldValue( ) );
905 }
906 
908 {
909  Q_UNUSED( node )
910  return mUsesGeometry;
911 }
912 
914 {
915  Q_UNUSED( node )
916  return mReferencedColumns;
917 }
918 
920 {
921  return allParamsStatic( node, parent, context );
922 }
923 
924 //
925 // GetLayerVisibility
926 //
927 
928 QgsExpressionContextUtils::GetLayerVisibility::GetLayerVisibility( const QList<QgsMapLayer *> &layers, double scale )
929  : QgsScopedExpressionFunction( QStringLiteral( "is_layer_visible" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "General" ) )
930  , mLayers( _qgis_listRawToQPointer( layers ) )
931  , mScale( scale )
932 {
933  for ( const auto &layer : mLayers )
934  {
935  if ( layer->hasScaleBasedVisibility() )
936  {
937  mScaleBasedVisibilityDetails[ layer ] = qMakePair( layer->minimumScale(), layer->maximumScale() );
938  }
939  }
940 }
941 
942 QgsExpressionContextUtils::GetLayerVisibility::GetLayerVisibility()
943  : QgsScopedExpressionFunction( QStringLiteral( "is_layer_visible" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "General" ) )
944 {}
945 
946 QVariant QgsExpressionContextUtils::GetLayerVisibility::func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
947 {
948  if ( mLayers.isEmpty() )
949  {
950  return false;
951  }
952 
953  bool isVisible = false;
954  QgsMapLayer *layer = QgsExpressionUtils::getMapLayer( values.at( 0 ), parent );
955  if ( layer && mLayers.contains( layer ) )
956  {
957  isVisible = true;
958  if ( mScaleBasedVisibilityDetails.contains( layer ) && !qgsDoubleNear( mScale, 0.0 ) )
959  {
960  if ( ( !qgsDoubleNear( mScaleBasedVisibilityDetails[ layer ].first, 0.0 ) && mScale > mScaleBasedVisibilityDetails[ layer ].first ) ||
961  ( !qgsDoubleNear( mScaleBasedVisibilityDetails[ layer ].second, 0.0 ) && mScale < mScaleBasedVisibilityDetails[ layer ].second ) )
962  {
963  isVisible = false;
964  }
965  }
966  }
967 
968  return isVisible;
969 }
970 
971 QgsScopedExpressionFunction *QgsExpressionContextUtils::GetLayerVisibility::clone() const
972 {
973  GetLayerVisibility *func = new GetLayerVisibility();
974  func->mLayers = mLayers;
975  func->mScale = mScale;
976  func->mScaleBasedVisibilityDetails = mScaleBasedVisibilityDetails;
977  return func;
978 }
979 
980 //
981 // mesh expression context
982 //
983 
985 class CurrentVertexZValueExpressionFunction: public QgsScopedExpressionFunction
986 {
987  public:
988  CurrentVertexZValueExpressionFunction():
989  QgsScopedExpressionFunction( "$vertex_z",
990  0,
991  QStringLiteral( "Meshes" ) )
992  {}
993 
994  QgsScopedExpressionFunction *clone() const override {return new CurrentVertexZValueExpressionFunction();}
995 
996  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
997  {
998  if ( !context )
999  return QVariant();
1000 
1001  if ( !context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1002  return QVariant();
1003 
1004  int vertexIndex = context->variable( QStringLiteral( "_mesh_vertex_index" ) ).toInt();
1005 
1006  QgsMeshLayer *layer = qobject_cast<QgsMeshLayer *>( qvariant_cast<QgsMapLayer *>( context->variable( QStringLiteral( "_mesh_layer" ) ) ) );
1007  if ( !layer || !layer->nativeMesh() || layer->nativeMesh()->vertexCount() <= vertexIndex )
1008  return QVariant();
1009 
1010  const QgsMeshVertex &vertex = layer->nativeMesh()->vertex( vertexIndex );
1011  if ( !vertex.isEmpty() )
1012  return vertex.z();
1013  else
1014  return QVariant();
1015  }
1016 
1017  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1018  {
1019  return false;
1020  }
1021 };
1022 
1023 class CurrentVertexXValueExpressionFunction: public QgsScopedExpressionFunction
1024 {
1025  public:
1026  CurrentVertexXValueExpressionFunction():
1027  QgsScopedExpressionFunction( "$vertex_x",
1028  0,
1029  QStringLiteral( "Meshes" ) )
1030  {}
1031 
1032  QgsScopedExpressionFunction *clone() const override {return new CurrentVertexXValueExpressionFunction();}
1033 
1034  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1035  {
1036  if ( !context )
1037  return QVariant();
1038 
1039  if ( !context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1040  return QVariant();
1041 
1042  int vertexIndex = context->variable( QStringLiteral( "_mesh_vertex_index" ) ).toInt();
1043 
1044  QgsMeshLayer *layer = qobject_cast<QgsMeshLayer *>( qvariant_cast<QgsMapLayer *>( context->variable( QStringLiteral( "_mesh_layer" ) ) ) );
1045  if ( !layer || !layer->nativeMesh() || layer->nativeMesh()->vertexCount() <= vertexIndex )
1046  return QVariant();
1047 
1048  const QgsMeshVertex &vertex = layer->nativeMesh()->vertex( vertexIndex );
1049  if ( !vertex.isEmpty() )
1050  return vertex.x();
1051  else
1052  return QVariant();
1053  }
1054 
1055  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1056  {
1057  return false;
1058  }
1059 };
1060 
1061 class CurrentVertexYValueExpressionFunction: public QgsScopedExpressionFunction
1062 {
1063  public:
1064  CurrentVertexYValueExpressionFunction():
1065  QgsScopedExpressionFunction( "$vertex_y",
1066  0,
1067  QStringLiteral( "Meshes" ) )
1068  {}
1069 
1070  QgsScopedExpressionFunction *clone() const override {return new CurrentVertexYValueExpressionFunction();}
1071 
1072  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1073  {
1074  if ( !context )
1075  return QVariant();
1076 
1077  if ( !context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1078  return QVariant();
1079 
1080  int vertexIndex = context->variable( QStringLiteral( "_mesh_vertex_index" ) ).toInt();
1081 
1082  QgsMeshLayer *layer = qobject_cast<QgsMeshLayer *>( qvariant_cast<QgsMapLayer *>( context->variable( QStringLiteral( "_mesh_layer" ) ) ) );
1083  if ( !layer || !layer->nativeMesh() || layer->nativeMesh()->vertexCount() <= vertexIndex )
1084  return QVariant();
1085 
1086  const QgsMeshVertex &vertex = layer->nativeMesh()->vertex( vertexIndex );
1087  if ( !vertex.isEmpty() )
1088  return vertex.y();
1089  else
1090  return QVariant();
1091  }
1092 
1093  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1094  {
1095  return false;
1096  }
1097 };
1098 
1099 class CurrentVertexExpressionFunction: public QgsScopedExpressionFunction
1100 {
1101  public:
1102  CurrentVertexExpressionFunction():
1103  QgsScopedExpressionFunction( "$vertex_as_point",
1104  0,
1105  QStringLiteral( "Meshes" ) )
1106  {}
1107 
1108  QgsScopedExpressionFunction *clone() const override {return new CurrentVertexExpressionFunction();}
1109 
1110  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1111  {
1112  if ( !context )
1113  return QVariant();
1114 
1115  if ( !context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1116  return QVariant();
1117 
1118  int vertexIndex = context->variable( QStringLiteral( "_mesh_vertex_index" ) ).toInt();
1119 
1120  QgsMeshLayer *layer = qobject_cast<QgsMeshLayer *>( qvariant_cast<QgsMapLayer *>( context->variable( QStringLiteral( "_mesh_layer" ) ) ) );
1121  if ( !layer || !layer->nativeMesh() || layer->nativeMesh()->vertexCount() <= vertexIndex )
1122  return QVariant();
1123 
1124  const QgsMeshVertex &vertex = layer->nativeMesh()->vertex( vertexIndex );
1125  if ( !vertex.isEmpty() )
1126  return QVariant::fromValue( QgsGeometry( new QgsPoint( vertex ) ) );
1127  else
1128  return QVariant();
1129  }
1130 
1131  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1132  {
1133  return false;
1134  }
1135 };
1136 
1137 class CurrentVertexIndexExpressionFunction: public QgsScopedExpressionFunction
1138 {
1139  public:
1140  CurrentVertexIndexExpressionFunction():
1141  QgsScopedExpressionFunction( "$vertex_index",
1142  0,
1143  QStringLiteral( "Meshes" ) )
1144  {}
1145 
1146  QgsScopedExpressionFunction *clone() const override {return new CurrentVertexIndexExpressionFunction();}
1147 
1148  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1149  {
1150  if ( !context )
1151  return QVariant();
1152 
1153  if ( !context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1154  return QVariant();
1155 
1156  return context->variable( QStringLiteral( "_mesh_vertex_index" ) );
1157  }
1158 
1159 
1160  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1161  {
1162  return false;
1163  }
1164 };
1165 
1166 class CurrentFaceAreaExpressionFunction: public QgsScopedExpressionFunction
1167 {
1168  public:
1169  CurrentFaceAreaExpressionFunction():
1170  QgsScopedExpressionFunction( "$face_area",
1171  0,
1172  QStringLiteral( "Meshes" ) )
1173  {}
1174 
1175  QgsScopedExpressionFunction *clone() const override {return new CurrentFaceAreaExpressionFunction();}
1176 
1177  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction * ) override
1178  {
1179  if ( !context )
1180  return QVariant();
1181 
1182  if ( !context->hasVariable( QStringLiteral( "_mesh_face_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1183  return QVariant();
1184 
1185  int faceIndex = context->variable( QStringLiteral( "_mesh_face_index" ) ).toInt();
1186 
1187  QgsMeshLayer *layer = qobject_cast<QgsMeshLayer *>( qvariant_cast<QgsMapLayer *>( context->variable( QStringLiteral( "_mesh_layer" ) ) ) );
1188  if ( !layer || !layer->nativeMesh() || layer->nativeMesh()->faceCount() <= faceIndex )
1189  return QVariant();
1190 
1191  const QgsMeshFace &face = layer->nativeMesh()->face( faceIndex );
1192  if ( !face.isEmpty() )
1193  {
1194  QgsDistanceArea *calc = parent->geomCalculator();
1195  QgsGeometry geom = QgsMeshUtils::toGeometry( layer->nativeMesh()->face( faceIndex ), layer->nativeMesh()->vertices );
1196  if ( calc )
1197  {
1198  double area = calc->measureArea( geom );
1199  area = calc->convertAreaMeasurement( area, parent->areaUnits() );
1200  return QVariant( area );
1201  }
1202  else
1203  {
1204  return QVariant( geom.area() );
1205  }
1206  }
1207  else
1208  return QVariant();
1209  }
1210 
1211  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1212  {
1213  return false;
1214  }
1215 };
1216 
1217 class CurrentFaceIndexExpressionFunction: public QgsScopedExpressionFunction
1218 {
1219  public:
1220  CurrentFaceIndexExpressionFunction():
1221  QgsScopedExpressionFunction( "$face_index",
1222  0,
1223  QStringLiteral( "Meshes" ) )
1224  {}
1225 
1226  QgsScopedExpressionFunction *clone() const override {return new CurrentFaceIndexExpressionFunction();}
1227 
1228  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1229  {
1230  if ( !context )
1231  return QVariant();
1232 
1233  if ( !context->hasVariable( QStringLiteral( "_mesh_face_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1234  return QVariant();
1235 
1236  return context->variable( QStringLiteral( "_mesh_face_index" ) ).toInt();
1237 
1238  }
1239 
1240  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1241  {
1242  return false;
1243  }
1244 };
1245 
1246 
1247 
1249 {
1250  std::unique_ptr<QgsExpressionContextScope> scope = std::make_unique<QgsExpressionContextScope>();
1251 
1252  switch ( elementType )
1253  {
1254  case QgsMesh::Vertex:
1255  {
1256  QgsExpression::registerFunction( new CurrentVertexExpressionFunction, true );
1257  QgsExpression::registerFunction( new CurrentVertexXValueExpressionFunction, true );
1258  QgsExpression::registerFunction( new CurrentVertexYValueExpressionFunction, true );
1259  QgsExpression::registerFunction( new CurrentVertexZValueExpressionFunction, true );
1260  QgsExpression::registerFunction( new CurrentVertexIndexExpressionFunction, true );
1261  scope->addFunction( "$vertex_as_point", new CurrentVertexExpressionFunction );
1262  scope->addFunction( "$vertex_x", new CurrentVertexXValueExpressionFunction );
1263  scope->addFunction( "$vertex_y", new CurrentVertexYValueExpressionFunction );
1264  scope->addFunction( "$vertex_z", new CurrentVertexZValueExpressionFunction );
1265  scope->addFunction( "$vertex_index", new CurrentVertexIndexExpressionFunction );
1266  }
1267  break;
1268  case QgsMesh::Face:
1269  {
1270  QgsExpression::registerFunction( new CurrentFaceAreaExpressionFunction, true );
1271  QgsExpression::registerFunction( new CurrentFaceIndexExpressionFunction, true );
1272  scope->addFunction( "$face_area", new CurrentFaceAreaExpressionFunction );
1273  scope->addFunction( "$face_index", new CurrentFaceIndexExpressionFunction );
1274  }
1275  break;
1276  case QgsMesh::Edge:
1277  break;
1278  }
1279 
1280  return scope.release();
1281 }
static QString version()
Version string.
Definition: qgis.cpp:285
static QString releaseName()
Release name.
Definition: qgis.cpp:297
static int versionInt()
Version number used for comparing versions using the "Check QGIS Version" function.
Definition: qgis.cpp:290
static void setCustomVariables(const QVariantMap &customVariables)
Custom expression variables for this application.
static QString osName()
Returns a string name of the operating system QGIS is running on.
static QString platform()
Returns the QGIS platform name, e.g., "desktop" or "server".
static QVariantMap customVariables()
Custom expression variables for this application.
static QString locale()
Returns the QGIS locale.
static void setCustomVariable(const QString &name, const QVariant &value)
Set a single custom expression variable.
static QString userFullName()
Returns the user's operating system login account full display name.
static QString userLoginName()
Returns the user's operating system login account name.
QString toProj() const
Returns a Proj string representation of this CRS.
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
QString description() const
Returns the descriptive name of the CRS, e.g., "WGS 84" or "GDA 94 / Vicgrid94".
QString projectionAcronym() const
Returns the projection acronym for the projection used by the CRS.
QString authid() const
Returns the authority identifier for the CRS.
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
QgsProjOperation operation() const
Returns information about the PROJ operation associated with the coordinate reference system,...
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
double measureArea(const QgsGeometry &geometry) const
Measures the area of a geometry.
double convertAreaMeasurement(double area, QgsUnitTypes::AreaUnit toUnits) const
Takes an area measurement calculated by this QgsDistanceArea object and converts it to a different ar...
Single scope for storing variables and functions for use within a QgsExpressionContext.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the scope.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the scope.
void addFunction(const QString &name, QgsScopedExpressionFunction *function)
Adds a function to the scope.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context 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.
static QgsExpressionContextScope * layoutItemScope(const QgsLayoutItem *item)
Creates a new scope which contains variables and functions relating to a QgsLayoutItem.
static void setLayoutMultiFrameVariable(QgsLayoutMultiFrame *frame, const QString &name, const QVariant &value)
Sets a layout multi frame context variable, with the given name and value.
static void setLayerVariable(QgsMapLayer *layer, const QString &name, const QVariant &value)
Sets a layer context variable.
static QgsExpressionContextScope * processingModelAlgorithmScope(const QgsProcessingModelAlgorithm *model, const QVariantMap &parameters, QgsProcessingContext &context)
Creates a new scope which contains variables and functions relating to a processing model algorithm,...
static QgsExpressionContextScope * updateSymbolScope(const QgsSymbol *symbol, QgsExpressionContextScope *symbolScope=nullptr)
Updates a symbol scope related to a QgsSymbol to an expression context.
static void setProjectVariables(QgsProject *project, const QVariantMap &variables)
Sets all project context variables.
static QgsExpressionContextScope * layoutScope(const QgsLayout *layout)
Creates a new scope which contains variables and functions relating to a QgsLayout layout.
static QgsExpressionContext createFeatureBasedContext(const QgsFeature &feature, const QgsFields &fields)
Helper function for creating an expression context which contains just a feature and fields collectio...
static QgsExpressionContextScope * meshExpressionScope(QgsMesh::ElementType elementType)
Creates a new scope which contains functions relating to mesh layer element elementType.
static void removeProjectVariable(QgsProject *project, const QString &name)
Remove project context variable.
static void setLayerVariables(QgsMapLayer *layer, const QVariantMap &variables)
Sets all layer context variables.
static void setGlobalVariables(const QVariantMap &variables)
Sets all global context variables.
static void setLayoutItemVariables(QgsLayoutItem *item, const QVariantMap &variables)
Sets all layout item context variables for an item.
static void setLayoutMultiFrameVariables(QgsLayoutMultiFrame *frame, const QVariantMap &variables)
Sets all layout multiframe context variables for an frame.
static QgsExpressionContextScope * processingAlgorithmScope(const QgsProcessingAlgorithm *algorithm, const QVariantMap &parameters, QgsProcessingContext &context)
Creates a new scope which contains variables and functions relating to a processing algorithm,...
static QgsExpressionContextScope * notificationScope(const QString &message=QString())
Creates a new scope which contains variables and functions relating to provider notifications.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * parentFormScope(const QgsFeature &formFeature=QgsFeature(), const QString &formMode=QString())
Creates a new scope which contains functions and variables from the current parent attribute form/tab...
static void setLayoutVariable(QgsLayout *layout, const QString &name, const QVariant &value)
Sets a layout context variable.
static QgsExpressionContextScope * formScope(const QgsFeature &formFeature=QgsFeature(), const QString &formMode=QString())
Creates a new scope which contains functions and variables from the current attribute form/table form...
static QgsExpressionContextScope * multiFrameScope(const QgsLayoutMultiFrame *frame)
Creates a new scope which contains variables and functions relating to a QgsLayoutMultiFrame.
static void setLayoutItemVariable(QgsLayoutItem *item, const QString &name, const QVariant &value)
Sets a layout item context variable, with the given name and value.
static QgsExpressionContextScope * mapToolCaptureScope(const QList< QgsPointLocator::Match > &matches)
Sets the expression context variables which are available for expressions triggered by a map tool cap...
static QgsExpressionContextScope * atlasScope(const QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
static void registerContextFunctions()
Registers all known core functions provided by QgsExpressionContextScope objects.
static void setLayoutVariables(QgsLayout *layout, const QVariantMap &variables)
Sets all layout context variables.
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
static void removeGlobalVariable(const QString &name)
Remove a global context variable.
static void setGlobalVariable(const QString &name, const QVariant &value)
Sets a global context variable.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
static void setProjectVariable(QgsProject *project, const QString &name, const QVariant &value)
Sets a project context variable.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static const QString EXPR_SYMBOL_COLOR
Inbuilt variable name for symbol color variable.
bool hasVariable(const QString &name) const
Check whether a variable is specified by any scope within the context.
static const QString EXPR_SYMBOL_ANGLE
Inbuilt variable name for symbol angle variable.
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
A abstract base class for defining QgsExpression functions.
static bool allParamsStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context)
This will return true if all the params for the provided function node are static within the constrai...
An expression node for expression functions.
Class for parsing and evaluation of expressions (formerly called "search strings").
static bool registerFunction(QgsExpressionFunction *function, bool transferOwnership=false)
Registers a function to the expression engine.
QgsUnitTypes::AreaUnit areaUnits() const
Returns the desired areal units for calculations involving geomCalculator(), e.g.,...
QgsDistanceArea * geomCalculator()
Returns calculator used for distance and area calculations (used by $length, $area and $perimeter fun...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
QgsGeometry geometry
Definition: qgsfeature.h:67
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:191
Q_GADGET QgsFeatureId id
Definition: qgsfeature.h:64
Container of fields for a vector layer.
Definition: qgsfields.h:45
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
static QgsGeometry fromPointXY(const QgsPointXY &point) SIP_HOLDGIL
Creates a new geometry from a QgsPointXY object.
double area() const
Returns the planar, 2-dimensional area of the geometry.
Class used to render QgsLayout as an atlas, by iterating over the features from an associated vector ...
QString nameForPage(int page) const
Returns the calculated name for a specified atlas page number.
QgsVectorLayer * coverageLayer() const
Returns the coverage layer used for the atlas features.
QgsLayout * layout() override
Returns the layout associated with the iterator.
bool enabled() const
Returns whether the atlas generation is enabled.
QString currentFilename() const
Returns the current feature filename.
int count() const override
Returns the number of features to iterate over.
int currentFeatureNumber() const
Returns the current feature number, where a value of 0 corresponds to the first feature.
Layout graphical items for displaying a map.
Item representing the paper in a layout.
Base class for graphical items within a QgsLayout.
QgsLayoutSize sizeWithUnits() const
Returns the item's current size, including units.
int page() const
Returns the page the item is currently on, with the first page returning 0.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
virtual QString uuid() const
Returns the item identification string.
QString id() const
Returns the item's ID name.
Abstract base class for layout items with the ability to distribute the content to several frames (Qg...
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from the object.
const QgsLayout * layout() const
Returns the layout the object is attached to.
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for the object.
QPointF pagePositionToLayoutPosition(int page, const QgsLayoutPoint &position) const
Converts a position on a page to an absolute position in layout coordinates.
int pageCount() const
Returns the number of pages in the collection.
QgsLayoutItemPage * page(int pageNumber)
Returns a specific page (by pageNumber) from the collection.
This class provides a method of storing points, consisting of an x and y coordinate,...
double dpi() const
Returns the dpi for outputting the layout.
QgsFeature feature() const
Returns the current feature for evaluating the layout.
QgsVectorLayer * layer() const
Returns the vector layer associated with the layout's context.
QSizeF toQSizeF() const
Converts the layout size to a QSizeF.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:51
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for the layout.
Definition: qgslayout.cpp:407
QgsLayoutRenderContext & renderContext()
Returns a reference to the layout's render context, which stores information relating to the current ...
Definition: qgslayout.cpp:359
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout's page collection, which stores and manages page items in the layout.
Definition: qgslayout.cpp:459
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from the layout.
Definition: qgslayout.cpp:415
QgsLayoutReportContext & reportContext()
Returns a reference to the layout's report context, which stores information relating to the current ...
Definition: qgslayout.cpp:369
Base class for all map layer types.
Definition: qgsmaplayer.h:73
QString name
Definition: qgsmaplayer.h:76
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
The QgsMapSettings class contains configuration for rendering of the map.
double scale() const
Returns the calculated map scale.
QgsUnitTypes::DistanceUnit mapUnits() const
Returns the units of the map's geographical coordinates - used for scale calculation.
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
QList< QgsMapLayer * > layers() const
Returns the list of layers which will be rendered in the map.
double rotation() const
Returns the rotation of the resulting map image, in degrees clockwise.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
A marker symbol type, for rendering Point and MultiPoint geometries.
double angle() const
Returns the marker angle for the whole symbol.
Interface for master layout type objects, such as print layouts and reports.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:97
QgsMesh * nativeMesh()
Returns native mesh (nullptr before rendering or calling to updateMesh)
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
bool isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
Definition: qgspoint.cpp:767
Q_GADGET double x
Definition: qgspoint.h:52
double z
Definition: qgspoint.h:54
double y
Definition: qgspoint.h:53
Abstract base class for processing algorithms.
QString id() const
Returns the unique ID for the algorithm, which is a combination of the algorithm provider's ID and th...
Contains information about the context in which a processing algorithm is executed.
QgsProject * project() const
Returns the project in which the algorithm is being executed.
QString description() const
Description.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:101
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:467
QgsExpressionContextScope * createExpressionContextScope() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QString fileName
Definition: qgsproject.h:104
QString absoluteFilePath() const
Returns full absolute path to the project file if the project is stored in a file system - derived fr...
Definition: qgsproject.cpp:698
QVariantMap customVariables() const
A map of custom project variables.
void setCustomVariables(const QVariantMap &customVariables)
A map of custom project variables.
QgsProjectStorage * projectStorage() const
Returns pointer to project storage implementation that handles read/write of the project file.
Definition: qgsproject.cpp:668
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:230
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Definition: qgsrectangle.h:251
Expression function for use within a QgsExpressionContextScope.
QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const override
Returns a set of field names which are required for this function.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
bool usesGeometry(const QgsExpressionNodeFunction *node) const override
Does this function use a geometry object.
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override=0
Returns result of evaluating the function.
virtual QgsScopedExpressionFunction * clone() const =0
Returns a clone of the function.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:38
QColor color() const
Returns the symbol's color.
Definition: qgssymbol.cpp:551
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
bool isTemporal() const
Returns true if the object's temporal range is enabled, and the object will be filtered when renderin...
static Q_INVOKABLE QString toString(QgsUnitTypes::DistanceUnit unit)
Returns a translated string representing a distance unit.
Represents a vector layer which manages a vector based data sets.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
Definition: MathUtils.cpp:786
CORE_EXPORT QgsGeometry toGeometry(const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Returns face as polygon geometry.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:1234
#define FID_IS_NULL(fid)
Definition: qgsfeatureid.h:30
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
Definition: qgsmaplayer.h:2129
QVector< int > QgsMeshFace
List of vertex indexes.
Single variable definition for use within a QgsExpressionContextScope.
int vertexCount() const
Returns number of vertices.
QVector< QgsMeshVertex > vertices
QgsMeshFace face(int index) const
Returns a face at the index.
int faceCount() const
Returns number of faces.
ElementType
Defines type of mesh elements.
QgsMeshVertex vertex(int index) const
Returns a vertex at the index.