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