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