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