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