QGIS API Documentation  3.24.2-Tisler (13c1a02865)
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"
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_p.h"
35 #include "qgsprojoperation.h"
36 #include "qgsmarkersymbol.h"
37 #include "qgstriangularmesh.h"
38 #include "qgsvectortileutils.h"
39 
41 {
42  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Global" ) );
43 
44  const QVariantMap customVariables = QgsApplication::customVariables();
45 
46  for ( QVariantMap::const_iterator it = customVariables.constBegin(); it != customVariables.constEnd(); ++it )
47  {
48  scope->setVariable( it.key(), it.value(), true );
49  }
50 
51  //add some extra global variables
52  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_version" ), Qgis::version(), true, true ) );
53  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_version_no" ), Qgis::versionInt(), true, true ) );
54  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_short_version" ), QStringLiteral( "%1.%2" ).arg( Qgis::versionInt() / 10000 ).arg( Qgis::versionInt() / 100 % 100 ), true, true ) );
55  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_release_name" ), Qgis::releaseName(), true, true ) );
56  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_platform" ), QgsApplication::platform(), true, true ) );
57  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_os_name" ), QgsApplication::osName(), true, true ) );
58  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_locale" ), QgsApplication::locale(), true, true ) );
59  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "user_account_name" ), QgsApplication::userLoginName(), true, true ) );
60  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "user_full_name" ), QgsApplication::userFullName(), true, true ) );
61 
62  return scope;
63 }
64 
65 void QgsExpressionContextUtils::setGlobalVariable( const QString &name, const QVariant &value )
66 {
67  QgsApplication::setCustomVariable( name, value );
68 }
69 
70 void QgsExpressionContextUtils::setGlobalVariables( const QVariantMap &variables )
71 {
73 }
74 
76 {
77  QVariantMap vars = QgsApplication::customVariables();
78  if ( vars.remove( name ) )
80 }
81 
83 
84 class GetLayoutItemVariables : public QgsScopedExpressionFunction
85 {
86  public:
87  GetLayoutItemVariables( const QgsLayout *c )
88  : QgsScopedExpressionFunction( QStringLiteral( "item_variables" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "Layout" ) )
89  , mLayout( c )
90  {}
91 
92  QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
93  {
94  if ( !mLayout )
95  return QVariant();
96 
97  const QString id = values.at( 0 ).toString();
98 
99  const QgsLayoutItem *item = mLayout->itemById( id );
100  if ( !item )
101  return QVariant();
102 
104 
105  return c.variablesToMap();
106  }
107 
108  QgsScopedExpressionFunction *clone() const override
109  {
110  return new GetLayoutItemVariables( mLayout );
111  }
112 
113  private:
114 
115  const QgsLayout *mLayout = nullptr;
116 
117 };
118 
119 
120 class GetLayoutMapLayerCredits : public QgsScopedExpressionFunction
121 {
122  public:
123  GetLayoutMapLayerCredits( const QgsLayout *c )
124  : QgsScopedExpressionFunction( QStringLiteral( "map_credits" ),
125  QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) )
126  << QgsExpressionFunction::Parameter( QStringLiteral( "include_layer_names" ), true, false )
127  << QgsExpressionFunction::Parameter( QStringLiteral( "layer_name_separator" ), true, QStringLiteral( ": " ) ), QStringLiteral( "Layout" ) )
128  , mLayout( c )
129  {}
130 
131  QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
132  {
133  if ( !mLayout )
134  return QVariant();
135 
136  const QString id = values.value( 0 ).toString();
137 
138  if ( QgsLayoutItemMap *map = qobject_cast< QgsLayoutItemMap * >( mLayout->itemById( id ) ) )
139  {
140  const QgsExpressionContext c = map->createExpressionContext();
141  const QVariantList mapLayers = c.variable( QStringLiteral( "map_layers" ) ).toList();
142 
143  const bool includeLayerNames = values.value( 1 ).toBool();
144  const QString layerNameSeparator = values.value( 2 ).toString();
145 
146  QVariantList res;
147  for ( const QVariant &value : mapLayers )
148  {
149  if ( const QgsMapLayer *layer = qobject_cast< const QgsMapLayer * >( value.value< QObject * >() ) )
150  {
151  const QStringList credits = !layer->metadata().rights().isEmpty() ? layer->metadata().rights() : QStringList() << layer->attribution();
152  for ( const QString &credit : credits )
153  {
154  if ( credit.trimmed().isEmpty() )
155  continue;
156 
157  const QString creditString = includeLayerNames ? layer->name() + layerNameSeparator + credit
158  : credit;
159 
160  if ( !res.contains( creditString ) )
161  res << creditString;
162  }
163  }
164  }
165 
166  return res;
167  }
168  return QVariant();
169  }
170 
171  QgsScopedExpressionFunction *clone() const override
172  {
173  return new GetLayoutMapLayerCredits( mLayout );
174  }
175 
176  private:
177 
178  const QgsLayout *mLayout = nullptr;
179 
180 };
181 
182 class GetCurrentFormFieldValue : public QgsScopedExpressionFunction
183 {
184  public:
185  GetCurrentFormFieldValue( )
186  : QgsScopedExpressionFunction( QStringLiteral( "current_value" ), QgsExpressionFunction::ParameterList() << QStringLiteral( "field_name" ), QStringLiteral( "Form" ) )
187  {}
188 
189  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
190  {
191  const QString fieldName( values.at( 0 ).toString() );
192  const QgsFeature feat( context->variable( QStringLiteral( "current_feature" ) ).value<QgsFeature>() );
193  if ( fieldName.isEmpty() || ! feat.isValid( ) )
194  {
195  return QVariant();
196  }
197  return feat.attribute( fieldName ) ;
198  }
199 
200  QgsScopedExpressionFunction *clone() const override
201  {
202  return new GetCurrentFormFieldValue( );
203  }
204 
205  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
206  {
207  return false;
208  };
209 
210 };
211 
212 class GetCurrentParentFormFieldValue : public QgsScopedExpressionFunction
213 {
214  public:
215  GetCurrentParentFormFieldValue( )
216  : QgsScopedExpressionFunction( QStringLiteral( "current_parent_value" ), QgsExpressionFunction::ParameterList() << QStringLiteral( "field_name" ), QStringLiteral( "Form" ) )
217  {}
218 
219  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
220  {
221  const QString fieldName( values.at( 0 ).toString() );
222  const QgsFeature feat( context->variable( QStringLiteral( "current_parent_feature" ) ).value<QgsFeature>() );
223  if ( fieldName.isEmpty() || ! feat.isValid( ) )
224  {
225  return QVariant();
226  }
227  return feat.attribute( fieldName ) ;
228  }
229 
230  QgsScopedExpressionFunction *clone() const override
231  {
232  return new GetCurrentParentFormFieldValue( );
233  }
234 
235  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
236  {
237  return false;
238  };
239 
240 };
241 
242 
243 class GetProcessingParameterValue : public QgsScopedExpressionFunction
244 {
245  public:
246  GetProcessingParameterValue( const QVariantMap &params )
247  : QgsScopedExpressionFunction( QStringLiteral( "parameter" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "name" ) ), QStringLiteral( "Processing" ) )
248  , mParams( params )
249  {}
250 
251  QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
252  {
253  return mParams.value( values.at( 0 ).toString() );
254  }
255 
256  QgsScopedExpressionFunction *clone() const override
257  {
258  return new GetProcessingParameterValue( mParams );
259  }
260 
261  private:
262 
263  const QVariantMap mParams;
264 
265 };
266 
268 
269 
270 QgsExpressionContextScope *QgsExpressionContextUtils::formScope( const QgsFeature &formFeature, const QString &formMode )
271 {
272  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Form" ) );
273  scope->addFunction( QStringLiteral( "current_value" ), new GetCurrentFormFieldValue( ) );
274  scope->setVariable( QStringLiteral( "current_geometry" ), formFeature.geometry( ), true );
275  scope->setVariable( QStringLiteral( "current_feature" ), formFeature, true );
276  scope->setVariable( QStringLiteral( "form_mode" ), formMode, true );
277  return scope;
278 }
279 
280 
281 QgsExpressionContextScope *QgsExpressionContextUtils::parentFormScope( const QgsFeature &parentFormFeature, const QString &parentFormMode )
282 {
283  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Parent Form" ) );
284  scope->addFunction( QStringLiteral( "current_parent_value" ), new GetCurrentParentFormFieldValue( ) );
285  scope->setVariable( QStringLiteral( "current_parent_geometry" ), parentFormFeature.geometry( ), true );
286  scope->setVariable( QStringLiteral( "current_parent_feature" ), parentFormFeature, true );
287  scope->setVariable( QStringLiteral( "parent_form_mode" ), parentFormMode, true );
288  return scope;
289 }
290 
292 {
293  if ( !project )
294  {
295  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Project" ) );
296  return scope;
297  }
298  else
299  return project->createExpressionContextScope();
300 }
301 
302 void QgsExpressionContextUtils::setProjectVariable( QgsProject *project, const QString &name, const QVariant &value )
303 {
304  if ( !project )
305  return;
306 
307  QVariantMap vars = project->customVariables();
308 
309  vars.insert( name, value );
310 
311  project->setCustomVariables( vars );
312 }
313 
314 void QgsExpressionContextUtils::setProjectVariables( QgsProject *project, const QVariantMap &variables )
315 {
316  if ( !project )
317  return;
318 
319  project->setCustomVariables( variables );
320 }
321 
323 {
324  if ( !project )
325  {
326  return;
327  }
328 
329  QVariantMap vars = project->customVariables();
330  if ( vars.remove( name ) )
331  project->setCustomVariables( vars );
332 }
333 
335 {
336  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Layer" ) );
337 
338  if ( !layer )
339  return scope;
340 
341  //add variables defined in layer properties
342  const QStringList variableNames = layer->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
343  const QStringList variableValues = layer->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
344 
345  int varIndex = 0;
346  for ( const QString &variableName : variableNames )
347  {
348  if ( varIndex >= variableValues.length() )
349  {
350  break;
351  }
352 
353  const QVariant varValue = variableValues.at( varIndex );
354  varIndex++;
355  scope->setVariable( variableName, varValue, true );
356  }
357 
358  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_name" ), layer->name(), true, true ) );
359  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_id" ), layer->id(), true, true ) );
360  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "_layer_crs" ), QVariant::fromValue<QgsCoordinateReferenceSystem>( layer->crs() ), true, true ) );
361  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_crs" ), layer->crs().authid(), true, true ) );
362  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer" ), QVariant::fromValue<QgsWeakMapLayerPointer >( QgsWeakMapLayerPointer( const_cast<QgsMapLayer *>( layer ) ) ), true, true ) );
363 
364  const QgsVectorLayer *vLayer = qobject_cast< const QgsVectorLayer * >( layer );
365  if ( vLayer )
366  {
367  scope->setFields( vLayer->fields() );
368  }
369 
370  //TODO - add functions. Possibilities include:
371  //is_selected
372  //field summary stats
373 
374  return scope;
375 }
376 
377 QList<QgsExpressionContextScope *> QgsExpressionContextUtils::globalProjectLayerScopes( const QgsMapLayer *layer )
378 {
379  QList<QgsExpressionContextScope *> scopes;
380  scopes << globalScope();
381 
382  QgsProject *project = QgsProject::instance(); // TODO: use project associated with layer
383  if ( project )
384  scopes << projectScope( project );
385 
386  if ( layer )
387  scopes << layerScope( layer );
388  return scopes;
389 }
390 
391 
392 void QgsExpressionContextUtils::setLayerVariable( QgsMapLayer *layer, const QString &name, const QVariant &value )
393 {
394  if ( !layer )
395  return;
396 
397  //write variable to layer
398  QStringList variableNames = layer->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
399  QStringList variableValues = layer->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
400 
401  variableNames << name;
402  variableValues << value.toString();
403 
404  layer->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
405  layer->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
406 }
407 
408 void QgsExpressionContextUtils::setLayerVariables( QgsMapLayer *layer, const QVariantMap &variables )
409 {
410  if ( !layer )
411  return;
412 
413  QStringList variableNames;
414  QStringList variableValues;
415 
416  QVariantMap::const_iterator it = variables.constBegin();
417  for ( ; it != variables.constEnd(); ++it )
418  {
419  variableNames << it.key();
420  variableValues << it.value().toString();
421  }
422 
423  layer->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
424  layer->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
425 }
426 
428 {
429  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
430  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
431 
432  // and because people don't read that ^^, I'm going to blast it all over this function
433 
434  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Map Settings" ) );
435 
436  //add known map settings context variables
437  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_id" ), "canvas", true ) );
438  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_rotation" ), mapSettings.rotation(), true ) );
439  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_scale" ), mapSettings.scale(), true ) );
440 
441  scope->setVariable( QStringLiteral( "zoom_level" ), QgsVectorTileUtils::scaleToZoomLevel( mapSettings.scale(), 0, 99999 ), true );
442  scope->setVariable( QStringLiteral( "vector_tile_zoom" ), QgsVectorTileUtils::scaleToZoom( mapSettings.scale() ), true );
443 
444  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
445  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
446 
447  const QgsGeometry extent = QgsGeometry::fromRect( mapSettings.visibleExtent() );
448  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent" ), QVariant::fromValue( extent ), true ) );
449  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_width" ), mapSettings.visibleExtent().width(), true ) );
450  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_height" ), mapSettings.visibleExtent().height(), true ) );
451 
452  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
453  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
454 
455  const QgsGeometry centerPoint = QgsGeometry::fromPointXY( mapSettings.visibleExtent().center() );
456  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_center" ), QVariant::fromValue( centerPoint ), true ) );
457 
458  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
459  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
460 
461  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs" ), mapSettings.destinationCrs().authid(), true ) );
462  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_definition" ), mapSettings.destinationCrs().toProj(), true ) );
463  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_units" ), QgsUnitTypes::toString( mapSettings.mapUnits() ), true ) );
464  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_description" ), mapSettings.destinationCrs().description(), true ) );
465  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_acronym" ), mapSettings.destinationCrs().projectionAcronym(), true ) );
466  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_projection" ), mapSettings.destinationCrs().operation().description(), true ) );
467  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_ellipsoid" ), mapSettings.destinationCrs().ellipsoidAcronym(), true ) );
468  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_proj4" ), mapSettings.destinationCrs().toProj(), true ) );
469  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_wkt" ), mapSettings.destinationCrs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ), true ) );
470 
471  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
472  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
473 
474  QVariantList layersIds;
475  QVariantList layers;
476  const QList<QgsMapLayer *> layersInMap = mapSettings.layers( true );
477  layersIds.reserve( layersInMap.count() );
478  layers.reserve( layersInMap.count() );
479  for ( QgsMapLayer *layer : layersInMap )
480  {
481  layersIds << layer->id();
482  layers << QVariant::fromValue<QgsWeakMapLayerPointer>( QgsWeakMapLayerPointer( layer ) );
483  }
484 
485  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
486  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
487 
488  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_layer_ids" ), layersIds, true ) );
489  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_layers" ), layers, true ) );
490 
491  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
492  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
493 
494  scope->addFunction( QStringLiteral( "is_layer_visible" ), new GetLayerVisibility( mapSettings.layers( true ), mapSettings.scale() ) );
495 
496  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
497  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
498 
499  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_start_time" ), mapSettings.isTemporal() ? mapSettings.temporalRange().begin() : QVariant(), true ) );
500  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_end_time" ), mapSettings.isTemporal() ? mapSettings.temporalRange().end() : QVariant(), true ) );
501  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_interval" ), mapSettings.isTemporal() ? ( mapSettings.temporalRange().end() - mapSettings.temporalRange().begin() ) : QVariant(), true ) );
502 
503  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
504  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
505 
506  return scope;
507 }
508 
509 QgsExpressionContextScope *QgsExpressionContextUtils::mapToolCaptureScope( const QList<QgsPointLocator::Match> &matches )
510 {
511  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Map Tool Capture" ) );
512 
513  QVariantList matchList;
514 
515  for ( const QgsPointLocator::Match &match : matches )
516  {
517  QVariantMap matchMap;
518 
519  matchMap.insert( QStringLiteral( "valid" ), match.isValid() );
520  matchMap.insert( QStringLiteral( "layer" ), QVariant::fromValue<QgsWeakMapLayerPointer>( QgsWeakMapLayerPointer( match.layer() ) ) );
521  matchMap.insert( QStringLiteral( "feature_id" ), match.featureId() );
522  matchMap.insert( QStringLiteral( "vertex_index" ), match.vertexIndex() );
523  matchMap.insert( QStringLiteral( "distance" ), match.distance() );
524 
525  matchList.append( matchMap );
526  }
527 
528  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "snapping_results" ), matchList ) );
529 
530  return scope;
531 }
532 
534 {
535  if ( !symbolScope )
536  return nullptr;
537 
538  symbolScope->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_SYMBOL_COLOR, symbol ? symbol->color() : QColor(), true ) );
539 
540  double angle = 0.0;
541  const QgsMarkerSymbol *markerSymbol = dynamic_cast< const QgsMarkerSymbol * >( symbol );
542  if ( markerSymbol )
543  {
544  angle = markerSymbol->angle();
545  }
547 
548  return symbolScope;
549 }
550 
552 {
553  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope( QObject::tr( "Layout" ) ) );
554  if ( !layout )
555  return scope.release();
556 
557  //add variables defined in layout properties
558  const QStringList variableNames = layout->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
559  const QStringList variableValues = layout->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
560 
561  int varIndex = 0;
562 
563  for ( const QString &variableName : variableNames )
564  {
565  if ( varIndex >= variableValues.length() )
566  {
567  break;
568  }
569 
570  const QVariant varValue = variableValues.at( varIndex );
571  varIndex++;
572  scope->setVariable( variableName, varValue );
573  }
574 
575  //add known layout context variables
576  if ( const QgsMasterLayoutInterface *l = dynamic_cast< const QgsMasterLayoutInterface * >( layout ) )
577  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_name" ), l->name(), true ) );
578 
579  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_numpages" ), layout->pageCollection()->pageCount(), true ) );
580  if ( layout->pageCollection()->pageCount() > 0 )
581  {
582  // just take first page size
583  const QSizeF s = layout->pageCollection()->page( 0 )->sizeWithUnits().toQSizeF();
584  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), s.height(), true ) );
585  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), s.width(), true ) );
586  }
587 
588  QVariantList offsets;
589  for ( int i = 0; i < layout->pageCollection()->pageCount(); i++ )
590  {
591  const QPointF p = layout->pageCollection()->pagePositionToLayoutPosition( i, QgsLayoutPoint( 0, 0 ) );
592  offsets << p.y();
593  }
594  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageoffsets" ), offsets, true ) );
595 
596  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_dpi" ), layout->renderContext().dpi(), true ) );
597 
598  scope->addFunction( QStringLiteral( "item_variables" ), new GetLayoutItemVariables( layout ) );
599  scope->addFunction( QStringLiteral( "map_credits" ), new GetLayoutMapLayerCredits( layout ) );
600 
601  if ( layout->reportContext().layer() )
602  {
603  scope->setFields( layout->reportContext().layer()->fields() );
604  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layerid" ), layout->reportContext().layer()->id(), true ) );
605  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layername" ), layout->reportContext().layer()->name(), true ) );
606  }
607 
608  if ( layout->reportContext().feature().isValid() )
609  {
610  const QgsFeature atlasFeature = layout->reportContext().feature();
611  scope->setFeature( atlasFeature );
612  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( atlasFeature ), true ) );
613  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), FID_IS_NULL( atlasFeature.id() ) ? QVariant() : atlasFeature.id(), true ) );
614  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( atlasFeature.geometry() ), true ) );
615  }
616 
617  return scope.release();
618 }
619 
620 void QgsExpressionContextUtils::setLayoutVariable( QgsLayout *layout, const QString &name, const QVariant &value )
621 {
622  if ( !layout )
623  return;
624 
625  //write variable to layout
626  QStringList variableNames = layout->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
627  QStringList variableValues = layout->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
628 
629  variableNames << name;
630  variableValues << value.toString();
631 
632  layout->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
633  layout->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
634 }
635 
636 void QgsExpressionContextUtils::setLayoutVariables( QgsLayout *layout, const QVariantMap &variables )
637 {
638  if ( !layout )
639  return;
640 
641  QStringList variableNames;
642  QStringList variableValues;
643 
644  QVariantMap::const_iterator it = variables.constBegin();
645  for ( ; it != variables.constEnd(); ++it )
646  {
647  variableNames << it.key();
648  variableValues << it.value().toString();
649  }
650 
651  layout->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
652  layout->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
653 }
654 
656 {
657  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Atlas" ) );
658  if ( !atlas )
659  {
660  //add some dummy atlas variables. This is done so that as in certain contexts we want to show
661  //users that these variables are available even if they have no current value
662  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_pagename" ), QString(), true, true ) );
663  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( QgsFeature() ), true, true ) );
664  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), QVariant(), true, true ) );
665  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( QgsGeometry() ), true, true ) );
666  return scope;
667  }
668 
669  //add known atlas variables
670  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_totalfeatures" ), atlas->count(), true, true ) );
671  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featurenumber" ), atlas->currentFeatureNumber() + 1, true, true ) );
672  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_filename" ), atlas->currentFilename(), true, true ) );
673  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_pagename" ), atlas->nameForPage( atlas->currentFeatureNumber() ), true, true ) );
674 
675  if ( atlas->enabled() && atlas->coverageLayer() )
676  {
677  scope->setFields( atlas->coverageLayer()->fields() );
678  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layerid" ), atlas->coverageLayer()->id(), true ) );
679  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layername" ), atlas->coverageLayer()->name(), true ) );
680  }
681 
682  if ( atlas->enabled() )
683  {
684  const QgsFeature atlasFeature = atlas->layout()->reportContext().feature();
685  scope->setFeature( atlasFeature );
686  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( atlasFeature ), true ) );
687  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), FID_IS_NULL( atlasFeature.id() ) ? QVariant() : atlasFeature.id(), true ) );
688  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( atlasFeature.geometry() ), true ) );
689  }
690 
691  return scope;
692 }
693 
695 {
696  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Layout Item" ) );
697  if ( !item )
698  return scope;
699 
700  //add variables defined in layout item properties
701  const QStringList variableNames = item->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
702  const QStringList variableValues = item->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
703 
704  int varIndex = 0;
705  for ( const QString &variableName : variableNames )
706  {
707  if ( varIndex >= variableValues.length() )
708  {
709  break;
710  }
711 
712  const QVariant varValue = variableValues.at( varIndex );
713  varIndex++;
714  scope->setVariable( variableName, varValue );
715  }
716 
717  //add known layout item context variables
718  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "item_id" ), item->id(), true ) );
719  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "item_uuid" ), item->uuid(), true ) );
720  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_page" ), item->page() + 1, true ) );
721 
722  if ( item->layout() )
723  {
724  const QgsLayoutItemPage *page = item->layout()->pageCollection()->page( item->page() );
725  if ( page )
726  {
727  const QSizeF s = page->sizeWithUnits().toQSizeF();
728  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), s.height(), true ) );
729  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), s.width(), true ) );
730  }
731  else
732  {
733  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), QVariant(), true ) );
734  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), QVariant(), true ) );
735  }
736  }
737 
738  return scope;
739 }
740 
741 void QgsExpressionContextUtils::setLayoutItemVariable( QgsLayoutItem *item, const QString &name, const QVariant &value )
742 {
743  if ( !item )
744  return;
745 
746  //write variable to layout item
747  QStringList variableNames = item->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
748  QStringList variableValues = item->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
749 
750  variableNames << name;
751  variableValues << value.toString();
752 
753  item->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
754  item->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
755 }
756 
757 void QgsExpressionContextUtils::setLayoutItemVariables( QgsLayoutItem *item, const QVariantMap &variables )
758 {
759  if ( !item )
760  return;
761 
762  QStringList variableNames;
763  QStringList variableValues;
764 
765  QVariantMap::const_iterator it = variables.constBegin();
766  for ( ; it != variables.constEnd(); ++it )
767  {
768  variableNames << it.key();
769  variableValues << it.value().toString();
770  }
771 
772  item->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
773  item->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
774 }
775 
777 {
778  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Multiframe Item" ) );
779  if ( !frame )
780  return scope;
781 
782  //add variables defined in layout item properties
783  const QStringList variableNames = frame->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
784  const QStringList variableValues = frame->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
785 
786  int varIndex = 0;
787  for ( const QString &variableName : variableNames )
788  {
789  if ( varIndex >= variableValues.length() )
790  {
791  break;
792  }
793 
794  const QVariant varValue = variableValues.at( varIndex );
795  varIndex++;
796  scope->setVariable( variableName, varValue );
797  }
798 
799  return scope;
800 }
801 
802 void QgsExpressionContextUtils::setLayoutMultiFrameVariable( QgsLayoutMultiFrame *frame, const QString &name, const QVariant &value )
803 {
804  if ( !frame )
805  return;
806 
807  //write variable to layout multiframe
808  QStringList variableNames = frame->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
809  QStringList variableValues = frame->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
810 
811  variableNames << name;
812  variableValues << value.toString();
813 
814  frame->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
815  frame->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
816 }
817 
819 {
820  if ( !frame )
821  return;
822 
823  QStringList variableNames;
824  QStringList variableValues;
825 
826  QVariantMap::const_iterator it = variables.constBegin();
827  for ( ; it != variables.constEnd(); ++it )
828  {
829  variableNames << it.key();
830  variableValues << it.value().toString();
831  }
832 
833  frame->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
834  frame->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
835 }
836 
838 {
840  scope->setFeature( feature );
841  scope->setFields( fields );
842  return QgsExpressionContext() << scope;
843 }
844 
846 {
847  // set aside for future use
848  Q_UNUSED( context )
849 
850  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope( QObject::tr( "Algorithm" ) ) );
851  scope->addFunction( QStringLiteral( "parameter" ), new GetProcessingParameterValue( parameters ) );
852 
853  if ( !algorithm )
854  return scope.release();
855 
856  //add standard algorithm variables
857  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "algorithm_id" ), algorithm->id(), true ) );
858 
859  return scope.release();
860 }
861 
862 QgsExpressionContextScope *QgsExpressionContextUtils::processingModelAlgorithmScope( const QgsProcessingModelAlgorithm *model, const QVariantMap &, QgsProcessingContext &context )
863 {
864  std::unique_ptr< QgsExpressionContextScope > modelScope( new QgsExpressionContextScope( QObject::tr( "Model" ) ) );
865  QString modelPath;
866  if ( !model->sourceFilePath().isEmpty() )
867  {
868  modelPath = model->sourceFilePath();
869  }
870  else if ( context.project() )
871  {
872  // fallback to project path -- the model may be embedded in a project, OR an unsaved model. In either case the
873  // project path is a logical value to fall back to
874  modelPath = context.project()->projectStorage() ? context.project()->fileName() : context.project()->absoluteFilePath();
875  }
876 
877  const QString modelFolder = !modelPath.isEmpty() ? QFileInfo( modelPath ).path() : QString();
878  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_path" ), QDir::toNativeSeparators( modelPath ), true ) );
879  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_folder" ), QDir::toNativeSeparators( modelFolder ), true, true ) );
880  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_name" ), model->displayName(), true ) );
881  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_group" ), model->group(), true ) );
882 
883  // custom variables
884  const QVariantMap customVariables = model->variables();
885  for ( auto it = customVariables.constBegin(); it != customVariables.constEnd(); ++it )
886  {
887  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( it.key(), it.value(), true ) );
888  }
889 
890  return modelScope.release();
891 }
892 
894 {
895  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope() );
896  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "notification_message" ), message, true ) );
897  return scope.release();
898 }
899 
901 {
902  QgsExpression::registerFunction( new GetNamedProjectColor( nullptr ) );
903  QgsExpression::registerFunction( new GetLayoutItemVariables( nullptr ) );
904  QgsExpression::registerFunction( new GetLayoutMapLayerCredits( nullptr ) );
905  QgsExpression::registerFunction( new GetLayerVisibility( QList<QgsMapLayer *>(), 0.0 ) );
906  QgsExpression::registerFunction( new GetProcessingParameterValue( QVariantMap() ) );
907  QgsExpression::registerFunction( new GetCurrentFormFieldValue( ) );
908  QgsExpression::registerFunction( new GetCurrentParentFormFieldValue( ) );
909 }
910 
912 {
913  Q_UNUSED( node )
914  return mUsesGeometry;
915 }
916 
918 {
919  Q_UNUSED( node )
920  return mReferencedColumns;
921 }
922 
924 {
925  return allParamsStatic( node, parent, context );
926 }
927 
928 //
929 // GetLayerVisibility
930 //
931 
932 QgsExpressionContextUtils::GetLayerVisibility::GetLayerVisibility( const QList<QgsMapLayer *> &layers, double scale )
933  : QgsScopedExpressionFunction( QStringLiteral( "is_layer_visible" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "General" ) )
934  , mLayers( _qgis_listRawToQPointer( layers ) )
935  , mScale( scale )
936 {
937  for ( const auto &layer : mLayers )
938  {
939  if ( layer->hasScaleBasedVisibility() )
940  {
941  mScaleBasedVisibilityDetails[ layer ] = qMakePair( layer->minimumScale(), layer->maximumScale() );
942  }
943  }
944 }
945 
946 QgsExpressionContextUtils::GetLayerVisibility::GetLayerVisibility()
947  : QgsScopedExpressionFunction( QStringLiteral( "is_layer_visible" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "General" ) )
948 {}
949 
950 QVariant QgsExpressionContextUtils::GetLayerVisibility::func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
951 {
952  if ( mLayers.isEmpty() )
953  {
954  return false;
955  }
956 
957  bool isVisible = false;
958  QgsMapLayer *layer = QgsExpressionUtils::getMapLayer( values.at( 0 ), parent );
959  if ( layer && mLayers.contains( layer ) )
960  {
961  isVisible = true;
962  if ( mScaleBasedVisibilityDetails.contains( layer ) && !qgsDoubleNear( mScale, 0.0 ) )
963  {
964  if ( ( !qgsDoubleNear( mScaleBasedVisibilityDetails[ layer ].first, 0.0 ) && mScale > mScaleBasedVisibilityDetails[ layer ].first ) ||
965  ( !qgsDoubleNear( mScaleBasedVisibilityDetails[ layer ].second, 0.0 ) && mScale < mScaleBasedVisibilityDetails[ layer ].second ) )
966  {
967  isVisible = false;
968  }
969  }
970  }
971 
972  return isVisible;
973 }
974 
975 QgsScopedExpressionFunction *QgsExpressionContextUtils::GetLayerVisibility::clone() const
976 {
977  GetLayerVisibility *func = new GetLayerVisibility();
978  func->mLayers = mLayers;
979  func->mScale = mScale;
980  func->mScaleBasedVisibilityDetails = mScaleBasedVisibilityDetails;
981  return func;
982 }
983 
984 //
985 // mesh expression context
986 //
987 
989 class CurrentVertexZValueExpressionFunction: public QgsScopedExpressionFunction
990 {
991  public:
992  CurrentVertexZValueExpressionFunction():
993  QgsScopedExpressionFunction( "$vertex_z",
994  0,
995  QStringLiteral( "Meshes" ) )
996  {}
997 
998  QgsScopedExpressionFunction *clone() const override {return new CurrentVertexZValueExpressionFunction();}
999 
1000  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1001  {
1002  if ( !context )
1003  return QVariant();
1004 
1005  if ( !context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1006  return QVariant();
1007 
1008  int vertexIndex = context->variable( QStringLiteral( "_mesh_vertex_index" ) ).toInt();
1009 
1010  QgsMeshLayer *layer = qobject_cast<QgsMeshLayer *>( qvariant_cast<QgsMapLayer *>( context->variable( QStringLiteral( "_mesh_layer" ) ) ) );
1011  if ( !layer || !layer->nativeMesh() || layer->nativeMesh()->vertexCount() <= vertexIndex )
1012  return QVariant();
1013 
1014  const QgsMeshVertex &vertex = layer->nativeMesh()->vertex( vertexIndex );
1015  if ( !vertex.isEmpty() )
1016  return vertex.z();
1017  else
1018  return QVariant();
1019  }
1020 
1021  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1022  {
1023  return false;
1024  }
1025 };
1026 
1027 class CurrentVertexXValueExpressionFunction: public QgsScopedExpressionFunction
1028 {
1029  public:
1030  CurrentVertexXValueExpressionFunction():
1031  QgsScopedExpressionFunction( "$vertex_x",
1032  0,
1033  QStringLiteral( "Meshes" ) )
1034  {}
1035 
1036  QgsScopedExpressionFunction *clone() const override {return new CurrentVertexXValueExpressionFunction();}
1037 
1038  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1039  {
1040  if ( !context )
1041  return QVariant();
1042 
1043  if ( !context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1044  return QVariant();
1045 
1046  int vertexIndex = context->variable( QStringLiteral( "_mesh_vertex_index" ) ).toInt();
1047 
1048  QgsMeshLayer *layer = qobject_cast<QgsMeshLayer *>( qvariant_cast<QgsMapLayer *>( context->variable( QStringLiteral( "_mesh_layer" ) ) ) );
1049  if ( !layer || !layer->nativeMesh() || layer->nativeMesh()->vertexCount() <= vertexIndex )
1050  return QVariant();
1051 
1052  const QgsMeshVertex &vertex = layer->nativeMesh()->vertex( vertexIndex );
1053  if ( !vertex.isEmpty() )
1054  return vertex.x();
1055  else
1056  return QVariant();
1057  }
1058 
1059  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1060  {
1061  return false;
1062  }
1063 };
1064 
1065 class CurrentVertexYValueExpressionFunction: public QgsScopedExpressionFunction
1066 {
1067  public:
1068  CurrentVertexYValueExpressionFunction():
1069  QgsScopedExpressionFunction( "$vertex_y",
1070  0,
1071  QStringLiteral( "Meshes" ) )
1072  {}
1073 
1074  QgsScopedExpressionFunction *clone() const override {return new CurrentVertexYValueExpressionFunction();}
1075 
1076  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1077  {
1078  if ( !context )
1079  return QVariant();
1080 
1081  if ( !context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1082  return QVariant();
1083 
1084  int vertexIndex = context->variable( QStringLiteral( "_mesh_vertex_index" ) ).toInt();
1085 
1086  QgsMeshLayer *layer = qobject_cast<QgsMeshLayer *>( qvariant_cast<QgsMapLayer *>( context->variable( QStringLiteral( "_mesh_layer" ) ) ) );
1087  if ( !layer || !layer->nativeMesh() || layer->nativeMesh()->vertexCount() <= vertexIndex )
1088  return QVariant();
1089 
1090  const QgsMeshVertex &vertex = layer->nativeMesh()->vertex( vertexIndex );
1091  if ( !vertex.isEmpty() )
1092  return vertex.y();
1093  else
1094  return QVariant();
1095  }
1096 
1097  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1098  {
1099  return false;
1100  }
1101 };
1102 
1103 class CurrentVertexExpressionFunction: public QgsScopedExpressionFunction
1104 {
1105  public:
1106  CurrentVertexExpressionFunction():
1107  QgsScopedExpressionFunction( "$vertex_as_point",
1108  0,
1109  QStringLiteral( "Meshes" ) )
1110  {}
1111 
1112  QgsScopedExpressionFunction *clone() const override {return new CurrentVertexExpressionFunction();}
1113 
1114  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1115  {
1116  if ( !context )
1117  return QVariant();
1118 
1119  if ( !context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1120  return QVariant();
1121 
1122  int vertexIndex = context->variable( QStringLiteral( "_mesh_vertex_index" ) ).toInt();
1123 
1124  QgsMeshLayer *layer = qobject_cast<QgsMeshLayer *>( qvariant_cast<QgsMapLayer *>( context->variable( QStringLiteral( "_mesh_layer" ) ) ) );
1125  if ( !layer || !layer->nativeMesh() || layer->nativeMesh()->vertexCount() <= vertexIndex )
1126  return QVariant();
1127 
1128  const QgsMeshVertex &vertex = layer->nativeMesh()->vertex( vertexIndex );
1129  if ( !vertex.isEmpty() )
1130  return QVariant::fromValue( QgsGeometry( new QgsPoint( vertex ) ) );
1131  else
1132  return QVariant();
1133  }
1134 
1135  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1136  {
1137  return false;
1138  }
1139 };
1140 
1141 class CurrentVertexIndexExpressionFunction: public QgsScopedExpressionFunction
1142 {
1143  public:
1144  CurrentVertexIndexExpressionFunction():
1145  QgsScopedExpressionFunction( "$vertex_index",
1146  0,
1147  QStringLiteral( "Meshes" ) )
1148  {}
1149 
1150  QgsScopedExpressionFunction *clone() const override {return new CurrentVertexIndexExpressionFunction();}
1151 
1152  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1153  {
1154  if ( !context )
1155  return QVariant();
1156 
1157  if ( !context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1158  return QVariant();
1159 
1160  return context->variable( QStringLiteral( "_mesh_vertex_index" ) );
1161  }
1162 
1163 
1164  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1165  {
1166  return false;
1167  }
1168 };
1169 
1170 class CurrentFaceAreaExpressionFunction: public QgsScopedExpressionFunction
1171 {
1172  public:
1173  CurrentFaceAreaExpressionFunction():
1174  QgsScopedExpressionFunction( "$face_area",
1175  0,
1176  QStringLiteral( "Meshes" ) )
1177  {}
1178 
1179  QgsScopedExpressionFunction *clone() const override {return new CurrentFaceAreaExpressionFunction();}
1180 
1181  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction * ) override
1182  {
1183  if ( !context )
1184  return QVariant();
1185 
1186  if ( !context->hasVariable( QStringLiteral( "_mesh_face_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1187  return QVariant();
1188 
1189  int faceIndex = context->variable( QStringLiteral( "_mesh_face_index" ) ).toInt();
1190 
1191  QgsMeshLayer *layer = qobject_cast<QgsMeshLayer *>( qvariant_cast<QgsMapLayer *>( context->variable( QStringLiteral( "_mesh_layer" ) ) ) );
1192  if ( !layer || !layer->nativeMesh() || layer->nativeMesh()->faceCount() <= faceIndex )
1193  return QVariant();
1194 
1195  const QgsMeshFace &face = layer->nativeMesh()->face( faceIndex );
1196  if ( !face.isEmpty() )
1197  {
1198  QgsDistanceArea *calc = parent->geomCalculator();
1199  QgsGeometry geom = QgsMeshUtils::toGeometry( layer->nativeMesh()->face( faceIndex ), layer->nativeMesh()->vertices );
1200  if ( calc )
1201  {
1202  double area = calc->measureArea( geom );
1203  area = calc->convertAreaMeasurement( area, parent->areaUnits() );
1204  return QVariant( area );
1205  }
1206  else
1207  {
1208  return QVariant( geom.area() );
1209  }
1210  }
1211  else
1212  return QVariant();
1213  }
1214 
1215  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1216  {
1217  return false;
1218  }
1219 };
1220 
1221 class CurrentFaceIndexExpressionFunction: public QgsScopedExpressionFunction
1222 {
1223  public:
1224  CurrentFaceIndexExpressionFunction():
1225  QgsScopedExpressionFunction( "$face_index",
1226  0,
1227  QStringLiteral( "Meshes" ) )
1228  {}
1229 
1230  QgsScopedExpressionFunction *clone() const override {return new CurrentFaceIndexExpressionFunction();}
1231 
1232  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1233  {
1234  if ( !context )
1235  return QVariant();
1236 
1237  if ( !context->hasVariable( QStringLiteral( "_mesh_face_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1238  return QVariant();
1239 
1240  return context->variable( QStringLiteral( "_mesh_face_index" ) ).toInt();
1241 
1242  }
1243 
1244  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1245  {
1246  return false;
1247  }
1248 };
1249 
1250 
1251 
1253 {
1254  std::unique_ptr<QgsExpressionContextScope> scope = std::make_unique<QgsExpressionContextScope>();
1255 
1256  switch ( elementType )
1257  {
1258  case QgsMesh::Vertex:
1259  {
1260  QgsExpression::registerFunction( new CurrentVertexExpressionFunction, true );
1261  QgsExpression::registerFunction( new CurrentVertexXValueExpressionFunction, true );
1262  QgsExpression::registerFunction( new CurrentVertexYValueExpressionFunction, true );
1263  QgsExpression::registerFunction( new CurrentVertexZValueExpressionFunction, true );
1264  QgsExpression::registerFunction( new CurrentVertexIndexExpressionFunction, true );
1265  scope->addFunction( "$vertex_as_point", new CurrentVertexExpressionFunction );
1266  scope->addFunction( "$vertex_x", new CurrentVertexXValueExpressionFunction );
1267  scope->addFunction( "$vertex_y", new CurrentVertexYValueExpressionFunction );
1268  scope->addFunction( "$vertex_z", new CurrentVertexZValueExpressionFunction );
1269  scope->addFunction( "$vertex_index", new CurrentVertexIndexExpressionFunction );
1270  }
1271  break;
1272  case QgsMesh::Face:
1273  {
1274  QgsExpression::registerFunction( new CurrentFaceAreaExpressionFunction, true );
1275  QgsExpression::registerFunction( new CurrentFaceIndexExpressionFunction, true );
1276  scope->addFunction( "$face_area", new CurrentFaceAreaExpressionFunction );
1277  scope->addFunction( "$face_index", new CurrentFaceIndexExpressionFunction );
1278  }
1279  break;
1280  case QgsMesh::Edge:
1281  break;
1282  }
1283 
1284  return scope.release();
1285 }
static QString version()
Version string.
Definition: qgis.cpp:277
static QString releaseName()
Release name.
Definition: qgis.cpp:289
static int versionInt()
Version number used for comparing versions using the "Check QGIS Version" function.
Definition: qgis.cpp:282
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", "server", "qgis_process" or "external" (for external...
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 projectionAcronym() const
Returns the projection acronym for the projection used by 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:209
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:125
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.
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers which will be rendered in 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.
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:470
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:701
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:671
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.
static double scaleToZoom(double mapScale, double z0Scale=559082264.0287178)
Finds zoom level given map scale denominator.
static int scaleToZoomLevel(double mapScale, int sourceMinZoom, int sourceMaxZoom, double z0Scale=559082264.0287178)
Finds the best fitting zoom level given a map scale denominator and allowed zoom level range.
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:1578
#define FID_IS_NULL(fid)
Definition: qgsfeatureid.h:30
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
Definition: qgsmaplayer.h:2133
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.