QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgsexpressioncontextutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsexpressioncontextutils.cpp
3  ------------------------
4  Date : April 2015
5  Copyright : (C) 2015 by Nyall Dawson
6  Email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 #include "qgsapplication.h"
18 #include "qgsvectorlayer.h"
19 #include "qgsproject.h"
20 #include "qgsexpression.h"
21 #include "qgsprocessingcontext.h"
22 #include "qgsprocessingmodelalgorithm.h"
23 #include "qgsprocessingalgorithm.h"
24 #include "qgsmapsettings.h"
25 #include "qgssymbollayerutils.h"
26 #include "qgslayout.h"
27 #include "qgslayoutitem.h"
28 #include "qgsexpressionutils.h"
30 #include "qgslayoutatlas.h"
31 #include "qgslayoutmultiframe.h"
32 #include "qgsfeatureid.h"
33 #include "qgslayoutitemmap.h"
34 #include "qgsmaplayerlistutils.h"
35 #include "qgsprojoperation.h"
36 #include "qgsmarkersymbol.h"
37 
39 {
40  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Global" ) );
41 
42  QVariantMap customVariables = QgsApplication::customVariables();
43 
44  for ( QVariantMap::const_iterator it = customVariables.constBegin(); it != customVariables.constEnd(); ++it )
45  {
46  scope->setVariable( it.key(), it.value(), true );
47  }
48 
49  //add some extra global variables
50  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_version" ), Qgis::version(), true, true ) );
51  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_version_no" ), Qgis::versionInt(), true, true ) );
52  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_short_version" ), QStringLiteral( "%1.%2" ).arg( Qgis::versionInt() / 10000 ).arg( Qgis::versionInt() / 100 % 100 ), true, true ) );
53  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_release_name" ), Qgis::releaseName(), true, true ) );
54  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_platform" ), QgsApplication::platform(), true, true ) );
55  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_os_name" ), QgsApplication::osName(), true, true ) );
56  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "qgis_locale" ), QgsApplication::locale(), true, true ) );
57  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "user_account_name" ), QgsApplication::userLoginName(), true, true ) );
58  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "user_full_name" ), QgsApplication::userFullName(), true, true ) );
59 
60  return scope;
61 }
62 
63 void QgsExpressionContextUtils::setGlobalVariable( const QString &name, const QVariant &value )
64 {
65  QgsApplication::setCustomVariable( name, value );
66 }
67 
68 void QgsExpressionContextUtils::setGlobalVariables( const QVariantMap &variables )
69 {
71 }
72 
74 {
75  QVariantMap vars = QgsApplication::customVariables();
76  if ( vars.remove( name ) )
78 }
79 
81 
82 class GetLayoutItemVariables : public QgsScopedExpressionFunction
83 {
84  public:
85  GetLayoutItemVariables( const QgsLayout *c )
86  : QgsScopedExpressionFunction( QStringLiteral( "item_variables" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "Layout" ) )
87  , mLayout( c )
88  {}
89 
90  QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
91  {
92  if ( !mLayout )
93  return QVariant();
94 
95  QString id = values.at( 0 ).toString();
96 
97  const QgsLayoutItem *item = mLayout->itemById( id );
98  if ( !item )
99  return QVariant();
100 
102 
103  return c.variablesToMap();
104  }
105 
106  QgsScopedExpressionFunction *clone() const override
107  {
108  return new GetLayoutItemVariables( mLayout );
109  }
110 
111  private:
112 
113  const QgsLayout *mLayout = nullptr;
114 
115 };
116 
117 
118 class GetLayoutMapLayerCredits : public QgsScopedExpressionFunction
119 {
120  public:
121  GetLayoutMapLayerCredits( const QgsLayout *c )
122  : QgsScopedExpressionFunction( QStringLiteral( "map_credits" ),
123  QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) )
124  << QgsExpressionFunction::Parameter( QStringLiteral( "include_layer_names" ), true, false )
125  << QgsExpressionFunction::Parameter( QStringLiteral( "layer_name_separator" ), true, QStringLiteral( ": " ) ), QStringLiteral( "Layout" ) )
126  , mLayout( c )
127  {}
128 
129  QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
130  {
131  if ( !mLayout )
132  return QVariant();
133 
134  QString id = values.value( 0 ).toString();
135 
136  if ( QgsLayoutItemMap *map = qobject_cast< QgsLayoutItemMap * >( mLayout->itemById( id ) ) )
137  {
138  QgsExpressionContext c = map->createExpressionContext();
139  const QVariantList mapLayers = c.variable( QStringLiteral( "map_layers" ) ).toList();
140 
141  const bool includeLayerNames = values.value( 1 ).toBool();
142  const QString layerNameSeparator = values.value( 2 ).toString();
143 
144  QVariantList res;
145  for ( const QVariant &value : mapLayers )
146  {
147  if ( const QgsMapLayer *layer = qobject_cast< const QgsMapLayer * >( value.value< QObject * >() ) )
148  {
149  const QStringList credits = !layer->metadata().rights().isEmpty() ? layer->metadata().rights() : QStringList() << layer->attribution();
150  for ( const QString &credit : credits )
151  {
152  if ( credit.trimmed().isEmpty() )
153  continue;
154 
155  const QString creditString = includeLayerNames ? layer->name() + layerNameSeparator + credit
156  : credit;
157 
158  if ( !res.contains( creditString ) )
159  res << creditString;
160  }
161  }
162  }
163 
164  return res;
165  }
166  return QVariant();
167  }
168 
169  QgsScopedExpressionFunction *clone() const override
170  {
171  return new GetLayoutMapLayerCredits( mLayout );
172  }
173 
174  private:
175 
176  const QgsLayout *mLayout = nullptr;
177 
178 };
179 
180 class GetCurrentFormFieldValue : public QgsScopedExpressionFunction
181 {
182  public:
183  GetCurrentFormFieldValue( )
184  : QgsScopedExpressionFunction( QStringLiteral( "current_value" ), QgsExpressionFunction::ParameterList() << QStringLiteral( "field_name" ), QStringLiteral( "Form" ) )
185  {}
186 
187  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
188  {
189  QString fieldName( values.at( 0 ).toString() );
190  const QgsFeature feat( context->variable( QStringLiteral( "current_feature" ) ).value<QgsFeature>() );
191  if ( fieldName.isEmpty() || ! feat.isValid( ) )
192  {
193  return QVariant();
194  }
195  return feat.attribute( fieldName ) ;
196  }
197 
198  QgsScopedExpressionFunction *clone() const override
199  {
200  return new GetCurrentFormFieldValue( );
201  }
202 
203  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
204  {
205  return false;
206  };
207 
208 };
209 
210 class GetCurrentParentFormFieldValue : public QgsScopedExpressionFunction
211 {
212  public:
213  GetCurrentParentFormFieldValue( )
214  : QgsScopedExpressionFunction( QStringLiteral( "current_parent_value" ), QgsExpressionFunction::ParameterList() << QStringLiteral( "field_name" ), QStringLiteral( "Form" ) )
215  {}
216 
217  QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
218  {
219  QString fieldName( values.at( 0 ).toString() );
220  const QgsFeature feat( context->variable( QStringLiteral( "current_parent_feature" ) ).value<QgsFeature>() );
221  if ( fieldName.isEmpty() || ! feat.isValid( ) )
222  {
223  return QVariant();
224  }
225  return feat.attribute( fieldName ) ;
226  }
227 
228  QgsScopedExpressionFunction *clone() const override
229  {
230  return new GetCurrentParentFormFieldValue( );
231  }
232 
233  bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
234  {
235  return false;
236  };
237 
238 };
239 
240 
241 class GetProcessingParameterValue : public QgsScopedExpressionFunction
242 {
243  public:
244  GetProcessingParameterValue( const QVariantMap &params )
245  : QgsScopedExpressionFunction( QStringLiteral( "parameter" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "name" ) ), QStringLiteral( "Processing" ) )
246  , mParams( params )
247  {}
248 
249  QVariant func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *, const QgsExpressionNodeFunction * ) override
250  {
251  return mParams.value( values.at( 0 ).toString() );
252  }
253 
254  QgsScopedExpressionFunction *clone() const override
255  {
256  return new GetProcessingParameterValue( mParams );
257  }
258 
259  private:
260 
261  const QVariantMap mParams;
262 
263 };
264 
266 
267 
268 QgsExpressionContextScope *QgsExpressionContextUtils::formScope( const QgsFeature &formFeature, const QString &formMode )
269 {
270  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Form" ) );
271  scope->addFunction( QStringLiteral( "current_value" ), new GetCurrentFormFieldValue( ) );
272  scope->setVariable( QStringLiteral( "current_geometry" ), formFeature.geometry( ), true );
273  scope->setVariable( QStringLiteral( "current_feature" ), formFeature, true );
274  scope->setVariable( QStringLiteral( "form_mode" ), formMode, true );
275  return scope;
276 }
277 
278 
279 QgsExpressionContextScope *QgsExpressionContextUtils::parentFormScope( const QgsFeature &parentFormFeature, const QString &parentFormMode )
280 {
281  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Parent Form" ) );
282  scope->addFunction( QStringLiteral( "current_parent_value" ), new GetCurrentParentFormFieldValue( ) );
283  scope->setVariable( QStringLiteral( "current_parent_geometry" ), parentFormFeature.geometry( ), true );
284  scope->setVariable( QStringLiteral( "current_parent_feature" ), parentFormFeature, true );
285  scope->setVariable( QStringLiteral( "parent_form_mode" ), parentFormMode, true );
286  return scope;
287 }
288 
290 {
291  if ( !project )
292  {
293  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Project" ) );
294  return scope;
295  }
296  else
297  return project->createExpressionContextScope();
298 }
299 
300 void QgsExpressionContextUtils::setProjectVariable( QgsProject *project, const QString &name, const QVariant &value )
301 {
302  if ( !project )
303  return;
304 
305  QVariantMap vars = project->customVariables();
306 
307  vars.insert( name, value );
308 
309  project->setCustomVariables( vars );
310 }
311 
312 void QgsExpressionContextUtils::setProjectVariables( QgsProject *project, const QVariantMap &variables )
313 {
314  if ( !project )
315  return;
316 
317  project->setCustomVariables( variables );
318 }
319 
321 {
322  if ( !project )
323  {
324  return;
325  }
326 
327  QVariantMap vars = project->customVariables();
328  if ( vars.remove( name ) )
329  project->setCustomVariables( vars );
330 }
331 
333 {
334  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Layer" ) );
335 
336  if ( !layer )
337  return scope;
338 
339  //add variables defined in layer properties
340  const QStringList variableNames = layer->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
341  const QStringList variableValues = layer->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
342 
343  int varIndex = 0;
344  for ( const QString &variableName : variableNames )
345  {
346  if ( varIndex >= variableValues.length() )
347  {
348  break;
349  }
350 
351  QVariant varValue = variableValues.at( varIndex );
352  varIndex++;
353  scope->setVariable( variableName, varValue, true );
354  }
355 
356  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_name" ), layer->name(), true, true ) );
357  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_id" ), layer->id(), true, true ) );
358  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "_layer_crs" ), QVariant::fromValue<QgsCoordinateReferenceSystem>( layer->crs() ), true, true ) );
359  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_crs" ), layer->crs().authid(), true, true ) );
360  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer" ), QVariant::fromValue<QgsWeakMapLayerPointer >( QgsWeakMapLayerPointer( const_cast<QgsMapLayer *>( layer ) ) ), true, true ) );
361 
362  const QgsVectorLayer *vLayer = qobject_cast< const QgsVectorLayer * >( layer );
363  if ( vLayer )
364  {
365  scope->setFields( vLayer->fields() );
366  }
367 
368  //TODO - add functions. Possibilities include:
369  //is_selected
370  //field summary stats
371 
372  return scope;
373 }
374 
375 QList<QgsExpressionContextScope *> QgsExpressionContextUtils::globalProjectLayerScopes( const QgsMapLayer *layer )
376 {
377  QList<QgsExpressionContextScope *> scopes;
378  scopes << globalScope();
379 
380  QgsProject *project = QgsProject::instance(); // TODO: use project associated with layer
381  if ( project )
382  scopes << projectScope( project );
383 
384  if ( layer )
385  scopes << layerScope( layer );
386  return scopes;
387 }
388 
389 
390 void QgsExpressionContextUtils::setLayerVariable( QgsMapLayer *layer, const QString &name, const QVariant &value )
391 {
392  if ( !layer )
393  return;
394 
395  //write variable to layer
396  QStringList variableNames = layer->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
397  QStringList variableValues = layer->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
398 
399  variableNames << name;
400  variableValues << value.toString();
401 
402  layer->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
403  layer->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
404 }
405 
406 void QgsExpressionContextUtils::setLayerVariables( QgsMapLayer *layer, const QVariantMap &variables )
407 {
408  if ( !layer )
409  return;
410 
411  QStringList variableNames;
412  QStringList variableValues;
413 
414  QVariantMap::const_iterator it = variables.constBegin();
415  for ( ; it != variables.constEnd(); ++it )
416  {
417  variableNames << it.key();
418  variableValues << it.value().toString();
419  }
420 
421  layer->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
422  layer->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
423 }
424 
426 {
427  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
428  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
429 
430  // and because people don't read that ^^, I'm going to blast it all over this function
431 
432  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Map Settings" ) );
433 
434  //add known map settings context variables
435  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_id" ), "canvas", true ) );
436  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_rotation" ), mapSettings.rotation(), true ) );
437  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_scale" ), mapSettings.scale(), true ) );
438 
439  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
440  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
441 
442  QgsGeometry extent = QgsGeometry::fromRect( mapSettings.visibleExtent() );
443  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent" ), QVariant::fromValue( extent ), true ) );
444  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_width" ), mapSettings.visibleExtent().width(), true ) );
445  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_height" ), mapSettings.visibleExtent().height(), true ) );
446 
447  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
448  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
449 
450  QgsGeometry centerPoint = QgsGeometry::fromPointXY( mapSettings.visibleExtent().center() );
451  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_center" ), QVariant::fromValue( centerPoint ), true ) );
452 
453  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
454  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
455 
456  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs" ), mapSettings.destinationCrs().authid(), true ) );
457  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_definition" ), mapSettings.destinationCrs().toProj(), true ) );
458  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_units" ), QgsUnitTypes::toString( mapSettings.mapUnits() ), true ) );
459  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_description" ), mapSettings.destinationCrs().description(), true ) );
460  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_acronym" ), mapSettings.destinationCrs().projectionAcronym(), true ) );
461  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_projection" ), mapSettings.destinationCrs().operation().description(), true ) );
462  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_ellipsoid" ), mapSettings.destinationCrs().ellipsoidAcronym(), true ) );
463  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_proj4" ), mapSettings.destinationCrs().toProj(), true ) );
464  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_wkt" ), mapSettings.destinationCrs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ), true ) );
465 
466  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
467  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
468 
469  QVariantList layersIds;
470  QVariantList layers;
471  const QList<QgsMapLayer *> layersInMap = mapSettings.layers();
472  layersIds.reserve( layersInMap.count() );
473  layers.reserve( layersInMap.count() );
474  for ( QgsMapLayer *layer : layersInMap )
475  {
476  layersIds << layer->id();
477  layers << QVariant::fromValue<QgsWeakMapLayerPointer>( QgsWeakMapLayerPointer( layer ) );
478  }
479 
480  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
481  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
482 
483  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_layer_ids" ), layersIds, true ) );
484  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_layers" ), layers, true ) );
485 
486  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
487  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
488 
489  scope->addFunction( QStringLiteral( "is_layer_visible" ), new GetLayerVisibility( mapSettings.layers(), mapSettings.scale() ) );
490 
491  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
492  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
493 
494  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_start_time" ), mapSettings.isTemporal() ? mapSettings.temporalRange().begin() : QVariant(), true ) );
495  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_end_time" ), mapSettings.isTemporal() ? mapSettings.temporalRange().end() : QVariant(), true ) );
496  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_interval" ), mapSettings.isTemporal() ? ( mapSettings.temporalRange().end() - mapSettings.temporalRange().begin() ) : QVariant(), true ) );
497 
498  // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
499  // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
500 
501  return scope;
502 }
503 
504 QgsExpressionContextScope *QgsExpressionContextUtils::mapToolCaptureScope( const QList<QgsPointLocator::Match> &matches )
505 {
506  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Map Tool Capture" ) );
507 
508  QVariantList matchList;
509 
510  for ( const QgsPointLocator::Match &match : matches )
511  {
512  QVariantMap matchMap;
513 
514  matchMap.insert( QStringLiteral( "valid" ), match.isValid() );
515  matchMap.insert( QStringLiteral( "layer" ), QVariant::fromValue<QgsWeakMapLayerPointer>( QgsWeakMapLayerPointer( match.layer() ) ) );
516  matchMap.insert( QStringLiteral( "feature_id" ), match.featureId() );
517  matchMap.insert( QStringLiteral( "vertex_index" ), match.vertexIndex() );
518  matchMap.insert( QStringLiteral( "distance" ), match.distance() );
519 
520  matchList.append( matchMap );
521  }
522 
523  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "snapping_results" ), matchList ) );
524 
525  return scope;
526 }
527 
529 {
530  if ( !symbolScope )
531  return nullptr;
532 
533  symbolScope->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_SYMBOL_COLOR, symbol ? symbol->color() : QColor(), true ) );
534 
535  double angle = 0.0;
536  const QgsMarkerSymbol *markerSymbol = dynamic_cast< const QgsMarkerSymbol * >( symbol );
537  if ( markerSymbol )
538  {
539  angle = markerSymbol->angle();
540  }
542 
543  return symbolScope;
544 }
545 
547 {
548  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope( QObject::tr( "Layout" ) ) );
549  if ( !layout )
550  return scope.release();
551 
552  //add variables defined in layout properties
553  const QStringList variableNames = layout->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
554  const QStringList variableValues = layout->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
555 
556  int varIndex = 0;
557 
558  for ( const QString &variableName : variableNames )
559  {
560  if ( varIndex >= variableValues.length() )
561  {
562  break;
563  }
564 
565  QVariant varValue = variableValues.at( varIndex );
566  varIndex++;
567  scope->setVariable( variableName, varValue );
568  }
569 
570  //add known layout context variables
571  if ( const QgsMasterLayoutInterface *l = dynamic_cast< const QgsMasterLayoutInterface * >( layout ) )
572  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_name" ), l->name(), true ) );
573 
574  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_numpages" ), layout->pageCollection()->pageCount(), true ) );
575  if ( layout->pageCollection()->pageCount() > 0 )
576  {
577  // just take first page size
578  QSizeF s = layout->pageCollection()->page( 0 )->sizeWithUnits().toQSizeF();
579  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), s.height(), true ) );
580  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), s.width(), true ) );
581  }
582 
583  QVariantList offsets;
584  for ( int i = 0; i < layout->pageCollection()->pageCount(); i++ )
585  {
586  QPointF p = layout->pageCollection()->pagePositionToLayoutPosition( i, QgsLayoutPoint( 0, 0 ) );
587  offsets << p.y();
588  }
589  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageoffsets" ), offsets, true ) );
590 
591  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_dpi" ), layout->renderContext().dpi(), true ) );
592 
593  scope->addFunction( QStringLiteral( "item_variables" ), new GetLayoutItemVariables( layout ) );
594  scope->addFunction( QStringLiteral( "map_credits" ), new GetLayoutMapLayerCredits( layout ) );
595 
596  if ( layout->reportContext().layer() )
597  {
598  scope->setFields( layout->reportContext().layer()->fields() );
599  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layerid" ), layout->reportContext().layer()->id(), true ) );
600  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layername" ), layout->reportContext().layer()->name(), true ) );
601  }
602 
603  if ( layout->reportContext().feature().isValid() )
604  {
605  QgsFeature atlasFeature = layout->reportContext().feature();
606  scope->setFeature( atlasFeature );
607  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( atlasFeature ), true ) );
608  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), FID_IS_NULL( atlasFeature.id() ) ? QVariant() : atlasFeature.id(), true ) );
609  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( atlasFeature.geometry() ), true ) );
610  }
611 
612  return scope.release();
613 }
614 
615 void QgsExpressionContextUtils::setLayoutVariable( QgsLayout *layout, const QString &name, const QVariant &value )
616 {
617  if ( !layout )
618  return;
619 
620  //write variable to layout
621  QStringList variableNames = layout->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
622  QStringList variableValues = layout->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
623 
624  variableNames << name;
625  variableValues << value.toString();
626 
627  layout->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
628  layout->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
629 }
630 
631 void QgsExpressionContextUtils::setLayoutVariables( QgsLayout *layout, const QVariantMap &variables )
632 {
633  if ( !layout )
634  return;
635 
636  QStringList variableNames;
637  QStringList variableValues;
638 
639  QVariantMap::const_iterator it = variables.constBegin();
640  for ( ; it != variables.constEnd(); ++it )
641  {
642  variableNames << it.key();
643  variableValues << it.value().toString();
644  }
645 
646  layout->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
647  layout->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
648 }
649 
651 {
652  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Atlas" ) );
653  if ( !atlas )
654  {
655  //add some dummy atlas variables. This is done so that as in certain contexts we want to show
656  //users that these variables are available even if they have no current value
657  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_pagename" ), QString(), true, true ) );
658  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( QgsFeature() ), true, true ) );
659  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), QVariant(), true, true ) );
660  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( QgsGeometry() ), true, true ) );
661  return scope;
662  }
663 
664  //add known atlas variables
665  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_totalfeatures" ), atlas->count(), true, true ) );
666  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featurenumber" ), atlas->currentFeatureNumber() + 1, true, true ) );
667  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_filename" ), atlas->currentFilename(), true, true ) );
668  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_pagename" ), atlas->nameForPage( atlas->currentFeatureNumber() ), true, true ) );
669 
670  if ( atlas->enabled() && atlas->coverageLayer() )
671  {
672  scope->setFields( atlas->coverageLayer()->fields() );
673  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layerid" ), atlas->coverageLayer()->id(), true ) );
674  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layername" ), atlas->coverageLayer()->name(), true ) );
675  }
676 
677  if ( atlas->enabled() )
678  {
679  QgsFeature atlasFeature = atlas->layout()->reportContext().feature();
680  scope->setFeature( atlasFeature );
681  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( atlasFeature ), true ) );
682  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), FID_IS_NULL( atlasFeature.id() ) ? QVariant() : atlasFeature.id(), true ) );
683  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( atlasFeature.geometry() ), true ) );
684  }
685 
686  return scope;
687 }
688 
690 {
691  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Layout Item" ) );
692  if ( !item )
693  return scope;
694 
695  //add variables defined in layout item properties
696  const QStringList variableNames = item->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
697  const QStringList variableValues = item->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
698 
699  int varIndex = 0;
700  for ( const QString &variableName : variableNames )
701  {
702  if ( varIndex >= variableValues.length() )
703  {
704  break;
705  }
706 
707  QVariant varValue = variableValues.at( varIndex );
708  varIndex++;
709  scope->setVariable( variableName, varValue );
710  }
711 
712  //add known layout item context variables
713  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "item_id" ), item->id(), true ) );
714  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "item_uuid" ), item->uuid(), true ) );
715  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_page" ), item->page() + 1, true ) );
716 
717  if ( item->layout() )
718  {
719  const QgsLayoutItemPage *page = item->layout()->pageCollection()->page( item->page() );
720  if ( page )
721  {
722  const QSizeF s = page->sizeWithUnits().toQSizeF();
723  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), s.height(), true ) );
724  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), s.width(), true ) );
725  }
726  else
727  {
728  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), QVariant(), true ) );
729  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), QVariant(), true ) );
730  }
731  }
732 
733  return scope;
734 }
735 
736 void QgsExpressionContextUtils::setLayoutItemVariable( QgsLayoutItem *item, const QString &name, const QVariant &value )
737 {
738  if ( !item )
739  return;
740 
741  //write variable to layout item
742  QStringList variableNames = item->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
743  QStringList variableValues = item->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
744 
745  variableNames << name;
746  variableValues << value.toString();
747 
748  item->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
749  item->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
750 }
751 
752 void QgsExpressionContextUtils::setLayoutItemVariables( QgsLayoutItem *item, const QVariantMap &variables )
753 {
754  if ( !item )
755  return;
756 
757  QStringList variableNames;
758  QStringList variableValues;
759 
760  QVariantMap::const_iterator it = variables.constBegin();
761  for ( ; it != variables.constEnd(); ++it )
762  {
763  variableNames << it.key();
764  variableValues << it.value().toString();
765  }
766 
767  item->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
768  item->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
769 }
770 
772 {
773  QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Multiframe Item" ) );
774  if ( !frame )
775  return scope;
776 
777  //add variables defined in layout item properties
778  const QStringList variableNames = frame->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
779  const QStringList variableValues = frame->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
780 
781  int varIndex = 0;
782  for ( const QString &variableName : variableNames )
783  {
784  if ( varIndex >= variableValues.length() )
785  {
786  break;
787  }
788 
789  QVariant varValue = variableValues.at( varIndex );
790  varIndex++;
791  scope->setVariable( variableName, varValue );
792  }
793 
794  return scope;
795 }
796 
797 void QgsExpressionContextUtils::setLayoutMultiFrameVariable( QgsLayoutMultiFrame *frame, const QString &name, const QVariant &value )
798 {
799  if ( !frame )
800  return;
801 
802  //write variable to layout multiframe
803  QStringList variableNames = frame->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
804  QStringList variableValues = frame->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
805 
806  variableNames << name;
807  variableValues << value.toString();
808 
809  frame->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
810  frame->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
811 }
812 
814 {
815  if ( !frame )
816  return;
817 
818  QStringList variableNames;
819  QStringList variableValues;
820 
821  QVariantMap::const_iterator it = variables.constBegin();
822  for ( ; it != variables.constEnd(); ++it )
823  {
824  variableNames << it.key();
825  variableValues << it.value().toString();
826  }
827 
828  frame->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
829  frame->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
830 }
831 
833 {
835  scope->setFeature( feature );
836  scope->setFields( fields );
837  return QgsExpressionContext() << scope;
838 }
839 
841 {
842  // set aside for future use
843  Q_UNUSED( context )
844 
845  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope( QObject::tr( "Algorithm" ) ) );
846  scope->addFunction( QStringLiteral( "parameter" ), new GetProcessingParameterValue( parameters ) );
847 
848  if ( !algorithm )
849  return scope.release();
850 
851  //add standard algorithm variables
852  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "algorithm_id" ), algorithm->id(), true ) );
853 
854  return scope.release();
855 }
856 
857 QgsExpressionContextScope *QgsExpressionContextUtils::processingModelAlgorithmScope( const QgsProcessingModelAlgorithm *model, const QVariantMap &, QgsProcessingContext &context )
858 {
859  std::unique_ptr< QgsExpressionContextScope > modelScope( new QgsExpressionContextScope( QObject::tr( "Model" ) ) );
860  QString modelPath;
861  if ( !model->sourceFilePath().isEmpty() )
862  {
863  modelPath = model->sourceFilePath();
864  }
865  else if ( context.project() )
866  {
867  // fallback to project path -- the model may be embedded in a project, OR an unsaved model. In either case the
868  // project path is a logical value to fall back to
869  modelPath = context.project()->projectStorage() ? context.project()->fileName() : context.project()->absoluteFilePath();
870  }
871 
872  const QString modelFolder = !modelPath.isEmpty() ? QFileInfo( modelPath ).path() : QString();
873  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_path" ), QDir::toNativeSeparators( modelPath ), true ) );
874  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_folder" ), QDir::toNativeSeparators( modelFolder ), true, true ) );
875  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_name" ), model->displayName(), true ) );
876  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_group" ), model->group(), true ) );
877 
878  // custom variables
879  const QVariantMap customVariables = model->variables();
880  for ( auto it = customVariables.constBegin(); it != customVariables.constEnd(); ++it )
881  {
882  modelScope->addVariable( QgsExpressionContextScope::StaticVariable( it.key(), it.value(), true ) );
883  }
884 
885  return modelScope.release();
886 }
887 
889 {
890  std::unique_ptr< QgsExpressionContextScope > scope( new QgsExpressionContextScope() );
891  scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "notification_message" ), message, true ) );
892  return scope.release();
893 }
894 
896 {
897  QgsExpression::registerFunction( new GetNamedProjectColor( nullptr ) );
898  QgsExpression::registerFunction( new GetLayoutItemVariables( nullptr ) );
899  QgsExpression::registerFunction( new GetLayoutMapLayerCredits( nullptr ) );
900  QgsExpression::registerFunction( new GetLayerVisibility( QList<QgsMapLayer *>(), 0.0 ) );
901  QgsExpression::registerFunction( new GetProcessingParameterValue( QVariantMap() ) );
902  QgsExpression::registerFunction( new GetCurrentFormFieldValue( ) );
903  QgsExpression::registerFunction( new GetCurrentParentFormFieldValue( ) );
904 }
905 
907 {
908  Q_UNUSED( node )
909  return mUsesGeometry;
910 }
911 
913 {
914  Q_UNUSED( node )
915  return mReferencedColumns;
916 }
917 
919 {
920  return allParamsStatic( node, parent, context );
921 }
922 
923 //
924 // GetLayerVisibility
925 //
926 
927 QgsExpressionContextUtils::GetLayerVisibility::GetLayerVisibility( const QList<QgsMapLayer *> &layers, double scale )
928  : QgsScopedExpressionFunction( QStringLiteral( "is_layer_visible" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "General" ) )
929  , mLayers( _qgis_listRawToQPointer( layers ) )
930  , mScale( scale )
931 {
932  for ( const auto &layer : mLayers )
933  {
934  if ( layer->hasScaleBasedVisibility() )
935  {
936  mScaleBasedVisibilityDetails[ layer ] = qMakePair( layer->minimumScale(), layer->maximumScale() );
937  }
938  }
939 }
940 
941 QgsExpressionContextUtils::GetLayerVisibility::GetLayerVisibility()
942  : QgsScopedExpressionFunction( QStringLiteral( "is_layer_visible" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "General" ) )
943 {}
944 
945 QVariant QgsExpressionContextUtils::GetLayerVisibility::func( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
946 {
947  if ( mLayers.isEmpty() )
948  {
949  return false;
950  }
951 
952  bool isVisible = false;
953  QgsMapLayer *layer = QgsExpressionUtils::getMapLayer( values.at( 0 ), parent );
954  if ( layer && mLayers.contains( layer ) )
955  {
956  isVisible = true;
957  if ( mScaleBasedVisibilityDetails.contains( layer ) && !qgsDoubleNear( mScale, 0.0 ) )
958  {
959  if ( ( !qgsDoubleNear( mScaleBasedVisibilityDetails[ layer ].first, 0.0 ) && mScale > mScaleBasedVisibilityDetails[ layer ].first ) ||
960  ( !qgsDoubleNear( mScaleBasedVisibilityDetails[ layer ].second, 0.0 ) && mScale < mScaleBasedVisibilityDetails[ layer ].second ) )
961  {
962  isVisible = false;
963  }
964  }
965  }
966 
967  return isVisible;
968 }
969 
970 QgsScopedExpressionFunction *QgsExpressionContextUtils::GetLayerVisibility::clone() const
971 {
972  GetLayerVisibility *func = new GetLayerVisibility();
973  func->mLayers = mLayers;
974  func->mScale = mScale;
975  func->mScaleBasedVisibilityDetails = mScaleBasedVisibilityDetails;
976  return func;
977 }
static QString version()
Version string.
Definition: qgis.cpp:285
static QString releaseName()
Release name.
Definition: qgis.cpp:297
static int versionInt()
Version number used for comparing versions using the "Check QGIS Version" function.
Definition: qgis.cpp:290
static void setCustomVariables(const QVariantMap &customVariables)
Custom expression variables for this application.
static QString osName()
Returns a string name of the operating system QGIS is running on.
static QString platform()
Returns the QGIS platform name, e.g., "desktop" or "server".
static QVariantMap customVariables()
Custom expression variables for this application.
static QString locale()
Returns the QGIS locale.
static void setCustomVariable(const QString &name, const QVariant &value)
Set a single custom expression variable.
static QString userFullName()
Returns the user's operating system login account full display name.
static QString userLoginName()
Returns the user's operating system login account name.
QString toProj() const
Returns a Proj string representation of this CRS.
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
QString description() const
Returns the descriptive name of the CRS, e.g., "WGS 84" or "GDA 94 / Vicgrid94".
QString projectionAcronym() const
Returns the projection acronym for the projection used by the CRS.
QString authid() const
Returns the authority identifier for the CRS.
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
QgsProjOperation operation() const
Returns information about the PROJ operation associated with the coordinate reference system,...
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 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.
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.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
QgsGeometry geometry
Definition: qgsfeature.h:67
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:191
Q_GADGET QgsFeatureId id
Definition: qgsfeature.h:64
Container of fields for a vector layer.
Definition: qgsfields.h:45
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
static QgsGeometry fromPointXY(const QgsPointXY &point) SIP_HOLDGIL
Creates a new geometry from a QgsPointXY object.
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:70
QString name
Definition: qgsmaplayer.h:73
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:76
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
The QgsMapSettings class contains configuration for rendering of the map.
double scale() const
Returns the calculated map scale.
QgsUnitTypes::DistanceUnit mapUnits() const
Returns the units of the map's geographical coordinates - used for scale calculation.
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes takes output image size into accou...
QList< QgsMapLayer * > layers() const
Returns the list of layers which will be rendered in the map.
double rotation() const
Returns the rotation of the resulting map image, in degrees clockwise.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
A marker symbol type, for rendering Point and MultiPoint geometries.
double angle() const
Returns the marker angle for the whole symbol.
Interface for master layout type objects, such as print layouts and reports.
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:99
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:467
QgsExpressionContextScope * createExpressionContextScope() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QString fileName
Definition: qgsproject.h:102
QString absoluteFilePath() const
Returns full absolute path to the project file if the project is stored in a file system - derived fr...
Definition: qgsproject.cpp:698
QVariantMap customVariables() const
A map of custom project variables.
void setCustomVariables(const QVariantMap &customVariables)
A map of custom project variables.
QgsProjectStorage * projectStorage() const
Returns pointer to project storage implementation that handles read/write of the project file.
Definition: qgsproject.cpp:668
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:230
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Definition: qgsrectangle.h:251
Expression function for use within a QgsExpressionContextScope.
QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const override
Returns a set of field names which are required for this function.
bool isStatic(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const override
Will be called during prepare to determine if the function is static.
bool usesGeometry(const QgsExpressionNodeFunction *node) const override
Does this function use a geometry object.
QVariant func(const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node) override=0
Returns result of evaluating the function.
virtual QgsScopedExpressionFunction * clone() const =0
Returns a clone of the function.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:38
QColor color() const
Returns the symbol's color.
Definition: qgssymbol.cpp:551
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
bool isTemporal() const
Returns true if the object's temporal range is enabled, and the object will be filtered when renderin...
static Q_INVOKABLE QString toString(QgsUnitTypes::DistanceUnit unit)
Returns a translated string representing a distance unit.
Represents a vector layer which manages a vector based data sets.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
Definition: MathUtils.cpp:786
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:598
#define FID_IS_NULL(fid)
Definition: qgsfeatureid.h:30
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
Definition: qgsmaplayer.h:1853
Single variable definition for use within a QgsExpressionContextScope.