QGIS API Documentation  3.25.0-Master (dec16ba68b)
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  if ( mapSettings.frameRate() >= 0 )
507  scope->setVariable( QStringLiteral( "frame_rate" ), mapSettings.frameRate(), true );
508  if ( mapSettings.currentFrame() >= 0 )
509  scope->setVariable( QStringLiteral( "frame_number" ), mapSettings.currentFrame(), true );
510 
511  return scope;
512 }
513 
514 QgsExpressionContextScope *QgsExpressionContextUtils::mapToolCaptureScope( const QList<QgsPointLocator::Match> &matches )
515 {
516  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Map Tool Capture" ) );
517 
518  QVariantList matchList;
519 
520  for ( const QgsPointLocator::Match &match : matches )
521  {
522  QVariantMap matchMap;
523 
524  matchMap.insert( QStringLiteral( "valid" ), match.isValid() );
525  matchMap.insert( QStringLiteral( "layer" ), QVariant::fromValue<QgsWeakMapLayerPointer>( QgsWeakMapLayerPointer( match.layer() ) ) );
526  matchMap.insert( QStringLiteral( "feature_id" ), match.featureId() );
527  matchMap.insert( QStringLiteral( "vertex_index" ), match.vertexIndex() );
528  matchMap.insert( QStringLiteral( "distance" ), match.distance() );
529 
530  matchList.append( matchMap );
531  }
532 
533  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "snapping_results" ), matchList ) );
534 
535  return scope;
536 }
537 
539 {
540  if ( !symbolScope )
541  return nullptr;
542 
543  symbolScope->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_SYMBOL_COLOR, symbol ? symbol->color() : QColor(), true ) );
544 
545  double angle = 0.0;
546  const QgsMarkerSymbol *markerSymbol = dynamic_cast< const QgsMarkerSymbol * >( symbol );
547  if ( markerSymbol )
548  {
549  angle = markerSymbol->angle();
550  }
552 
553  return symbolScope;
554 }
555 
557 {
558  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope( QObject::tr( "Layout" ) ) );
559  if ( !layout )
560  return scope.release();
561 
562  //add variables defined in layout properties
563  const QStringList variableNames = layout->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
564  const QStringList variableValues = layout->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
565 
566  int varIndex = 0;
567 
568  for ( const QString &variableName : variableNames )
569  {
570  if ( varIndex >= variableValues.length() )
571  {
572  break;
573  }
574 
575  const QVariant varValue = variableValues.at( varIndex );
576  varIndex++;
577  scope->setVariable( variableName, varValue );
578  }
579 
580  //add known layout context variables
581  if ( const QgsMasterLayoutInterface *l = dynamic_cast< const QgsMasterLayoutInterface * >( layout ) )
582  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_name" ), l->name(), true ) );
583 
584  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_numpages" ), layout->pageCollection()->pageCount(), true ) );
585  if ( layout->pageCollection()->pageCount() > 0 )
586  {
587  // just take first page size
588  const QSizeF s = layout->pageCollection()->page( 0 )->sizeWithUnits().toQSizeF();
589  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), s.height(), true ) );
590  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), s.width(), true ) );
591  }
592 
593  QVariantList offsets;
594  for ( int i = 0; i < layout->pageCollection()->pageCount(); i++ )
595  {
596  const QPointF p = layout->pageCollection()->pagePositionToLayoutPosition( i, QgsLayoutPoint( 0, 0 ) );
597  offsets << p.y();
598  }
599  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageoffsets" ), offsets, true ) );
600 
601  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_dpi" ), layout->renderContext().dpi(), true ) );
602 
603  scope->addFunction( QStringLiteral( "item_variables" ), new GetLayoutItemVariables( layout ) );
604  scope->addFunction( QStringLiteral( "map_credits" ), new GetLayoutMapLayerCredits( layout ) );
605 
606  if ( layout->reportContext().layer() )
607  {
608  scope->setFields( layout->reportContext().layer()->fields() );
609  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layerid" ), layout->reportContext().layer()->id(), true ) );
610  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layername" ), layout->reportContext().layer()->name(), true ) );
611  }
612 
613  if ( layout->reportContext().feature().isValid() )
614  {
615  const QgsFeature atlasFeature = layout->reportContext().feature();
616  scope->setFeature( atlasFeature );
617  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( atlasFeature ), true ) );
618  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), FID_IS_NULL( atlasFeature.id() ) ? QVariant() : atlasFeature.id(), true ) );
619  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( atlasFeature.geometry() ), true ) );
620  }
621 
622  return scope.release();
623 }
624 
625 void QgsExpressionContextUtils::setLayoutVariable( QgsLayout *layout, const QString &name, const QVariant &value )
626 {
627  if ( !layout )
628  return;
629 
630  //write variable to layout
631  QStringList variableNames = layout->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
632  QStringList variableValues = layout->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
633 
634  variableNames << name;
635  variableValues << value.toString();
636 
637  layout->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
638  layout->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
639 }
640 
641 void QgsExpressionContextUtils::setLayoutVariables( QgsLayout *layout, const QVariantMap &variables )
642 {
643  if ( !layout )
644  return;
645 
646  QStringList variableNames;
647  QStringList variableValues;
648 
649  QVariantMap::const_iterator it = variables.constBegin();
650  for ( ; it != variables.constEnd(); ++it )
651  {
652  variableNames << it.key();
653  variableValues << it.value().toString();
654  }
655 
656  layout->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
657  layout->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
658 }
659 
661 {
662  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Atlas" ) );
663  if ( !atlas )
664  {
665  //add some dummy atlas variables. This is done so that as in certain contexts we want to show
666  //users that these variables are available even if they have no current value
667  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_pagename" ), QString(), true, true ) );
668  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( QgsFeature() ), true, true ) );
669  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), QVariant(), true, true ) );
670  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( QgsGeometry() ), true, true ) );
671  return scope;
672  }
673 
674  //add known atlas variables
675  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_totalfeatures" ), atlas->count(), true, true ) );
676  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featurenumber" ), atlas->currentFeatureNumber() + 1, true, true ) );
677  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_filename" ), atlas->currentFilename(), true, true ) );
678  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_pagename" ), atlas->nameForPage( atlas->currentFeatureNumber() ), true, true ) );
679 
680  if ( atlas->enabled() && atlas->coverageLayer() )
681  {
682  scope->setFields( atlas->coverageLayer()->fields() );
683  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layerid" ), atlas->coverageLayer()->id(), true ) );
684  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layername" ), atlas->coverageLayer()->name(), true ) );
685  }
686 
687  if ( atlas->enabled() )
688  {
689  const QgsFeature atlasFeature = atlas->layout()->reportContext().feature();
690  scope->setFeature( atlasFeature );
691  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( atlasFeature ), true ) );
692  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), FID_IS_NULL( atlasFeature.id() ) ? QVariant() : atlasFeature.id(), true ) );
693  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( atlasFeature.geometry() ), true ) );
694  }
695 
696  return scope;
697 }
698 
700 {
701  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Layout Item" ) );
702  if ( !item )
703  return scope;
704 
705  //add variables defined in layout item properties
706  const QStringList variableNames = item->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
707  const QStringList variableValues = item->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
708 
709  int varIndex = 0;
710  for ( const QString &variableName : variableNames )
711  {
712  if ( varIndex >= variableValues.length() )
713  {
714  break;
715  }
716 
717  const QVariant varValue = variableValues.at( varIndex );
718  varIndex++;
719  scope->setVariable( variableName, varValue );
720  }
721 
722  //add known layout item context variables
723  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "item_id" ), item->id(), true ) );
724  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "item_uuid" ), item->uuid(), true ) );
725  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_page" ), item->page() + 1, true ) );
726 
727  if ( item->layout() )
728  {
729  const QgsLayoutItemPage *page = item->layout()->pageCollection()->page( item->page() );
730  if ( page )
731  {
732  const QSizeF s = page->sizeWithUnits().toQSizeF();
733  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), s.height(), true ) );
734  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), s.width(), true ) );
735  }
736  else
737  {
738  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), QVariant(), true ) );
739  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), QVariant(), true ) );
740  }
741  }
742 
743  return scope;
744 }
745 
746 void QgsExpressionContextUtils::setLayoutItemVariable( QgsLayoutItem *item, const QString &name, const QVariant &value )
747 {
748  if ( !item )
749  return;
750 
751  //write variable to layout item
752  QStringList variableNames = item->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
753  QStringList variableValues = item->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
754 
755  variableNames << name;
756  variableValues << value.toString();
757 
758  item->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
759  item->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
760 }
761 
762 void QgsExpressionContextUtils::setLayoutItemVariables( QgsLayoutItem *item, const QVariantMap &variables )
763 {
764  if ( !item )
765  return;
766 
767  QStringList variableNames;
768  QStringList variableValues;
769 
770  QVariantMap::const_iterator it = variables.constBegin();
771  for ( ; it != variables.constEnd(); ++it )
772  {
773  variableNames << it.key();
774  variableValues << it.value().toString();
775  }
776 
777  item->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
778  item->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
779 }
780 
782 {
783  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Multiframe Item" ) );
784  if ( !frame )
785  return scope;
786 
787  //add variables defined in layout item properties
788  const QStringList variableNames = frame->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
789  const QStringList variableValues = frame->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
790 
791  int varIndex = 0;
792  for ( const QString &variableName : variableNames )
793  {
794  if ( varIndex >= variableValues.length() )
795  {
796  break;
797  }
798 
799  const QVariant varValue = variableValues.at( varIndex );
800  varIndex++;
801  scope->setVariable( variableName, varValue );
802  }
803 
804  return scope;
805 }
806 
807 void QgsExpressionContextUtils::setLayoutMultiFrameVariable( QgsLayoutMultiFrame *frame, const QString &name, const QVariant &value )
808 {
809  if ( !frame )
810  return;
811 
812  //write variable to layout multiframe
813  QStringList variableNames = frame->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
814  QStringList variableValues = frame->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
815 
816  variableNames << name;
817  variableValues << value.toString();
818 
819  frame->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
820  frame->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
821 }
822 
824 {
825  if ( !frame )
826  return;
827 
828  QStringList variableNames;
829  QStringList variableValues;
830 
831  QVariantMap::const_iterator it = variables.constBegin();
832  for ( ; it != variables.constEnd(); ++it )
833  {
834  variableNames << it.key();
835  variableValues << it.value().toString();
836  }
837 
838  frame->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
839  frame->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
840 }
841 
843 {
845  scope->setFeature( feature );
846  scope->setFields( fields );
847  return QgsExpressionContext() << scope;
848 }
849 
851 {
852  // set aside for future use
853  Q_UNUSED( context )
854 
855  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope( QObject::tr( "Algorithm" ) ) );
856  scope->addFunction( QStringLiteral( "parameter" ), new GetProcessingParameterValue( parameters ) );
857 
858  if ( !algorithm )
859  return scope.release();
860 
861  //add standard algorithm variables
862  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "algorithm_id" ), algorithm->id(), true ) );
863 
864  return scope.release();
865 }
866 
867 QgsExpressionContextScope *QgsExpressionContextUtils::processingModelAlgorithmScope( const QgsProcessingModelAlgorithm *model, const QVariantMap &, QgsProcessingContext &context )
868 {
869  std::unique_ptr< QgsExpressionContextScope > modelScope( new QgsExpressionContextScope( QObject::tr( "Model" ) ) );
870  QString modelPath;
871  if ( !model->sourceFilePath().isEmpty() )
872  {
873  modelPath = model->sourceFilePath();
874  }
875  else if ( context.project() )
876  {
877  // fallback to project path -- the model may be embedded in a project, OR an unsaved model. In either case the
878  // project path is a logical value to fall back to
879  modelPath = context.project()->projectStorage() ? context.project()->fileName() : context.project()->absoluteFilePath();
880  }
881 
882  const QString modelFolder = !modelPath.isEmpty() ? QFileInfo( modelPath ).path() : QString();
883  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_path" ), QDir::toNativeSeparators( modelPath ), true ) );
884  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_folder" ), QDir::toNativeSeparators( modelFolder ), true, true ) );
885  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_name" ), model->displayName(), true ) );
886  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_group" ), model->group(), true ) );
887 
888  // custom variables
889  const QVariantMap customVariables = model->variables();
890  for ( auto it = customVariables.constBegin(); it != customVariables.constEnd(); ++it )
891  {
892  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( it.key(), it.value(), true ) );
893  }
894 
895  return modelScope.release();
896 }
897 
899 {
900  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope() );
901  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "notification_message" ), message, true ) );
902  return scope.release();
903 }
904 
906 {
907  QgsExpression::registerFunction( new GetNamedProjectColor( nullptr ) );
908  QgsExpression::registerFunction( new GetLayoutItemVariables( nullptr ) );
909  QgsExpression::registerFunction( new GetLayoutMapLayerCredits( nullptr ) );
910  QgsExpression::registerFunction( new GetLayerVisibility( QList<QgsMapLayer *>(), 0.0 ) );
911  QgsExpression::registerFunction( new GetProcessingParameterValue( QVariantMap() ) );
912  QgsExpression::registerFunction( new GetCurrentFormFieldValue( ) );
913  QgsExpression::registerFunction( new GetCurrentParentFormFieldValue( ) );
914 }
915 
917 {
918  Q_UNUSED( node )
919  return mUsesGeometry;
920 }
921 
923 {
924  Q_UNUSED( node )
925  return mReferencedColumns;
926 }
927 
929 {
930  return allParamsStatic( node, parent, context );
931 }
932 
933 //
934 // GetLayerVisibility
935 //
936 
937 QgsExpressionContextUtils::GetLayerVisibility::GetLayerVisibility( const QList<QgsMapLayer *> &layers, double scale )
938  : QgsScopedExpressionFunction( QStringLiteral( "is_layer_visible" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "General" ) )
939  , mLayers( _qgis_listRawToQPointer( layers ) )
940  , mScale( scale )
941 {
942  for ( const auto &layer : mLayers )
943  {
944  if ( layer->hasScaleBasedVisibility() )
945  {
946  mScaleBasedVisibilityDetails[ layer ] = qMakePair( layer->minimumScale(), layer->maximumScale() );
947  }
948  }
949 }
950 
951 QgsExpressionContextUtils::GetLayerVisibility::GetLayerVisibility()
952  : QgsScopedExpressionFunction( QStringLiteral( "is_layer_visible" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "General" ) )
953 {}
954 
955 QVariant QgsExpressionContextUtils::GetLayerVisibility::func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
956 {
957  if ( mLayers.isEmpty() )
958  {
959  return false;
960  }
961 
962  bool isVisible = false;
963  QgsMapLayer *layer = QgsExpressionUtils::getMapLayer( values.at( 0 ), parent );
964  if ( layer && mLayers.contains( layer ) )
965  {
966  isVisible = true;
967  if ( mScaleBasedVisibilityDetails.contains( layer ) && !qgsDoubleNear( mScale, 0.0 ) )
968  {
969  if ( ( !qgsDoubleNear( mScaleBasedVisibilityDetails[ layer ].first, 0.0 ) && mScale > mScaleBasedVisibilityDetails[ layer ].first ) ||
970  ( !qgsDoubleNear( mScaleBasedVisibilityDetails[ layer ].second, 0.0 ) && mScale < mScaleBasedVisibilityDetails[ layer ].second ) )
971  {
972  isVisible = false;
973  }
974  }
975  }
976 
977  return isVisible;
978 }
979 
980 QgsScopedExpressionFunction *QgsExpressionContextUtils::GetLayerVisibility::clone() const
981 {
982  GetLayerVisibility *func = new GetLayerVisibility();
983  func->mLayers = mLayers;
984  func->mScale = mScale;
985  func->mScaleBasedVisibilityDetails = mScaleBasedVisibilityDetails;
986  return func;
987 }
988 
989 //
990 // mesh expression context
991 //
992 
994 class CurrentVertexZValueExpressionFunction: public QgsScopedExpressionFunction
995 {
996  public:
997  CurrentVertexZValueExpressionFunction():
998  QgsScopedExpressionFunction( "$vertex_z",
999  0,
1000  QStringLiteral( "Meshes" ) )
1001  {}
1002 
1003  QgsScopedExpressionFunction *clone() const override {return new CurrentVertexZValueExpressionFunction();}
1004 
1005  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1006  {
1007  if ( !context )
1008  return QVariant();
1009 
1010  if ( !context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1011  return QVariant();
1012 
1013  int vertexIndex = context->variable( QStringLiteral( "_mesh_vertex_index" ) ).toInt();
1014 
1015  QgsMeshLayer *layer = qobject_cast<QgsMeshLayer *>( qvariant_cast<QgsMapLayer *>( context->variable( QStringLiteral( "_mesh_layer" ) ) ) );
1016  if ( !layer || !layer->nativeMesh() || layer->nativeMesh()->vertexCount() <= vertexIndex )
1017  return QVariant();
1018 
1019  const QgsMeshVertex &vertex = layer->nativeMesh()->vertex( vertexIndex );
1020  if ( !vertex.isEmpty() )
1021  return vertex.z();
1022  else
1023  return QVariant();
1024  }
1025 
1026  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1027  {
1028  return false;
1029  }
1030 };
1031 
1032 class CurrentVertexXValueExpressionFunction: public QgsScopedExpressionFunction
1033 {
1034  public:
1035  CurrentVertexXValueExpressionFunction():
1036  QgsScopedExpressionFunction( "$vertex_x",
1037  0,
1038  QStringLiteral( "Meshes" ) )
1039  {}
1040 
1041  QgsScopedExpressionFunction *clone() const override {return new CurrentVertexXValueExpressionFunction();}
1042 
1043  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1044  {
1045  if ( !context )
1046  return QVariant();
1047 
1048  if ( !context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1049  return QVariant();
1050 
1051  int vertexIndex = context->variable( QStringLiteral( "_mesh_vertex_index" ) ).toInt();
1052 
1053  QgsMeshLayer *layer = qobject_cast<QgsMeshLayer *>( qvariant_cast<QgsMapLayer *>( context->variable( QStringLiteral( "_mesh_layer" ) ) ) );
1054  if ( !layer || !layer->nativeMesh() || layer->nativeMesh()->vertexCount() <= vertexIndex )
1055  return QVariant();
1056 
1057  const QgsMeshVertex &vertex = layer->nativeMesh()->vertex( vertexIndex );
1058  if ( !vertex.isEmpty() )
1059  return vertex.x();
1060  else
1061  return QVariant();
1062  }
1063 
1064  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1065  {
1066  return false;
1067  }
1068 };
1069 
1070 class CurrentVertexYValueExpressionFunction: public QgsScopedExpressionFunction
1071 {
1072  public:
1073  CurrentVertexYValueExpressionFunction():
1074  QgsScopedExpressionFunction( "$vertex_y",
1075  0,
1076  QStringLiteral( "Meshes" ) )
1077  {}
1078 
1079  QgsScopedExpressionFunction *clone() const override {return new CurrentVertexYValueExpressionFunction();}
1080 
1081  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1082  {
1083  if ( !context )
1084  return QVariant();
1085 
1086  if ( !context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1087  return QVariant();
1088 
1089  int vertexIndex = context->variable( QStringLiteral( "_mesh_vertex_index" ) ).toInt();
1090 
1091  QgsMeshLayer *layer = qobject_cast<QgsMeshLayer *>( qvariant_cast<QgsMapLayer *>( context->variable( QStringLiteral( "_mesh_layer" ) ) ) );
1092  if ( !layer || !layer->nativeMesh() || layer->nativeMesh()->vertexCount() <= vertexIndex )
1093  return QVariant();
1094 
1095  const QgsMeshVertex &vertex = layer->nativeMesh()->vertex( vertexIndex );
1096  if ( !vertex.isEmpty() )
1097  return vertex.y();
1098  else
1099  return QVariant();
1100  }
1101 
1102  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1103  {
1104  return false;
1105  }
1106 };
1107 
1108 class CurrentVertexExpressionFunction: public QgsScopedExpressionFunction
1109 {
1110  public:
1111  CurrentVertexExpressionFunction():
1112  QgsScopedExpressionFunction( "$vertex_as_point",
1113  0,
1114  QStringLiteral( "Meshes" ) )
1115  {}
1116 
1117  QgsScopedExpressionFunction *clone() const override {return new CurrentVertexExpressionFunction();}
1118 
1119  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1120  {
1121  if ( !context )
1122  return QVariant();
1123 
1124  if ( !context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1125  return QVariant();
1126 
1127  int vertexIndex = context->variable( QStringLiteral( "_mesh_vertex_index" ) ).toInt();
1128 
1129  QgsMeshLayer *layer = qobject_cast<QgsMeshLayer *>( qvariant_cast<QgsMapLayer *>( context->variable( QStringLiteral( "_mesh_layer" ) ) ) );
1130  if ( !layer || !layer->nativeMesh() || layer->nativeMesh()->vertexCount() <= vertexIndex )
1131  return QVariant();
1132 
1133  const QgsMeshVertex &vertex = layer->nativeMesh()->vertex( vertexIndex );
1134  if ( !vertex.isEmpty() )
1135  return QVariant::fromValue( QgsGeometry( new QgsPoint( vertex ) ) );
1136  else
1137  return QVariant();
1138  }
1139 
1140  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1141  {
1142  return false;
1143  }
1144 };
1145 
1146 class CurrentVertexIndexExpressionFunction: public QgsScopedExpressionFunction
1147 {
1148  public:
1149  CurrentVertexIndexExpressionFunction():
1150  QgsScopedExpressionFunction( "$vertex_index",
1151  0,
1152  QStringLiteral( "Meshes" ) )
1153  {}
1154 
1155  QgsScopedExpressionFunction *clone() const override {return new CurrentVertexIndexExpressionFunction();}
1156 
1157  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1158  {
1159  if ( !context )
1160  return QVariant();
1161 
1162  if ( !context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1163  return QVariant();
1164 
1165  return context->variable( QStringLiteral( "_mesh_vertex_index" ) );
1166  }
1167 
1168 
1169  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1170  {
1171  return false;
1172  }
1173 };
1174 
1175 class CurrentFaceAreaExpressionFunction: public QgsScopedExpressionFunction
1176 {
1177  public:
1178  CurrentFaceAreaExpressionFunction():
1179  QgsScopedExpressionFunction( "$face_area",
1180  0,
1181  QStringLiteral( "Meshes" ) )
1182  {}
1183 
1184  QgsScopedExpressionFunction *clone() const override {return new CurrentFaceAreaExpressionFunction();}
1185 
1186  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction * ) override
1187  {
1188  if ( !context )
1189  return QVariant();
1190 
1191  if ( !context->hasVariable( QStringLiteral( "_mesh_face_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1192  return QVariant();
1193 
1194  int faceIndex = context->variable( QStringLiteral( "_mesh_face_index" ) ).toInt();
1195 
1196  QgsMeshLayer *layer = qobject_cast<QgsMeshLayer *>( qvariant_cast<QgsMapLayer *>( context->variable( QStringLiteral( "_mesh_layer" ) ) ) );
1197  if ( !layer || !layer->nativeMesh() || layer->nativeMesh()->faceCount() <= faceIndex )
1198  return QVariant();
1199 
1200  const QgsMeshFace &face = layer->nativeMesh()->face( faceIndex );
1201  if ( !face.isEmpty() )
1202  {
1203  QgsDistanceArea *calc = parent->geomCalculator();
1204  QgsGeometry geom = QgsMeshUtils::toGeometry( layer->nativeMesh()->face( faceIndex ), layer->nativeMesh()->vertices );
1205  if ( calc )
1206  {
1207  double area = calc->measureArea( geom );
1208  area = calc->convertAreaMeasurement( area, parent->areaUnits() );
1209  return QVariant( area );
1210  }
1211  else
1212  {
1213  return QVariant( geom.area() );
1214  }
1215  }
1216  else
1217  return QVariant();
1218  }
1219 
1220  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1221  {
1222  return false;
1223  }
1224 };
1225 
1226 class CurrentFaceIndexExpressionFunction: public QgsScopedExpressionFunction
1227 {
1228  public:
1229  CurrentFaceIndexExpressionFunction():
1230  QgsScopedExpressionFunction( "$face_index",
1231  0,
1232  QStringLiteral( "Meshes" ) )
1233  {}
1234 
1235  QgsScopedExpressionFunction *clone() const override {return new CurrentFaceIndexExpressionFunction();}
1236 
1237  QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1238  {
1239  if ( !context )
1240  return QVariant();
1241 
1242  if ( !context->hasVariable( QStringLiteral( "_mesh_face_index" ) ) || !context->hasVariable( QStringLiteral( "_mesh_layer" ) ) )
1243  return QVariant();
1244 
1245  return context->variable( QStringLiteral( "_mesh_face_index" ) ).toInt();
1246 
1247  }
1248 
1249  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1250  {
1251  return false;
1252  }
1253 };
1254 
1255 
1256 
1258 {
1259  std::unique_ptr<QgsExpressionContextScope> scope = std::make_unique<QgsExpressionContextScope>();
1260 
1261  switch ( elementType )
1262  {
1263  case QgsMesh::Vertex:
1264  {
1265  QgsExpression::registerFunction( new CurrentVertexExpressionFunction, true );
1266  QgsExpression::registerFunction( new CurrentVertexXValueExpressionFunction, true );
1267  QgsExpression::registerFunction( new CurrentVertexYValueExpressionFunction, true );
1268  QgsExpression::registerFunction( new CurrentVertexZValueExpressionFunction, true );
1269  QgsExpression::registerFunction( new CurrentVertexIndexExpressionFunction, true );
1270  scope->addFunction( "$vertex_as_point", new CurrentVertexExpressionFunction );
1271  scope->addFunction( "$vertex_x", new CurrentVertexXValueExpressionFunction );
1272  scope->addFunction( "$vertex_y", new CurrentVertexYValueExpressionFunction );
1273  scope->addFunction( "$vertex_z", new CurrentVertexZValueExpressionFunction );
1274  scope->addFunction( "$vertex_index", new CurrentVertexIndexExpressionFunction );
1275  }
1276  break;
1277  case QgsMesh::Face:
1278  {
1279  QgsExpression::registerFunction( new CurrentFaceAreaExpressionFunction, true );
1280  QgsExpression::registerFunction( new CurrentFaceIndexExpressionFunction, true );
1281  scope->addFunction( "$face_area", new CurrentFaceAreaExpressionFunction );
1282  scope->addFunction( "$face_index", new CurrentFaceIndexExpressionFunction );
1283  }
1284  break;
1285  case QgsMesh::Edge:
1286  break;
1287  }
1288 
1289  return scope.release();
1290 }
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.
long long currentFrame() const
Returns the current frame number of the map, for maps which are part of an animation.
QgsUnitTypes::DistanceUnit mapUnits() const
Returns the units of the map's geographical coordinates - used for scale calculation.
double frameRate() const
Returns the frame rate of the map (in frames per second), for maps which are part of an animation.
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:99
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:104
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:474
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:107
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:815
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:785
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:93
QColor color() const
Returns the symbol's color.
Definition: qgssymbol.cpp:575
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:1990
#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.