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