QGIS API Documentation 3.43.0-Master (b60ef06885e)
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->serverProperties()->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
390 const QgsCoordinateReferenceSystem verticalCrs = layer->verticalCrs();
391 if ( verticalCrs.isValid() )
392 {
393 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_vertical_crs" ), verticalCrs.authid(), true, true ) );
394 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_vertical_crs_definition" ), verticalCrs.toProj(), true, true ) );
395 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_vertical_crs_description" ), verticalCrs.description(), true, true ) );
396 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_vertical_crs_wkt" ), verticalCrs.toWkt( Qgis::CrsWktVariant::Preferred ), true ) );
397 }
398
399 const QgsVectorLayer *vLayer = qobject_cast< const QgsVectorLayer * >( layer );
400 if ( vLayer )
401 {
402 scope->setFields( vLayer->fields() );
403 }
404
405 //TODO - add functions. Possibilities include:
406 //is_selected
407 //field summary stats
408
409 return scope;
410}
411
412QList<QgsExpressionContextScope *> QgsExpressionContextUtils::globalProjectLayerScopes( const QgsMapLayer *layer )
413{
414 QList<QgsExpressionContextScope *> scopes;
415 scopes << globalScope();
416
417 QgsProject *project = QgsProject::instance(); // TODO: use project associated with layer skip-keyword-check
418 if ( project )
419 scopes << projectScope( project );
420
421 if ( layer )
422 scopes << layerScope( layer );
423 return scopes;
424}
425
426
427void QgsExpressionContextUtils::setLayerVariable( QgsMapLayer *layer, const QString &name, const QVariant &value )
428{
429 if ( !layer )
430 return;
431
432 // write variable to layer
433 QStringList variableNames = layer->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
434 QStringList variableValues = layer->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
435
436 // Set variable value if it is already in list
437 const int index = variableNames.indexOf( name );
438 if ( index != -1 )
439 {
440 variableValues[ index ] = value.toString();
441 }
442 // Otherwise, append it to the list
443 else
444 {
445 variableNames << name;
446 variableValues << value.toString();
447 }
448
449 layer->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
450 layer->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
451}
452
453void QgsExpressionContextUtils::setLayerVariables( QgsMapLayer *layer, const QVariantMap &variables )
454{
455 if ( !layer )
456 return;
457
458 QStringList variableNames;
459 QStringList variableValues;
460
461 QVariantMap::const_iterator it = variables.constBegin();
462 for ( ; it != variables.constEnd(); ++it )
463 {
464 variableNames << it.key();
465 variableValues << it.value().toString();
466 }
467
468 layer->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
469 layer->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
470}
471
473{
474 // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
475 // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
476
477 // and because people don't read that ^^, I'm going to blast it all over this function
478
479 QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Map Settings" ) );
480
481 //add known map settings context variables
482 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_id" ), "canvas", true ) );
483 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_rotation" ), mapSettings.rotation(), true ) );
484 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_scale" ), mapSettings.scale(), true ) );
485
486 scope->setVariable( QStringLiteral( "zoom_level" ), QgsVectorTileUtils::scaleToZoomLevel( mapSettings.scale(), 0, 99999 ), true );
487 scope->setVariable( QStringLiteral( "vector_tile_zoom" ), QgsVectorTileUtils::scaleToZoom( mapSettings.scale() ), true );
488
489 // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
490 // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
491
492 const QgsGeometry extent = QgsGeometry::fromRect( mapSettings.visibleExtent() );
493 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent" ), QVariant::fromValue( extent ), true ) );
494 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_width" ), mapSettings.visibleExtent().width(), true ) );
495 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_height" ), mapSettings.visibleExtent().height(), true ) );
496
497 // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
498 // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
499
500 const QgsGeometry centerPoint = QgsGeometry::fromPointXY( mapSettings.visibleExtent().center() );
501 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_extent_center" ), QVariant::fromValue( centerPoint ), true ) );
502
503 // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
504 // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
505
506 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs" ), mapSettings.destinationCrs().authid(), true ) );
507 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_definition" ), mapSettings.destinationCrs().toProj(), true ) );
508 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_units" ), QgsUnitTypes::toString( mapSettings.mapUnits() ), true ) );
509 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_description" ), mapSettings.destinationCrs().description(), true ) );
510 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_acronym" ), mapSettings.destinationCrs().projectionAcronym(), true ) );
511 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_projection" ), mapSettings.destinationCrs().operation().description(), true ) );
512 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_ellipsoid" ), mapSettings.destinationCrs().ellipsoidAcronym(), true ) );
513 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_proj4" ), mapSettings.destinationCrs().toProj(), true ) );
514 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_crs_wkt" ), mapSettings.destinationCrs().toWkt( Qgis::CrsWktVariant::Preferred ), true ) );
515
516 // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
517 // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
518
519 QVariantList layersIds;
520 QVariantList layers;
521 const QList<QgsMapLayer *> layersInMap = mapSettings.layers( true );
522 layersIds.reserve( layersInMap.count() );
523 layers.reserve( layersInMap.count() );
524 for ( QgsMapLayer *layer : layersInMap )
525 {
526 layersIds << layer->id();
527 layers << QVariant::fromValue<QgsWeakMapLayerPointer>( QgsWeakMapLayerPointer( layer ) );
528 }
529
530 // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
531 // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
532
533 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_layer_ids" ), layersIds, true ) );
534 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_layers" ), layers, true ) );
535
536 // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
537 // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
538
539 scope->addFunction( QStringLiteral( "is_layer_visible" ), new GetLayerVisibility( mapSettings.layers( true ), mapSettings.scale() ) );
540
541 // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
542 // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
543
544 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_start_time" ), mapSettings.isTemporal() ? mapSettings.temporalRange().begin() : QVariant(), true ) );
545 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_end_time" ), mapSettings.isTemporal() ? mapSettings.temporalRange().end() : QVariant(), true ) );
546 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_interval" ), mapSettings.isTemporal() ? QgsInterval( mapSettings.temporalRange().end() - mapSettings.temporalRange().begin() ) : QVariant(), true ) );
547
548 // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
549 // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
550
551 const QgsDoubleRange zRange = mapSettings.zRange();
552 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_z_range_lower" ), !zRange.isInfinite() ? zRange.lower() : QVariant(), true ) );
553 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "map_z_range_upper" ), !zRange.isInfinite() ? zRange.upper() : QVariant(), true ) );
554
555 // IMPORTANT: ANY CHANGES HERE ALSO NEED TO BE MADE TO QgsLayoutItemMap::createExpressionContext()
556 // (rationale is described in QgsLayoutItemMap::createExpressionContext() )
557
558 if ( mapSettings.frameRate() >= 0 )
559 scope->setVariable( QStringLiteral( "frame_rate" ), mapSettings.frameRate(), true );
560 if ( mapSettings.currentFrame() >= 0 )
561 scope->setVariable( QStringLiteral( "frame_number" ), mapSettings.currentFrame(), true );
562
563 return scope;
564}
565
566QgsExpressionContextScope *QgsExpressionContextUtils::mapToolCaptureScope( const QList<QgsPointLocator::Match> &matches )
567{
568 QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Map Tool Capture" ) );
569
570 QVariantList matchList;
571
572 for ( const QgsPointLocator::Match &match : matches )
573 {
574 QVariantMap matchMap;
575
576 matchMap.insert( QStringLiteral( "valid" ), match.isValid() );
577 matchMap.insert( QStringLiteral( "layer" ), QVariant::fromValue<QgsWeakMapLayerPointer>( QgsWeakMapLayerPointer( match.layer() ) ) );
578 matchMap.insert( QStringLiteral( "feature_id" ), match.featureId() );
579 matchMap.insert( QStringLiteral( "vertex_index" ), match.vertexIndex() );
580 matchMap.insert( QStringLiteral( "distance" ), match.distance() );
581
582 matchList.append( matchMap );
583 }
584
585 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "snapping_results" ), matchList ) );
586
587 return scope;
588}
589
591{
592 QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Map Layer Position" ) );
593 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layer_cursor_point" ), QVariant::fromValue( QgsGeometry::fromPointXY( position ) ) ) );
594 return scope;
595}
596
598{
599 if ( !symbolScope )
600 return nullptr;
601
602 symbolScope->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_SYMBOL_COLOR, symbol ? symbol->color() : QColor(), true ) );
603
604 double angle = 0.0;
605 const QgsMarkerSymbol *markerSymbol = dynamic_cast< const QgsMarkerSymbol * >( symbol );
606 if ( markerSymbol )
607 {
608 angle = markerSymbol->angle();
609 }
611
612 return symbolScope;
613}
614
616{
617 auto scope = std::make_unique<QgsExpressionContextScope>( QObject::tr( "Layout" ) );
618 if ( !layout )
619 return scope.release();
620
621 //add variables defined in layout properties
622 const QStringList variableNames = layout->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
623 const QStringList variableValues = layout->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
624
625 int varIndex = 0;
626
627 for ( const QString &variableName : variableNames )
628 {
629 if ( varIndex >= variableValues.length() )
630 {
631 break;
632 }
633
634 const QVariant varValue = variableValues.at( varIndex );
635 varIndex++;
636 scope->setVariable( variableName, varValue );
637 }
638
639 //add known layout context variables
640 if ( const QgsMasterLayoutInterface *l = dynamic_cast< const QgsMasterLayoutInterface * >( layout ) )
641 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_name" ), l->name(), true ) );
642
643 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_numpages" ), layout->pageCollection()->pageCount(), true ) );
644 if ( layout->pageCollection()->pageCount() > 0 )
645 {
646 // just take first page size
647 const QSizeF s = layout->pageCollection()->page( 0 )->sizeWithUnits().toQSizeF();
648 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), s.height(), true ) );
649 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), s.width(), true ) );
650 }
651
652 QVariantList offsets;
653 for ( int i = 0; i < layout->pageCollection()->pageCount(); i++ )
654 {
655 const QPointF p = layout->pageCollection()->pagePositionToLayoutPosition( i, QgsLayoutPoint( 0, 0 ) );
656 offsets << p.y();
657 }
658 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageoffsets" ), offsets, true ) );
659
660 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_dpi" ), layout->renderContext().dpi(), true ) );
661
662 scope->addFunction( QStringLiteral( "item_variables" ), new GetLayoutItemVariables( layout ) );
663 scope->addFunction( QStringLiteral( "map_credits" ), new GetLayoutMapLayerCredits( layout ) );
664
665 if ( layout->reportContext().layer() )
666 {
667 scope->setFields( layout->reportContext().layer()->fields() );
668 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layerid" ), layout->reportContext().layer()->id(), true ) );
669 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layername" ), layout->reportContext().layer()->name(), true ) );
670 }
671
672 if ( layout->reportContext().feature().isValid() )
673 {
674 const QgsFeature atlasFeature = layout->reportContext().feature();
675 scope->setFeature( atlasFeature );
676 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( atlasFeature ), true ) );
677 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), FID_IS_NULL( atlasFeature.id() ) ? QVariant() : atlasFeature.id(), true ) );
678 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( atlasFeature.geometry() ), true ) );
679 }
680
681 return scope.release();
682}
683
684void QgsExpressionContextUtils::setLayoutVariable( QgsLayout *layout, const QString &name, const QVariant &value )
685{
686 if ( !layout )
687 return;
688
689 //write variable to layout
690 QStringList variableNames = layout->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
691 QStringList variableValues = layout->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
692
693 variableNames << name;
694 variableValues << value.toString();
695
696 layout->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
697 layout->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
698}
699
700void QgsExpressionContextUtils::setLayoutVariables( QgsLayout *layout, const QVariantMap &variables )
701{
702 if ( !layout )
703 return;
704
705 QStringList variableNames;
706 QStringList variableValues;
707
708 QVariantMap::const_iterator it = variables.constBegin();
709 for ( ; it != variables.constEnd(); ++it )
710 {
711 variableNames << it.key();
712 variableValues << it.value().toString();
713 }
714
715 layout->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
716 layout->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
717}
718
720{
721 QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Atlas" ) );
722 if ( !atlas )
723 {
724 //add some dummy atlas variables. This is done so that as in certain contexts we want to show
725 //users that these variables are available even if they have no current value
726 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_pagename" ), QString(), true, true ) );
727 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( QgsFeature() ), true, true ) );
728 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), QVariant(), true, true ) );
729 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( QgsGeometry() ), true, true ) );
730 return scope;
731 }
732
733 //add known atlas variables
734 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_totalfeatures" ), atlas->count(), true, true ) );
735 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featurenumber" ), atlas->currentFeatureNumber() + 1, true, true ) );
736 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_filename" ), atlas->currentFilename(), true, true ) );
737 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_pagename" ), atlas->nameForPage( atlas->currentFeatureNumber() ), true, true ) );
738
739 if ( atlas->enabled() && atlas->coverageLayer() )
740 {
741 scope->setFields( atlas->coverageLayer()->fields() );
742 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layerid" ), atlas->coverageLayer()->id(), true ) );
743 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_layername" ), atlas->coverageLayer()->name(), true ) );
744 }
745
746 if ( atlas->enabled() )
747 {
748 const QgsFeature atlasFeature = atlas->layout()->reportContext().feature();
749 scope->setFeature( atlasFeature );
750 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_feature" ), QVariant::fromValue( atlasFeature ), true ) );
751 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_featureid" ), FID_IS_NULL( atlasFeature.id() ) ? QVariant() : atlasFeature.id(), true ) );
752 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "atlas_geometry" ), QVariant::fromValue( atlasFeature.geometry() ), true ) );
753 }
754
755 return scope;
756}
757
759{
760 QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Layout Item" ) );
761 if ( !item )
762 return scope;
763
764 //add variables defined in layout item properties
765 const QStringList variableNames = item->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
766 const QStringList variableValues = item->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
767
768 int varIndex = 0;
769 for ( const QString &variableName : variableNames )
770 {
771 if ( varIndex >= variableValues.length() )
772 {
773 break;
774 }
775
776 const QVariant varValue = variableValues.at( varIndex );
777 varIndex++;
778 scope->setVariable( variableName, varValue );
779 }
780
781 //add known layout item context variables
782 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "item_id" ), item->id(), true ) );
783 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "item_uuid" ), item->uuid(), true ) );
784 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_page" ), item->page() + 1, true ) );
785
786 if ( item->layout() )
787 {
788 const QgsLayoutItemPage *page = item->layout()->pageCollection()->page( item->page() );
789 if ( page )
790 {
791 const QSizeF s = page->sizeWithUnits().toQSizeF();
792 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), s.height(), true ) );
793 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), s.width(), true ) );
794 }
795 else
796 {
797 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pageheight" ), QVariant(), true ) );
798 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "layout_pagewidth" ), QVariant(), true ) );
799 }
800 }
801
802 return scope;
803}
804
805void QgsExpressionContextUtils::setLayoutItemVariable( QgsLayoutItem *item, const QString &name, const QVariant &value )
806{
807 if ( !item )
808 return;
809
810 //write variable to layout item
811 QStringList variableNames = item->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
812 QStringList variableValues = item->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
813
814 variableNames << name;
815 variableValues << value.toString();
816
817 item->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
818 item->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
819}
820
821void QgsExpressionContextUtils::setLayoutItemVariables( QgsLayoutItem *item, const QVariantMap &variables )
822{
823 if ( !item )
824 return;
825
826 QStringList variableNames;
827 QStringList variableValues;
828
829 QVariantMap::const_iterator it = variables.constBegin();
830 for ( ; it != variables.constEnd(); ++it )
831 {
832 variableNames << it.key();
833 variableValues << it.value().toString();
834 }
835
836 item->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
837 item->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
838}
839
841{
842 QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Multiframe Item" ) );
843 if ( !frame )
844 return scope;
845
846 //add variables defined in layout item properties
847 const QStringList variableNames = frame->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
848 const QStringList variableValues = frame->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
849
850 int varIndex = 0;
851 for ( const QString &variableName : variableNames )
852 {
853 if ( varIndex >= variableValues.length() )
854 {
855 break;
856 }
857
858 const QVariant varValue = variableValues.at( varIndex );
859 varIndex++;
860 scope->setVariable( variableName, varValue );
861 }
862
863 return scope;
864}
865
866void QgsExpressionContextUtils::setLayoutMultiFrameVariable( QgsLayoutMultiFrame *frame, const QString &name, const QVariant &value )
867{
868 if ( !frame )
869 return;
870
871 //write variable to layout multiframe
872 QStringList variableNames = frame->customProperty( QStringLiteral( "variableNames" ) ).toStringList();
873 QStringList variableValues = frame->customProperty( QStringLiteral( "variableValues" ) ).toStringList();
874
875 variableNames << name;
876 variableValues << value.toString();
877
878 frame->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
879 frame->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
880}
881
883{
884 if ( !frame )
885 return;
886
887 QStringList variableNames;
888 QStringList variableValues;
889
890 QVariantMap::const_iterator it = variables.constBegin();
891 for ( ; it != variables.constEnd(); ++it )
892 {
893 variableNames << it.key();
894 variableValues << it.value().toString();
895 }
896
897 frame->setCustomProperty( QStringLiteral( "variableNames" ), variableNames );
898 frame->setCustomProperty( QStringLiteral( "variableValues" ), variableValues );
899}
900
902{
904 scope->setFeature( feature );
905 scope->setFields( fields );
906 return QgsExpressionContext() << scope;
907}
908
910{
911 // set aside for future use
912 Q_UNUSED( context )
913
914 auto scope = std::make_unique<QgsExpressionContextScope>( QObject::tr( "Algorithm" ) );
915 scope->addFunction( QStringLiteral( "parameter" ), new GetProcessingParameterValue( parameters ) );
916
917 if ( !algorithm )
918 return scope.release();
919
920 //add standard algorithm variables
921 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "algorithm_id" ), algorithm->id(), true ) );
922
923 return scope.release();
924}
925
926QgsExpressionContextScope *QgsExpressionContextUtils::processingModelAlgorithmScope( const QgsProcessingModelAlgorithm *model, const QVariantMap &, QgsProcessingContext &context )
927{
928 auto modelScope = std::make_unique<QgsExpressionContextScope>( QObject::tr( "Model" ) );
929 QString modelPath;
930 if ( !model->sourceFilePath().isEmpty() )
931 {
932 modelPath = model->sourceFilePath();
933 }
934 else if ( context.project() )
935 {
936 // fallback to project path -- the model may be embedded in a project, OR an unsaved model. In either case the
937 // project path is a logical value to fall back to
938 modelPath = context.project()->projectStorage() ? context.project()->fileName() : context.project()->absoluteFilePath();
939 }
940
941 const QString modelFolder = !modelPath.isEmpty() ? QFileInfo( modelPath ).path() : QString();
942 modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_path" ), QDir::toNativeSeparators( modelPath ), true ) );
943 modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_folder" ), QDir::toNativeSeparators( modelFolder ), true, true ) );
944 modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_name" ), model->displayName(), true ) );
945 modelScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "model_group" ), model->group(), true ) );
946
947 // custom variables
948 const QVariantMap customVariables = model->variables();
949 for ( auto it = customVariables.constBegin(); it != customVariables.constEnd(); ++it )
950 {
951 modelScope->addVariable( QgsExpressionContextScope::StaticVariable( it.key(), it.value(), true ) );
952 }
953
954 return modelScope.release();
955}
956
958{
959 auto scope = std::make_unique<QgsExpressionContextScope>();
960 scope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "notification_message" ), message, true ) );
961 return scope.release();
962}
963
965{
966 QgsExpression::registerFunction( new GetNamedProjectColor( nullptr ) );
967 QgsExpression::registerFunction( new GetNamedProjectColorObject( nullptr ) );
968 QgsExpression::registerFunction( new GetSensorData( ) );
969 QgsExpression::registerFunction( new GetLayoutItemVariables( nullptr ) );
970 QgsExpression::registerFunction( new GetLayoutMapLayerCredits( nullptr ) );
971 QgsExpression::registerFunction( new GetLayerVisibility( QList<QgsMapLayer *>(), 0.0 ) );
972 QgsExpression::registerFunction( new GetProcessingParameterValue( QVariantMap() ) );
973 QgsExpression::registerFunction( new GetCurrentFormFieldValue( ) );
974 QgsExpression::registerFunction( new GetCurrentParentFormFieldValue( ) );
975 QgsExpression::registerFunction( new LoadLayerFunction( ) );
976}
977
979{
980 Q_UNUSED( node )
981 return mUsesGeometry;
982}
983
985{
986 Q_UNUSED( node )
987 return mReferencedColumns;
988}
989
991{
992 return allParamsStatic( node, parent, context );
993}
994
995//
996// GetLayerVisibility
997//
998
999QgsExpressionContextUtils::GetLayerVisibility::GetLayerVisibility( const QList<QgsMapLayer *> &layers, double scale )
1000 : QgsScopedExpressionFunction( QStringLiteral( "is_layer_visible" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "General" ) )
1001 , mLayers( _qgis_listRawToQPointer( layers ) )
1002 , mScale( scale )
1003{
1004 for ( const auto &layer : mLayers )
1005 {
1006 if ( layer->hasScaleBasedVisibility() )
1007 {
1008 mScaleBasedVisibilityDetails[ layer ] = qMakePair( layer->minimumScale(), layer->maximumScale() );
1009 }
1010 }
1011}
1012
1013QgsExpressionContextUtils::GetLayerVisibility::GetLayerVisibility()
1014 : QgsScopedExpressionFunction( QStringLiteral( "is_layer_visible" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "General" ) )
1015{}
1016
1017QVariant QgsExpressionContextUtils::GetLayerVisibility::func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction * )
1018{
1019 if ( mLayers.isEmpty() )
1020 {
1021 return false;
1022 }
1023
1024 bool isVisible = false;
1026 QgsMapLayer *layer = QgsExpressionUtils::getMapLayer( values.at( 0 ), context, parent );
1028 if ( layer && mLayers.contains( layer ) )
1029 {
1030 isVisible = true;
1031 if ( mScaleBasedVisibilityDetails.contains( layer ) && !qgsDoubleNear( mScale, 0.0 ) )
1032 {
1033 if ( ( !qgsDoubleNear( mScaleBasedVisibilityDetails[ layer ].first, 0.0 ) && mScale > mScaleBasedVisibilityDetails[ layer ].first ) ||
1034 ( !qgsDoubleNear( mScaleBasedVisibilityDetails[ layer ].second, 0.0 ) && mScale < mScaleBasedVisibilityDetails[ layer ].second ) )
1035 {
1036 isVisible = false;
1037 }
1038 }
1039 }
1040
1041 return isVisible;
1042}
1043
1044QgsScopedExpressionFunction *QgsExpressionContextUtils::GetLayerVisibility::clone() const
1045{
1046 GetLayerVisibility *func = new GetLayerVisibility();
1047 func->mLayers = mLayers;
1048 func->mScale = mScale;
1049 func->mScaleBasedVisibilityDetails = mScaleBasedVisibilityDetails;
1050 return func;
1051}
1052
1053//
1054// mesh expression context
1055//
1056
1058class CurrentVertexZValueExpressionFunction: public QgsScopedExpressionFunction
1059{
1060 public:
1061 CurrentVertexZValueExpressionFunction():
1062 QgsScopedExpressionFunction( "$vertex_z",
1063 0,
1064 QStringLiteral( "Meshes" ) )
1065 {}
1066
1067 QgsScopedExpressionFunction *clone() const override {return new CurrentVertexZValueExpressionFunction();}
1068
1069 QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1070 {
1071 if ( context &&
1072 context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) &&
1073 context->hasVariable( QStringLiteral( "_native_mesh" ) ) )
1074 {
1075 int vertexIndex = context->variable( QStringLiteral( "_mesh_vertex_index" ) ).toInt();
1076 const QgsMesh nativeMesh = qvariant_cast<QgsMesh>( context->variable( QStringLiteral( "_native_mesh" ) ) );
1077 const QgsMeshVertex &vertex = nativeMesh.vertex( vertexIndex );
1078 if ( !vertex.isEmpty() )
1079 return vertex.z();
1080 }
1081
1082 return QVariant();
1083 }
1084
1085 bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1086 {
1087 return false;
1088 }
1089};
1090
1091class CurrentVertexXValueExpressionFunction: public QgsScopedExpressionFunction
1092{
1093 public:
1094 CurrentVertexXValueExpressionFunction():
1095 QgsScopedExpressionFunction( "$vertex_x",
1096 0,
1097 QStringLiteral( "Meshes" ) )
1098 {}
1099
1100 QgsScopedExpressionFunction *clone() const override {return new CurrentVertexXValueExpressionFunction();}
1101
1102 QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1103 {
1104 if ( context &&
1105 context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) &&
1106 context->hasVariable( QStringLiteral( "_native_mesh" ) ) )
1107 {
1108 int vertexIndex = context->variable( QStringLiteral( "_mesh_vertex_index" ) ).toInt();
1109 const QgsMesh nativeMesh = qvariant_cast<QgsMesh>( context->variable( QStringLiteral( "_native_mesh" ) ) );
1110 const QgsMeshVertex &vertex = nativeMesh.vertex( vertexIndex );
1111 if ( !vertex.isEmpty() )
1112 return vertex.x();
1113 }
1114
1115 return QVariant();
1116 }
1117
1118 bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1119 {
1120 return false;
1121 }
1122};
1123
1124class CurrentVertexYValueExpressionFunction: public QgsScopedExpressionFunction
1125{
1126 public:
1127 CurrentVertexYValueExpressionFunction():
1128 QgsScopedExpressionFunction( "$vertex_y",
1129 0,
1130 QStringLiteral( "Meshes" ) )
1131 {}
1132
1133 QgsScopedExpressionFunction *clone() const override {return new CurrentVertexYValueExpressionFunction();}
1134
1135 QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1136 {
1137 if ( context &&
1138 context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) &&
1139 context->hasVariable( QStringLiteral( "_native_mesh" ) ) )
1140 {
1141 int vertexIndex = context->variable( QStringLiteral( "_mesh_vertex_index" ) ).toInt();
1142 const QgsMesh nativeMesh = qvariant_cast<QgsMesh>( context->variable( QStringLiteral( "_native_mesh" ) ) );
1143 const QgsMeshVertex &vertex = nativeMesh.vertex( vertexIndex );
1144 if ( !vertex.isEmpty() )
1145 return vertex.y();
1146 }
1147
1148 return QVariant();
1149 }
1150
1151 bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1152 {
1153 return false;
1154 }
1155};
1156
1157class CurrentVertexExpressionFunction: public QgsScopedExpressionFunction
1158{
1159 public:
1160 CurrentVertexExpressionFunction():
1161 QgsScopedExpressionFunction( "$vertex_as_point",
1162 0,
1163 QStringLiteral( "Meshes" ) )
1164 {}
1165
1166 QgsScopedExpressionFunction *clone() const override {return new CurrentVertexExpressionFunction();}
1167
1168 QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1169 {
1170 if ( context &&
1171 context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) &&
1172 context->hasVariable( QStringLiteral( "_native_mesh" ) ) )
1173 {
1174 int vertexIndex = context->variable( QStringLiteral( "_mesh_vertex_index" ) ).toInt();
1175 const QgsMesh nativeMesh = qvariant_cast<QgsMesh>( context->variable( QStringLiteral( "_native_mesh" ) ) );
1176 const QgsMeshVertex &vertex = nativeMesh.vertex( vertexIndex );
1177 if ( !vertex.isEmpty() )
1178 return QVariant::fromValue( QgsGeometry( new QgsPoint( vertex ) ) );
1179 }
1180
1181 return QVariant();
1182 }
1183
1184 bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1185 {
1186 return false;
1187 }
1188};
1189
1190class CurrentVertexIndexExpressionFunction: public QgsScopedExpressionFunction
1191{
1192 public:
1193 CurrentVertexIndexExpressionFunction():
1194 QgsScopedExpressionFunction( "$vertex_index",
1195 0,
1196 QStringLiteral( "Meshes" ) )
1197 {}
1198
1199 QgsScopedExpressionFunction *clone() const override {return new CurrentVertexIndexExpressionFunction();}
1200
1201 QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1202 {
1203 if ( !context )
1204 return QVariant();
1205
1206 if ( !context->hasVariable( QStringLiteral( "_mesh_vertex_index" ) ) )
1207 return QVariant();
1208
1209 return context->variable( QStringLiteral( "_mesh_vertex_index" ) );
1210 }
1211
1212
1213 bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1214 {
1215 return false;
1216 }
1217};
1218
1219class CurrentFaceAreaExpressionFunction: public QgsScopedExpressionFunction
1220{
1221 public:
1222 CurrentFaceAreaExpressionFunction():
1223 QgsScopedExpressionFunction( "$face_area",
1224 0,
1225 QStringLiteral( "Meshes" ) )
1226 {}
1227
1228 QgsScopedExpressionFunction *clone() const override {return new CurrentFaceAreaExpressionFunction();}
1229
1230 QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction * ) override
1231 {
1232 if ( context &&
1233 context->hasVariable( QStringLiteral( "_mesh_face_index" ) ) &&
1234 context->hasVariable( QStringLiteral( "_native_mesh" ) ) )
1235 {
1236 const int faceIndex = context->variable( QStringLiteral( "_mesh_face_index" ) ).toInt();
1237 const QgsMesh nativeMesh = qvariant_cast<QgsMesh>( context->variable( QStringLiteral( "_native_mesh" ) ) );
1238 const QgsMeshFace &face = nativeMesh.face( faceIndex );
1239 if ( !face.isEmpty() )
1240 {
1241 QgsDistanceArea *calc = parent->geomCalculator();
1242 QgsGeometry geom = QgsMeshUtils::toGeometry( nativeMesh.face( faceIndex ), nativeMesh.vertices );
1243 if ( calc )
1244 {
1245 try
1246 {
1247 double area = calc->measureArea( geom );
1248 area = calc->convertAreaMeasurement( area, parent->areaUnits() );
1249 return QVariant( area );
1250 }
1251 catch ( QgsCsException & )
1252 {
1253 parent->setEvalErrorString( QObject::tr( "An error occurred while calculating area" ) );
1254 return QVariant();
1255 }
1256 }
1257 else
1258 {
1259 return QVariant( geom.area() );
1260 }
1261 }
1262 }
1263
1264 return QVariant();
1265 }
1266
1267 bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1268 {
1269 return false;
1270 }
1271};
1272
1273class CurrentFaceIndexExpressionFunction: public QgsScopedExpressionFunction
1274{
1275 public:
1276 CurrentFaceIndexExpressionFunction():
1277 QgsScopedExpressionFunction( "$face_index",
1278 0,
1279 QStringLiteral( "Meshes" ) )
1280 {}
1281
1282 QgsScopedExpressionFunction *clone() const override {return new CurrentFaceIndexExpressionFunction();}
1283
1284 QVariant func( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * ) override
1285 {
1286 if ( !context )
1287 return QVariant();
1288
1289 if ( !context->hasVariable( QStringLiteral( "_mesh_face_index" ) ) )
1290 return QVariant();
1291
1292 return context->variable( QStringLiteral( "_mesh_face_index" ) ).toInt();
1293
1294 }
1295
1296 bool isStatic( const QgsExpressionNodeFunction *, QgsExpression *, const QgsExpressionContext * ) const override
1297 {
1298 return false;
1299 }
1300};
1301
1302
1303
1305{
1306 auto scope = std::make_unique<QgsExpressionContextScope>();
1307
1308 switch ( elementType )
1309 {
1310 case QgsMesh::Vertex:
1311 {
1312 QgsExpression::registerFunction( new CurrentVertexExpressionFunction, true );
1313 QgsExpression::registerFunction( new CurrentVertexXValueExpressionFunction, true );
1314 QgsExpression::registerFunction( new CurrentVertexYValueExpressionFunction, true );
1315 QgsExpression::registerFunction( new CurrentVertexZValueExpressionFunction, true );
1316 QgsExpression::registerFunction( new CurrentVertexIndexExpressionFunction, true );
1317 scope->addFunction( "$vertex_as_point", new CurrentVertexExpressionFunction );
1318 scope->addFunction( "$vertex_x", new CurrentVertexXValueExpressionFunction );
1319 scope->addFunction( "$vertex_y", new CurrentVertexYValueExpressionFunction );
1320 scope->addFunction( "$vertex_z", new CurrentVertexZValueExpressionFunction );
1321 scope->addFunction( "$vertex_index", new CurrentVertexIndexExpressionFunction );
1322 }
1323 break;
1324 case QgsMesh::Face:
1325 {
1326 QgsExpression::registerFunction( new CurrentFaceAreaExpressionFunction, true );
1327 QgsExpression::registerFunction( new CurrentFaceIndexExpressionFunction, true );
1328 scope->addFunction( "$face_area", new CurrentFaceAreaExpressionFunction );
1329 scope->addFunction( "$face_index", new CurrentFaceIndexExpressionFunction );
1330 }
1331 break;
1332 case QgsMesh::Edge:
1333 break;
1334 }
1335
1336 return scope.release();
1337}
1338
1339
1340QVariant LoadLayerFunction::func( const QVariantList &, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
1341{
1342 parent->setEvalErrorString( QObject::tr( "Invalid arguments for load_layer function" ) );
1343 return QVariant();
1344}
1345
1346bool LoadLayerFunction::isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const
1347{
1348 if ( node->args()->count() > 1 )
1349 {
1350 if ( !context )
1351 return false;
1352
1353 QPointer< QgsMapLayerStore > store( context->loadedLayerStore() );
1354 if ( !store )
1355 {
1356 parent->setEvalErrorString( QObject::tr( "load_layer cannot be used in this context" ) );
1357 return false;
1358 }
1359
1360 QgsExpressionNode *uriNode = node->args()->at( 0 );
1361 QgsExpressionNode *providerNode = node->args()->at( 1 );
1362 if ( !uriNode->isStatic( parent, context ) )
1363 {
1364 parent->setEvalErrorString( QObject::tr( "load_layer requires a static value for the uri argument" ) );
1365 return false;
1366 }
1367 if ( !providerNode->isStatic( parent, context ) )
1368 {
1369 parent->setEvalErrorString( QObject::tr( "load_layer requires a static value for the provider argument" ) );
1370 return false;
1371 }
1372
1373 const QString uri = uriNode->eval( parent, context ).toString();
1374 if ( uri.isEmpty() )
1375 {
1376 parent->setEvalErrorString( QObject::tr( "Invalid uri argument for load_layer" ) );
1377 return false;
1378 }
1379
1380 const QString providerKey = providerNode->eval( parent, context ).toString();
1381 if ( providerKey.isEmpty() )
1382 {
1383 parent->setEvalErrorString( QObject::tr( "Invalid provider argument for load_layer" ) );
1384 return false;
1385 }
1386
1387 const QgsCoordinateTransformContext transformContext = context->variable( QStringLiteral( "_project_transform_context" ) ).value<QgsCoordinateTransformContext>();
1388
1389 bool res = false;
1390 auto loadLayer = [ uri, providerKey, store, node, parent, &res, &transformContext ]
1391 {
1393 if ( !metadata )
1394 {
1395 parent->setEvalErrorString( QObject::tr( "Invalid provider argument for load_layer" ) );
1396 return;
1397 }
1398
1399 if ( metadata->supportedLayerTypes().empty() )
1400 {
1401 parent->setEvalErrorString( QObject::tr( "Cannot use %1 provider for load_layer" ).arg( providerKey ) );
1402 return;
1403 }
1404
1405 QgsMapLayerFactory::LayerOptions layerOptions( transformContext );
1406 layerOptions.loadAllStoredStyles = false;
1407 layerOptions.loadDefaultStyle = false;
1408
1409 QgsMapLayer *layer = QgsMapLayerFactory::createLayer( uri, uri, metadata->supportedLayerTypes().value( 0 ), layerOptions, providerKey );
1410 if ( !layer )
1411 {
1412 parent->setEvalErrorString( QObject::tr( "Could not load_layer with uri: %1" ).arg( uri ) );
1413 return;
1414 }
1415 if ( !layer->isValid() )
1416 {
1417 delete layer;
1418 parent->setEvalErrorString( QObject::tr( "Could not load_layer with uri: %1" ).arg( uri ) );
1419 return;
1420 }
1421
1422 store->addMapLayer( layer );
1423
1424 node->setCachedStaticValue( QVariant::fromValue( QgsWeakMapLayerPointer( layer ) ) );
1425 res = true;
1426 };
1427
1428 // Make sure we load the layer on the thread where the store lives
1429 if ( QThread::currentThread() == store->thread() )
1430 loadLayer();
1431 else
1432 QMetaObject::invokeMethod( store, loadLayer, Qt::BlockingQueuedConnection );
1433
1434 return res;
1435 }
1436 return false;
1437}
1438
1439QgsScopedExpressionFunction *LoadLayerFunction::clone() const
1440{
1441 return new LoadLayerFunction();
1442}
static QString version()
Version string.
Definition qgis.cpp:267
static QString releaseName()
Release name.
Definition qgis.cpp:279
static int versionInt()
Version number used for comparing versions using the "Check QGIS Version" function.
Definition qgis.cpp:272
@ 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.
Represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
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.
Custom exception class for Coordinate Reference System related exceptions.
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:233
bool isInfinite() const
Returns true if the range consists of all possible values.
Definition qgsrange.h:287
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.
QVariantMap variablesToMap() const
Returns a map of variable name to value representing all the expression variables contained by the co...
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
An 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.
Handles 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:58
QgsFeatureId id
Definition qgsfeature.h:66
QgsGeometry geometry
Definition qgsfeature.h:69
bool isValid() const
Returns the validity of this feature.
Container of fields for a vector layer.
Definition qgsfields.h:46
A geometry is the spatial representation of a feature.
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
Used to render QgsLayout as an atlas, by iterating over the features from an associated vector layer.
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.
Provides a method of storing points, consisting of an x and y coordinate, for use in QGIS layouts.
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.
QgsLayoutRenderContext & renderContext()
Returns a reference to the layout's render context, which stores information relating to the current ...
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout's page collection, which stores and manages page items in the layout.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from the layout.
QgsLayoutReportContext & reportContext()
Returns a reference to the layout's report context, which stores information relating to the current ...
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:77
QString name
Definition qgsmaplayer.h:81
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:84
QString id
Definition qgsmaplayer.h:80
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
QgsCoordinateReferenceSystem verticalCrs
Definition qgsmaplayer.h:85
Contains configuration for rendering maps.
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.
static QgsGeometry toGeometry(const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Returns face as polygon geometry.
Represents a 2D point.
Definition qgspointxy.h:60
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:49
double z
Definition qgspoint.h:54
double x
Definition qgspoint.h:52
bool isEmpty() const override
Returns true if the geometry is empty.
Definition qgspoint.cpp:736
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.
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...
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.
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
QgsPointXY center
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:231
QColor color() const
Returns the symbol's color.
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:446
T end() const
Returns the upper bound of the range.
Definition qgsrange.h:453
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 dataset.
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.
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:6819
#define Q_NOWARN_DEPRECATED_PUSH
Definition qgis.h:6818
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition qgis.h:6286
#define FID_IS_NULL(fid)
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
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.