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