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