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