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