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