QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgslayoutatlas.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayoutatlas.cpp
3  ----------------
4  begin : December 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 #include <algorithm>
18 #include <stdexcept>
19 #include <QtAlgorithms>
20 
21 #include "qgslayoutatlas.h"
22 #include "qgslayout.h"
23 #include "qgsmessagelog.h"
24 #include "qgsfeaturerequest.h"
25 #include "qgsfeatureiterator.h"
26 #include "qgsvectorlayer.h"
28 
30  : QObject( layout )
31  , mLayout( layout )
32  , mFilenameExpressionString( QStringLiteral( "'output_'||@atlas_featurenumber" ) )
33 {
34 
35  //listen out for layer removal
36  connect( mLayout->project(), static_cast < void ( QgsProject::* )( const QStringList & ) >( &QgsProject::layersWillBeRemoved ), this, &QgsLayoutAtlas::removeLayers );
37 
38  if ( mLayout->customProperty( QStringLiteral( "singleFile" ) ).isNull() )
39  mLayout->setCustomProperty( QStringLiteral( "singleFile" ), true );
40 }
41 
43 {
44  return QStringLiteral( "atlas" );
45 }
46 
48 {
49  return mLayout;
50 }
51 
52 const QgsLayout *QgsLayoutAtlas::layout() const
53 {
54  return mLayout.data();
55 }
56 
57 bool QgsLayoutAtlas::writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext & ) const
58 {
59  QDomElement atlasElem = document.createElement( QStringLiteral( "Atlas" ) );
60  atlasElem.setAttribute( QStringLiteral( "enabled" ), mEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
61 
62  if ( mCoverageLayer )
63  {
64  atlasElem.setAttribute( QStringLiteral( "coverageLayer" ), mCoverageLayer.layerId );
65  atlasElem.setAttribute( QStringLiteral( "coverageLayerName" ), mCoverageLayer.name );
66  atlasElem.setAttribute( QStringLiteral( "coverageLayerSource" ), mCoverageLayer.source );
67  atlasElem.setAttribute( QStringLiteral( "coverageLayerProvider" ), mCoverageLayer.provider );
68  }
69  else
70  {
71  atlasElem.setAttribute( QStringLiteral( "coverageLayer" ), QString() );
72  }
73 
74  atlasElem.setAttribute( QStringLiteral( "hideCoverage" ), mHideCoverage ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
75  atlasElem.setAttribute( QStringLiteral( "filenamePattern" ), mFilenameExpressionString );
76  atlasElem.setAttribute( QStringLiteral( "pageNameExpression" ), mPageNameExpression );
77 
78  atlasElem.setAttribute( QStringLiteral( "sortFeatures" ), mSortFeatures ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
79  if ( mSortFeatures )
80  {
81  atlasElem.setAttribute( QStringLiteral( "sortKey" ), mSortExpression );
82  atlasElem.setAttribute( QStringLiteral( "sortAscending" ), mSortAscending ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
83  }
84  atlasElem.setAttribute( QStringLiteral( "filterFeatures" ), mFilterFeatures ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
85  if ( mFilterFeatures )
86  {
87  atlasElem.setAttribute( QStringLiteral( "featureFilter" ), mFilterExpression );
88  }
89 
90  parentElement.appendChild( atlasElem );
91 
92  return true;
93 }
94 
95 bool QgsLayoutAtlas::readXml( const QDomElement &atlasElem, const QDomDocument &, const QgsReadWriteContext & )
96 {
97  mEnabled = atlasElem.attribute( QStringLiteral( "enabled" ), QStringLiteral( "0" ) ).toInt();
98 
99  // look for stored layer name
100  const QString layerId = atlasElem.attribute( QStringLiteral( "coverageLayer" ) );
101  const QString layerName = atlasElem.attribute( QStringLiteral( "coverageLayerName" ) );
102  const QString layerSource = atlasElem.attribute( QStringLiteral( "coverageLayerSource" ) );
103  const QString layerProvider = atlasElem.attribute( QStringLiteral( "coverageLayerProvider" ) );
104 
105  mCoverageLayer = QgsVectorLayerRef( layerId, layerName, layerSource, layerProvider );
106  mCoverageLayer.resolveWeakly( mLayout->project() );
107  mLayout->reportContext().setLayer( mCoverageLayer.get() );
108 
109  mPageNameExpression = atlasElem.attribute( QStringLiteral( "pageNameExpression" ), QString() );
110  QString error;
111  setFilenameExpression( atlasElem.attribute( QStringLiteral( "filenamePattern" ), QString() ), error );
112 
113  mSortFeatures = atlasElem.attribute( QStringLiteral( "sortFeatures" ), QStringLiteral( "0" ) ).toInt();
114  mSortExpression = atlasElem.attribute( QStringLiteral( "sortKey" ) );
115  mSortAscending = atlasElem.attribute( QStringLiteral( "sortAscending" ), QStringLiteral( "1" ) ).toInt();
116  mFilterFeatures = atlasElem.attribute( QStringLiteral( "filterFeatures" ), QStringLiteral( "0" ) ).toInt();
117  mFilterExpression = atlasElem.attribute( QStringLiteral( "featureFilter" ) );
118 
119  mHideCoverage = atlasElem.attribute( QStringLiteral( "hideCoverage" ), QStringLiteral( "0" ) ).toInt();
120 
121  emit toggled( mEnabled );
122  emit changed();
123  return true;
124 }
125 
126 void QgsLayoutAtlas::setEnabled( bool enabled )
127 {
128  if ( enabled == mEnabled )
129  {
130  return;
131  }
132 
133  mEnabled = enabled;
134  emit toggled( enabled );
135  emit changed();
136 }
137 
138 void QgsLayoutAtlas::removeLayers( const QStringList &layers )
139 {
140  if ( !mCoverageLayer )
141  {
142  return;
143  }
144 
145  for ( const QString &layerId : layers )
146  {
147  if ( layerId == mCoverageLayer.layerId )
148  {
149  //current coverage layer removed
150  mCoverageLayer.setLayer( nullptr );
151  setEnabled( false );
152  break;
153  }
154  }
155 }
156 
158 {
159  if ( layer == mCoverageLayer.get() )
160  {
161  return;
162  }
163 
164  mCoverageLayer.setLayer( layer );
165  emit coverageLayerChanged( layer );
166 }
167 
168 void QgsLayoutAtlas::setPageNameExpression( const QString &expression )
169 {
170  if ( mPageNameExpression == expression )
171  return;
172 
173  mPageNameExpression = expression;
174  emit changed();
175 }
176 
177 QString QgsLayoutAtlas::nameForPage( int pageNumber ) const
178 {
179  if ( pageNumber < 0 || pageNumber >= mFeatureIds.count() )
180  return QString();
181 
182  return mFeatureIds.at( pageNumber ).second;
183 }
184 
186 {
187  if ( mSortFeatures == enabled )
188  return;
189 
190  mSortFeatures = enabled;
191  emit changed();
192 }
193 
194 void QgsLayoutAtlas::setSortAscending( bool ascending )
195 {
196  if ( mSortAscending == ascending )
197  return;
198 
199  mSortAscending = ascending;
200  emit changed();
201 }
202 
203 void QgsLayoutAtlas::setSortExpression( const QString &expression )
204 {
205  if ( mSortExpression == expression )
206  return;
207 
208  mSortExpression = expression;
209  emit changed();
210 }
211 
213 {
214  if ( mFilterFeatures == filtered )
215  return;
216 
217  mFilterFeatures = filtered;
218  emit changed();
219 }
220 
221 bool QgsLayoutAtlas::setFilterExpression( const QString &expression, QString &errorString )
222 {
223  errorString.clear();
224  const bool hasChanged = mFilterExpression != expression;
225  mFilterExpression = expression;
226 
227  const QgsExpression filterExpression( mFilterExpression );
228  if ( hasChanged )
229  emit changed();
230  if ( filterExpression.hasParserError() )
231  {
232  errorString = filterExpression.parserErrorString();
233  return false;
234  }
235 
236  return true;
237 }
238 
239 
241 class AtlasFeatureSorter
242 {
243  public:
244  AtlasFeatureSorter( QgsLayoutAtlas::SorterKeys &keys, bool ascending = true )
245  : mKeys( keys )
246  , mAscending( ascending )
247  {}
248 
249  bool operator()( const QPair< QgsFeatureId, QString > &id1, const QPair< QgsFeatureId, QString > &id2 )
250  {
251  return mAscending ? qgsVariantLessThan( mKeys.value( id1.first ), mKeys.value( id2.first ) )
252  : qgsVariantGreaterThan( mKeys.value( id1.first ), mKeys.value( id2.first ) );
253  }
254 
255  private:
256  QgsLayoutAtlas::SorterKeys &mKeys;
257  bool mAscending;
258 };
259 
261 
263 {
264  mCurrentFeatureNo = -1;
265  if ( !mCoverageLayer )
266  {
267  return 0;
268  }
269 
270  QgsExpressionContext expressionContext = createExpressionContext();
271 
272  QString error;
273  updateFilenameExpression( error );
274 
275  // select all features with all attributes
276  QgsFeatureRequest req;
277 
278  req.setExpressionContext( expressionContext );
279 
280  mFilterParserError.clear();
281  if ( mFilterFeatures && !mFilterExpression.isEmpty() )
282  {
283  const QgsExpression filterExpression( mFilterExpression );
284  if ( filterExpression.hasParserError() )
285  {
286  mFilterParserError = filterExpression.parserErrorString();
287  return 0;
288  }
289 
290  //filter good to go
291  req.setFilterExpression( mFilterExpression );
292  }
293 
294 #ifdef HAVE_SERVER_PYTHON_PLUGINS
295  if ( mLayout->renderContext().featureFilterProvider() )
296  {
297  mLayout->renderContext().featureFilterProvider()->filterFeatures( mCoverageLayer.get(), req );
298  }
299 #endif
300 
301  QgsFeatureIterator fit = mCoverageLayer->getFeatures( req );
302 
303  std::unique_ptr<QgsExpression> nameExpression;
304  if ( !mPageNameExpression.isEmpty() )
305  {
306  nameExpression = std::make_unique< QgsExpression >( mPageNameExpression );
307  if ( nameExpression->hasParserError() )
308  {
309  nameExpression.reset( nullptr );
310  }
311  else
312  {
313  nameExpression->prepare( &expressionContext );
314  }
315  }
316 
317  // We cannot use nextFeature() directly since the feature pointer is rewinded by the rendering process
318  // We thus store the feature ids for future extraction
319  QgsFeature feat;
320  mFeatureIds.clear();
321  mFeatureKeys.clear();
322 
323  std::unique_ptr<QgsExpression> sortExpression;
324  if ( mSortFeatures && !mSortExpression.isEmpty() )
325  {
326  sortExpression = std::make_unique< QgsExpression >( mSortExpression );
327  if ( sortExpression->hasParserError() )
328  {
329  sortExpression.reset( nullptr );
330  }
331  else
332  {
333  sortExpression->prepare( &expressionContext );
334  }
335  }
336 
337  while ( fit.nextFeature( feat ) )
338  {
339  expressionContext.setFeature( feat );
340 
341  QString pageName;
342  if ( nameExpression )
343  {
344  const QVariant result = nameExpression->evaluate( &expressionContext );
345  if ( nameExpression->hasEvalError() )
346  {
347  QgsMessageLog::logMessage( tr( "Atlas name eval error: %1" ).arg( nameExpression->evalErrorString() ), tr( "Layout" ) );
348  }
349  pageName = result.toString();
350  }
351 
352  mFeatureIds.push_back( qMakePair( feat.id(), pageName ) );
353 
354  if ( sortExpression )
355  {
356  const QVariant result = sortExpression->evaluate( &expressionContext );
357  if ( sortExpression->hasEvalError() )
358  {
359  QgsMessageLog::logMessage( tr( "Atlas sort eval error: %1" ).arg( sortExpression->evalErrorString() ), tr( "Layout" ) );
360  }
361  mFeatureKeys.insert( feat.id(), result );
362  }
363  }
364 
365  // sort features, if asked for
366  if ( !mFeatureKeys.isEmpty() )
367  {
368  const AtlasFeatureSorter sorter( mFeatureKeys, mSortAscending );
369  std::sort( mFeatureIds.begin(), mFeatureIds.end(), sorter ); // clazy:exclude=detaching-member
370  }
371 
372  emit numberFeaturesChanged( mFeatureIds.size() );
373  return mFeatureIds.size();
374 }
375 
377 {
378  if ( !mCoverageLayer )
379  {
380  return false;
381  }
382 
383  emit renderBegun();
384 
385  if ( !updateFeatures() )
386  {
387  //no matching features found
388  return false;
389  }
390 
391  return true;
392 }
393 
395 {
396  emit featureChanged( QgsFeature() );
397  emit renderEnded();
398  return true;
399 }
400 
402 {
403  return mFeatureIds.size();
404 }
405 
406 QString QgsLayoutAtlas::filePath( const QString &baseFilePath, const QString &extension )
407 {
408  const QFileInfo fi( baseFilePath );
409  const QDir dir = fi.dir(); // ignore everything except the directory
410  QString base = dir.filePath( mCurrentFilename );
411  if ( !extension.startsWith( '.' ) )
412  base += '.';
413  base += extension;
414  return base;
415 }
416 
418 {
419  const int newFeatureNo = mCurrentFeatureNo + 1;
420  if ( newFeatureNo >= mFeatureIds.size() )
421  {
422  return false;
423  }
424 
425  return prepareForFeature( newFeatureNo );
426 }
427 
429 {
430  const int newFeatureNo = mCurrentFeatureNo - 1;
431  if ( newFeatureNo < 0 )
432  {
433  return false;
434  }
435 
436  return prepareForFeature( newFeatureNo );
437 }
438 
440 {
441  return prepareForFeature( 0 );
442 }
443 
445 {
446  return prepareForFeature( mFeatureIds.size() - 1 );
447 }
448 
449 bool QgsLayoutAtlas::seekTo( int feature )
450 {
451  return prepareForFeature( feature );
452 }
453 
454 bool QgsLayoutAtlas::seekTo( const QgsFeature &feature )
455 {
456  int i = -1;
457  auto it = mFeatureIds.constBegin();
458  for ( int currentIdx = 0; it != mFeatureIds.constEnd(); ++it, ++currentIdx )
459  {
460  if ( ( *it ).first == feature.id() )
461  {
462  i = currentIdx;
463  break;
464  }
465  }
466 
467  if ( i < 0 )
468  {
469  //feature not found
470  return false;
471  }
472 
473  return seekTo( i );
474 }
475 
477 {
478  prepareForFeature( mCurrentFeatureNo );
479 }
480 
482 {
483  mLayout->renderContext().setFlag( QgsLayoutRenderContext::FlagHideCoverageLayer, hide );
484  if ( hide == mHideCoverage )
485  return;
486 
487  mHideCoverage = hide;
488  mLayout->refresh();
489  emit changed();
490 }
491 
492 bool QgsLayoutAtlas::setFilenameExpression( const QString &pattern, QString &errorString )
493 {
494  const bool hasChanged = mFilenameExpressionString != pattern;
495  mFilenameExpressionString = pattern;
496 
497  if ( hasChanged )
498  emit changed();
499 
500  return updateFilenameExpression( errorString );
501 }
502 
504 {
505  return mCurrentFilename;
506 }
507 
509 {
510  QgsExpressionContext expressionContext;
511  expressionContext << QgsExpressionContextUtils::globalScope();
512  if ( mLayout )
513  expressionContext << QgsExpressionContextUtils::projectScope( mLayout->project() )
515 
516  expressionContext.appendScope( QgsExpressionContextUtils::atlasScope( this ) );
517 
518  if ( mCoverageLayer )
519  expressionContext.appendScope( mCoverageLayer->createExpressionContextScope() );
520 
521  if ( mLayout && mEnabled )
522  {
523  if ( mCurrentFeature.isValid() )
524  {
525  expressionContext.lastScope()->setFeature( mCurrentFeature );
526  }
527  else if ( mCoverageLayer ) // Create an empty feature for the expression validation
528  {
529  QgsFeature feature{ mCoverageLayer->fields() };
530  feature.setValid( true );
531  expressionContext.lastScope()->setFeature( feature );
532  }
533  }
534  return expressionContext;
535 }
536 
537 bool QgsLayoutAtlas::updateFilenameExpression( QString &error )
538 {
539  if ( !mCoverageLayer )
540  {
541  return false;
542  }
543 
544  const QgsExpressionContext expressionContext = createExpressionContext();
545  bool evalResult { true };
546 
547  if ( !mFilenameExpressionString.isEmpty() )
548  {
549  QgsExpression filenameExpression( mFilenameExpressionString );
550  // expression used to evaluate each filename
551  // test for evaluation errors
552  if ( filenameExpression.hasParserError() )
553  {
554  error = filenameExpression.parserErrorString();
555  return false;
556  }
557 
558  // prepare the filename expression
559  evalResult = filenameExpression.prepare( &expressionContext );
560  }
561 
562  // regenerate current filename
563  if ( evalResult )
564  {
565  evalResult = evalFeatureFilename( expressionContext );
566  }
567 
568  if ( ! evalResult )
569  {
570  error = mFilenameExpressionError;
571  }
572 
573  return evalResult;
574 }
575 
576 bool QgsLayoutAtlas::evalFeatureFilename( const QgsExpressionContext &context )
577 {
578  //generate filename for current atlas feature
579  mFilenameExpressionError.clear();
580  if ( !mFilenameExpressionString.isEmpty() )
581  {
582  QgsExpression filenameExpression( mFilenameExpressionString );
583  filenameExpression.prepare( &context );
584  const QVariant filenameRes = filenameExpression.evaluate( &context );
585  if ( filenameExpression.hasEvalError() )
586  {
587  mFilenameExpressionError = filenameExpression.evalErrorString();
588  QgsMessageLog::logMessage( tr( "Atlas filename evaluation error: %1" ).arg( filenameExpression.evalErrorString() ), tr( "Layout" ) );
589  return false;
590  }
591 
592  mCurrentFilename = filenameRes.toString();
593  }
594  return true;
595 }
596 
597 bool QgsLayoutAtlas::prepareForFeature( const int featureI )
598 {
599  if ( !mCoverageLayer )
600  {
601  return false;
602  }
603 
604  if ( mFeatureIds.isEmpty() )
605  {
606  emit messagePushed( tr( "No matching atlas features" ) );
607  return false;
608  }
609 
610  if ( featureI >= mFeatureIds.size() )
611  {
612  return false;
613  }
614 
615  mCurrentFeatureNo = featureI;
616 
617  // retrieve the next feature, based on its id
618  if ( !mCoverageLayer->getFeatures( QgsFeatureRequest().setFilterFid( mFeatureIds[ featureI ].first ) ).nextFeature( mCurrentFeature ) )
619  return false;
620 
621  mLayout->reportContext().blockSignals( true ); // setFeature emits changed, we don't want 2 signals
622  mLayout->reportContext().setLayer( mCoverageLayer.get() );
623  mLayout->reportContext().blockSignals( false );
624  mLayout->reportContext().setFeature( mCurrentFeature );
625 
626  // must come after we've set the report context feature, or the expression context will have an outdated atlas feature
627  const QgsExpressionContext expressionContext = createExpressionContext();
628 
629  // generate filename for current feature
630  if ( !evalFeatureFilename( expressionContext ) )
631  {
632  //error evaluating filename
633  return false;
634  }
635 
636  emit featureChanged( mCurrentFeature );
637  emit messagePushed( tr( "Atlas feature %1 of %2" ).arg( featureI + 1 ).arg( mFeatureIds.size() ) );
638 
639  return mCurrentFeature.isValid();
640 }
641 
QgsVectorLayer::getFeatures
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
Definition: qgsvectorlayer.cpp:1052
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:406
QgsExpressionContextScope::setFeature
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the scope.
Definition: qgsexpressioncontext.h:319
QgsLayoutAtlas::setPageNameExpression
void setPageNameExpression(const QString &expression)
Sets the expression (or field name) used for calculating the page name.
Definition: qgslayoutatlas.cpp:168
qgsexpressioncontextutils.h
QgsLayoutAtlas::messagePushed
void messagePushed(const QString &message)
Emitted when the atlas has an updated status bar message.
QgsVectorLayer::createExpressionContextScope
QgsExpressionContextScope * createExpressionContextScope() const FINAL
This method needs to be reimplemented in all classes which implement this interface and return an exp...
Definition: qgsvectorlayer.cpp:5208
QgsLayoutAtlas::featureChanged
void featureChanged(const QgsFeature &feature)
Emitted when the current atlas feature changes.
qgsfeaturerequest.h
QgsProject::layersWillBeRemoved
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the registry.
QgsLayoutAtlas::numberFeaturesChanged
void numberFeaturesChanged(int numFeatures)
Emitted when the number of features for the atlas changes.
_LayerRef::resolveWeakly
TYPE * resolveWeakly(const QgsProject *project, MatchType matchType=MatchType::All)
Resolves the map layer by attempting to find a matching layer in a project using a weak match.
Definition: qgsmaplayerref.h:211
QgsExpressionContextUtils::globalScope
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Definition: qgsexpressioncontextutils.cpp:40
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:34
QgsLayoutAtlas::sortExpression
QString sortExpression() const
Returns the expression (or field name) to use for sorting features.
Definition: qgslayoutatlas.h:190
qgsVariantLessThan
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
Definition: qgis.cpp:119
QgsLayoutAtlas::count
int count() const override
Returns the number of features to iterate over.
Definition: qgslayoutatlas.cpp:401
QgsExpressionContext::lastScope
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
Definition: qgsexpressioncontext.cpp:377
QgsLayoutAtlas::refreshCurrentFeature
void refreshCurrentFeature()
Refreshes the current atlas feature, by refetching its attributes from the vector layer provider.
Definition: qgslayoutatlas.cpp:476
qgsfeatureiterator.h
QgsLayoutAtlas::updateFeatures
int updateFeatures()
Requeries the current atlas coverage layer and applies filtering and sorting.
Definition: qgslayoutatlas.cpp:262
QgsLayoutAtlas::AtlasFeatureSorter
friend class AtlasFeatureSorter
Definition: qgslayoutatlas.h:397
QgsExpressionContextUtils::layoutScope
static QgsExpressionContextScope * layoutScope(const QgsLayout *layout)
Creates a new scope which contains variables and functions relating to a QgsLayout layout.
Definition: qgsexpressioncontextutils.cpp:556
QgsLayoutAtlas::QgsLayoutAtlas
QgsLayoutAtlas(QgsLayout *layout)
Constructor for new QgsLayoutAtlas.
Definition: qgslayoutatlas.cpp:29
QgsLayoutAtlas::setEnabled
void setEnabled(bool enabled)
Sets whether the atlas is enabled.
Definition: qgslayoutatlas.cpp:126
QgsLayoutAtlas::filePath
QString filePath(const QString &baseFilePath, const QString &extension) override
Returns the file path for the current feature, based on a specified base file path and extension.
Definition: qgslayoutatlas.cpp:406
QgsLayoutAtlas::changed
void changed()
Emitted when one of the atlas parameters changes.
QgsLayoutAtlas::filterExpression
QString filterExpression() const
Returns the expression used for filtering features in the coverage layer.
Definition: qgslayoutatlas.h:225
QgsLayoutAtlas::layout
QgsLayout * layout() override
Returns the layout associated with the iterator.
Definition: qgslayoutatlas.cpp:47
QgsProject
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:103
QgsLayoutAtlas::createExpressionContext
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
Definition: qgslayoutatlas.cpp:508
QgsFeatureRequest::setExpressionContext
QgsFeatureRequest & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate filter expressions.
Definition: qgsfeaturerequest.cpp:187
QgsFeatureRequest::setFilterExpression
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
Definition: qgsfeaturerequest.cpp:167
qgsVariantGreaterThan
bool qgsVariantGreaterThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is greater than the second.
Definition: qgis.cpp:187
_LayerRef::layerId
QString layerId
Original layer ID.
Definition: qgsmaplayerref.h:117
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3436
QgsFeature::id
QgsFeatureId id
Definition: qgsfeature.h:68
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:83
QgsExpressionContextUtils::projectScope
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
Definition: qgsexpressioncontextutils.cpp:291
QgsLayoutAtlas::last
bool last()
Seeks to the last feature, returning false if no feature was found.
Definition: qgslayoutatlas.cpp:444
_LayerRef::setLayer
void setLayer(TYPE *l)
Sets the reference to point to a specified layer.
Definition: qgsmaplayerref.h:78
QgsLayoutAtlas::enabled
bool enabled() const
Returns whether the atlas generation is enabled.
Definition: qgslayoutatlas.h:67
_LayerRef::provider
QString provider
Weak reference to layer provider.
Definition: qgsmaplayerref.h:124
QgsFeature::isValid
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:216
QgsLayoutAtlas::beginRender
bool beginRender() override
Called when rendering begins, before iteration commences.
Definition: qgslayoutatlas.cpp:376
QgsLayoutAtlas::seekTo
bool seekTo(int feature)
Seeks to the specified feature number.
Definition: qgslayoutatlas.cpp:449
_LayerRef::name
QString name
Weak reference to layer name.
Definition: qgsmaplayerref.h:122
QgsMessageLog::logMessage
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Definition: qgsmessagelog.cpp:27
QgsLayoutAtlas::first
bool first()
Seeks to the first feature, returning false if no feature was found.
Definition: qgslayoutatlas.cpp:439
QgsLayoutAtlas::renderBegun
void renderBegun()
Emitted when atlas rendering has begun.
QgsLayoutAtlas::endRender
bool endRender() override
Ends the render, performing any required cleanup tasks.
Definition: qgslayoutatlas.cpp:394
QgsLayoutAtlas::filenameExpression
QString filenameExpression() const
Returns the filename expression used for generating output filenames for each atlas page.
Definition: qgslayoutatlas.h:93
qgslayout.h
QgsLayoutAtlas::setSortAscending
void setSortAscending(bool ascending)
Sets whether features should be sorted in an ascending order.
Definition: qgslayoutatlas.cpp:194
QgsLayoutAtlas::setHideCoverage
void setHideCoverage(bool hide)
Sets whether the coverage layer should be hidden in map items in the layouts.
Definition: qgslayoutatlas.cpp:481
QgsExpressionContext::appendScope
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
Definition: qgsexpressioncontext.cpp:494
qgsvectorlayer.h
QgsLayoutAtlas::writeXml
bool writeXml(QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context) const override
Stores the objects's state in a DOM element.
Definition: qgslayoutatlas.cpp:57
QgsLayoutAtlas::stringType
QString stringType() const override
Returns the object type as a string.
Definition: qgslayoutatlas.cpp:42
QgsLayoutAtlas::coverageLayerChanged
void coverageLayerChanged(QgsVectorLayer *layer)
Emitted when the coverage layer for the atlas changes.
QgsLayoutAtlas::previous
bool previous()
Iterates to the previous feature, returning false if no previous feature exists.
Definition: qgslayoutatlas.cpp:428
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:399
QgsLayoutAtlas::setSortExpression
void setSortExpression(const QString &expression)
Sets the expression (or field name) to use for sorting features.
Definition: qgslayoutatlas.cpp:203
QgsLayoutAtlas::currentFilename
QString currentFilename() const
Returns the current feature filename.
Definition: qgslayoutatlas.cpp:503
QgsLayout
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition: qgslayout.h:50
_LayerRef::source
QString source
Weak reference to layer public source.
Definition: qgsmaplayerref.h:120
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsLayoutAtlas::renderEnded
void renderEnded()
Emitted when atlas rendering has ended.
QgsLayoutAtlas::toggled
void toggled(bool)
Emitted when atlas is enabled or disabled.
QgsLayoutAtlas::readXml
bool readXml(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context) override
Sets the objects's state from a DOM element.
Definition: qgslayoutatlas.cpp:95
QgsLayoutAtlas::setCoverageLayer
void setCoverageLayer(QgsVectorLayer *layer)
Sets the coverage layer to use for the atlas features.
Definition: qgslayoutatlas.cpp:157
QgsExpressionContextUtils::atlasScope
static QgsExpressionContextScope * atlasScope(const QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
Definition: qgsexpressioncontextutils.cpp:660
QgsVectorLayerRef
_LayerRef< QgsVectorLayer > QgsVectorLayerRef
Definition: qgsvectorlayerref.h:23
QgsLayoutAtlas::next
bool next() override
Definition: qgslayoutatlas.cpp:417
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
QgsLayoutAtlas::setFilterExpression
bool setFilterExpression(const QString &expression, QString &errorString)
Sets the expression used for filtering features in the coverage layer.
Definition: qgslayoutatlas.cpp:221
QgsExpression
Class for parsing and evaluation of expressions (formerly called "search strings")....
Definition: qgsexpression.h:102
QgsLayoutAtlas::setFilterFeatures
void setFilterFeatures(bool filtered)
Sets whether features should be filtered in the coverage layer.
Definition: qgslayoutatlas.cpp:212
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:289
QgsLayoutAtlas::setSortFeatures
void setSortFeatures(bool enabled)
Sets whether features should be sorted in the atlas.
Definition: qgslayoutatlas.cpp:185
QgsLayoutAtlas::setFilenameExpression
bool setFilenameExpression(const QString &expression, QString &errorString)
Sets the filename expression used for generating output filenames for each atlas page.
Definition: qgslayoutatlas.cpp:492
_LayerRef::get
TYPE * get() const
Returns a pointer to the layer, or nullptr if the reference has not yet been matched to a layer.
Definition: qgsmaplayerref.h:108
qgsmessagelog.h
QgsLayoutRenderContext::FlagHideCoverageLayer
@ FlagHideCoverageLayer
Hide coverage layer in outputs.
Definition: qgslayoutrendercontext.h:51
QgsExpressionContext::setFeature
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Definition: qgsexpressioncontext.cpp:525
qgslayoutatlas.h
QgsLayoutAtlas::nameForPage
QString nameForPage(int page) const
Returns the calculated name for a specified atlas page number.
Definition: qgslayoutatlas.cpp:177