28
28
#include " qgsproject.h"
29
29
#include " qgsmessagelog.h"
30
30
31
- QgsAtlasComposition::QgsAtlasComposition ( QgsComposition* composition ) :
32
- mComposition( composition ),
33
- mEnabled( false ),
34
- mHideCoverage( false ), mFilenamePattern( " 'output_'||$feature" ),
35
- mCoverageLayer( 0 ), mSingleFile( false ),
36
- mSortFeatures( false ), mSortAscending( true ), mCurrentFeatureNo( 0 ),
37
- mFilterFeatures( false ), mFeatureFilter( " " ),
38
- mFilenameParserError( QString() ),
39
- mFilterParserError( QString() )
31
+ QgsAtlasComposition::QgsAtlasComposition ( QgsComposition* composition )
32
+ : mComposition( composition )
33
+ , mEnabled( false )
34
+ , mHideCoverage( false )
35
+ , mFilenamePattern( " 'output_'||$feature" )
36
+ , mCoverageLayer( 0 )
37
+ , mSingleFile( false )
38
+ , mSortFeatures( false )
39
+ , mSortAscending( true )
40
+ , mCurrentFeatureNo( 0 )
41
+ , mFilterFeatures( false )
40
42
{
41
43
42
44
// declare special columns with a default value
@@ -113,6 +115,14 @@ void QgsAtlasComposition::setCoverageLayer( QgsVectorLayer* layer )
113
115
emit coverageLayerChanged ( layer );
114
116
}
115
117
118
+ QString QgsAtlasComposition::nameForPage ( int pageNumber ) const
119
+ {
120
+ if ( pageNumber < 0 || pageNumber >= mFeatureIds .count () )
121
+ return QString ();
122
+
123
+ return mFeatureIds .at ( pageNumber ).second ;
124
+ }
125
+
116
126
QgsComposerMap* QgsAtlasComposition::composerMap () const
117
127
{
118
128
// deprecated method. Until removed just return the first atlas-enabled composer map
@@ -175,21 +185,21 @@ class FieldSorter
175
185
public:
176
186
FieldSorter ( QgsAtlasComposition::SorterKeys& keys, bool ascending = true ) : mKeys ( keys ), mAscending ( ascending ) {}
177
187
178
- bool operator ()( const QgsFeatureId& id1, const QgsFeatureId& id2 )
188
+ bool operator ()( const QPair< QgsFeatureId, QString > & id1, const QPair< QgsFeatureId, QString > & id2 )
179
189
{
180
190
bool result = true ;
181
191
182
- if ( mKeys [ id1 ].type () == QVariant::Int )
192
+ if ( mKeys [ id1. first ].type () == QVariant::Int )
183
193
{
184
- result = mKeys [ id1 ].toInt () < mKeys [ id2 ].toInt ();
194
+ result = mKeys [ id1. first ].toInt () < mKeys [ id2. first ].toInt ();
185
195
}
186
- else if ( mKeys [ id1 ].type () == QVariant::Double )
196
+ else if ( mKeys [ id1. first ].type () == QVariant::Double )
187
197
{
188
- result = mKeys [ id1 ].toDouble () < mKeys [ id2 ].toDouble ();
198
+ result = mKeys [ id1. first ].toDouble () < mKeys [ id2. first ].toDouble ();
189
199
}
190
- else if ( mKeys [ id1 ].type () == QVariant::String )
200
+ else if ( mKeys [ id1. first ].type () == QVariant::String )
191
201
{
192
- result = ( QString::localeAwareCompare ( mKeys [ id1 ].toString (), mKeys [ id2 ].toString () ) < 0 );
202
+ result = ( QString::localeAwareCompare ( mKeys [ id1. first ].toString (), mKeys [ id2. first ].toString () ) < 0 );
193
203
}
194
204
195
205
return mAscending ? result : !result;
@@ -225,14 +235,37 @@ int QgsAtlasComposition::updateFeatures()
225
235
}
226
236
mFilterParserError = QString ();
227
237
238
+ QScopedPointer<QgsExpression> nameExpression;
239
+ if ( !mPageNameExpression .isEmpty () )
240
+ {
241
+ nameExpression.reset ( new QgsExpression ( mPageNameExpression ) );
242
+ if ( nameExpression->hasParserError () )
243
+ {
244
+ nameExpression.reset ( 0 );
245
+ }
246
+ nameExpression->prepare ( mCoverageLayer ->pendingFields () );
247
+ }
248
+
228
249
// We cannot use nextFeature() directly since the feature pointer is rewinded by the rendering process
229
250
// We thus store the feature ids for future extraction
230
251
QgsFeature feat;
231
252
mFeatureIds .clear ();
232
253
mFeatureKeys .clear ();
233
254
int sortIdx = mCoverageLayer ->fieldNameIndex ( mSortKeyAttributeName );
255
+
234
256
while ( fit.nextFeature ( feat ) )
235
257
{
258
+ QString pageName;
259
+ if ( !nameExpression.isNull () )
260
+ {
261
+ QVariant result = nameExpression->evaluate ( &feat, mCoverageLayer ->pendingFields () );
262
+ if ( nameExpression->hasEvalError () )
263
+ {
264
+ QgsMessageLog::logMessage ( tr ( " Atlas name eval error: %1" ).arg ( nameExpression->evalErrorString () ), tr ( " Composer" ) );
265
+ }
266
+ pageName = result.toString ();
267
+ }
268
+
236
269
if ( !filterExpression.isNull () )
237
270
{
238
271
QVariant result = filterExpression->evaluate ( &feat, mCoverageLayer ->pendingFields () );
@@ -247,7 +280,8 @@ int QgsAtlasComposition::updateFeatures()
247
280
continue ;
248
281
}
249
282
}
250
- mFeatureIds .push_back ( feat.id () );
283
+
284
+ mFeatureIds .push_back ( qMakePair ( feat.id (), pageName ) );
251
285
252
286
if ( mSortFeatures && sortIdx != -1 )
253
287
{
@@ -369,7 +403,18 @@ void QgsAtlasComposition::lastFeature()
369
403
370
404
bool QgsAtlasComposition::prepareForFeature ( const QgsFeature * feat )
371
405
{
372
- int featureI = mFeatureIds .indexOf ( feat->id () );
406
+ int featureI = -1 ;
407
+ QVector< QPair<QgsFeatureId, QString> >::const_iterator it = mFeatureIds .constBegin ();
408
+ int currentIdx = 0 ;
409
+ for ( ; it != mFeatureIds .constEnd (); ++it, ++currentIdx )
410
+ {
411
+ if (( *it ).first == feat->id () )
412
+ {
413
+ featureI = currentIdx;
414
+ break ;
415
+ }
416
+ }
417
+
373
418
if ( featureI < 0 )
374
419
{
375
420
// feature not found
@@ -405,7 +450,7 @@ bool QgsAtlasComposition::prepareForFeature( const int featureI, const bool upda
405
450
mCurrentFeatureNo = featureI;
406
451
407
452
// retrieve the next feature, based on its id
408
- mCoverageLayer ->getFeatures ( QgsFeatureRequest ().setFilterFid ( mFeatureIds [ featureI ] ) ).nextFeature ( mCurrentFeature );
453
+ mCoverageLayer ->getFeatures ( QgsFeatureRequest ().setFilterFid ( mFeatureIds [ featureI ]. first ) ).nextFeature ( mCurrentFeature );
409
454
410
455
QgsExpression::setSpecialColumn ( " $atlasfeatureid" , mCurrentFeature .id () );
411
456
QgsExpression::setSpecialColumn ( " $atlasgeometry" , QVariant::fromValue ( *mCurrentFeature .constGeometry () ) );
@@ -655,6 +700,7 @@ void QgsAtlasComposition::writeXML( QDomElement& elem, QDomDocument& doc ) const
655
700
atlasElem.setAttribute ( " hideCoverage" , mHideCoverage ? " true" : " false" );
656
701
atlasElem.setAttribute ( " singleFile" , mSingleFile ? " true" : " false" );
657
702
atlasElem.setAttribute ( " filenamePattern" , mFilenamePattern );
703
+ atlasElem.setAttribute ( " pageNameExpression" , mPageNameExpression );
658
704
659
705
atlasElem.setAttribute ( " sortFeatures" , mSortFeatures ? " true" : " false" );
660
706
if ( mSortFeatures )
@@ -693,6 +739,7 @@ void QgsAtlasComposition::readXML( const QDomElement& atlasElem, const QDomDocum
693
739
}
694
740
}
695
741
742
+ mPageNameExpression = atlasElem.attribute ( " pageNameExpression" , QString () );
696
743
mSingleFile = atlasElem.attribute ( " singleFile" , " false" ) == " true" ? true : false ;
697
744
mFilenamePattern = atlasElem.attribute ( " filenamePattern" , " " );
698
745
0 commit comments