18 #include <QtAlgorithms>
32 mComposition( composition ),
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() )
61 if ( enabled == mEnabled )
72 void QgsAtlasComposition::removeLayers( QStringList layers )
74 if ( !mCoverageLayer )
79 foreach ( QString layerId, layers )
81 if ( layerId == mCoverageLayer->
id() )
93 if ( layer == mCoverageLayer )
98 mCoverageLayer = layer;
110 QgsExpression::setSpecialColumn(
"$atlasfeature", QVariant::fromValue( fet ) );
121 QList<QgsComposerMap*> maps;
123 for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
150 if ( !mCoverageLayer )
159 if ( mCoverageLayer )
162 if ( idx >= 0 && idx < fields.
count() )
164 mSortKeyAttributeName = fields[idx].name();
168 mSortKeyAttributeName =
"";
182 if ( mKeys[ id1 ].type() == QVariant::Int )
184 result = mKeys[ id1 ].toInt() < mKeys[ id2 ].toInt();
186 else if ( mKeys[ id1 ].type() == QVariant::Double )
188 result = mKeys[ id1 ].toDouble() < mKeys[ id2 ].toDouble();
190 else if ( mKeys[ id1 ].type() == QVariant::String )
192 result = ( QString::localeAwareCompare( mKeys[ id1 ].toString(), mKeys[ id2 ].toString() ) < 0 );
195 return mAscending ? result : !result;
206 if ( !mCoverageLayer )
211 updateFilenameExpression();
216 QScopedPointer<QgsExpression> filterExpression;
217 if ( mFilterFeatures && !mFeatureFilter.isEmpty() )
219 filterExpression.reset(
new QgsExpression( mFeatureFilter ) );
220 if ( filterExpression->hasParserError() )
222 mFilterParserError = filterExpression->parserErrorString();
226 mFilterParserError = QString();
232 mFeatureKeys.clear();
233 int sortIdx = mCoverageLayer->
fieldNameIndex( mSortKeyAttributeName );
236 if ( !filterExpression.isNull() )
238 QVariant result = filterExpression->evaluate( &feat, mCoverageLayer->
pendingFields() );
239 if ( filterExpression->hasEvalError() )
245 if ( !result.toBool() )
250 mFeatureIds.push_back( feat.
id() );
252 if ( mSortFeatures && sortIdx != -1 )
254 mFeatureKeys.insert( feat.
id(), feat.
attributes()[ sortIdx ] );
259 if ( mFeatureKeys.count() )
261 FieldSorter sorter( mFeatureKeys, mSortAscending );
262 qSort( mFeatureIds.begin(), mFeatureIds.end(), sorter );
274 return mFeatureIds.size();
280 if ( !mCoverageLayer )
288 if ( !featuresUpdated )
303 if ( !mCoverageLayer )
315 void QgsAtlasComposition::updateAtlasMaps()
318 QList<QgsComposerMap*> maps;
320 for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
334 return mFeatureIds.size();
339 int newFeatureNo = mCurrentFeatureNo + 1;
340 if ( newFeatureNo >= mFeatureIds.size() )
342 newFeatureNo = mFeatureIds.size() - 1;
350 int newFeatureNo = mCurrentFeatureNo - 1;
351 if ( newFeatureNo < 0 )
371 int featureI = mFeatureIds.indexOf( feat->
id() );
388 if ( !mCoverageLayer )
393 if ( mFeatureIds.size() == 0 )
399 mCurrentFeatureNo = featureI;
406 QgsExpression::setSpecialColumn(
"$atlasfeature", QVariant::fromValue( mCurrentFeature ) );
407 QgsExpression::setSpecialColumn(
"$feature", QVariant((
int )featureI + 1 ) );
410 if ( !evalFeatureFilename() )
417 emit
statusMsgChanged( QString(
tr(
"Atlas feature %1 of %2" ) ).arg( featureI + 1 ).arg( mFeatureIds.size() ) );
419 if ( !mCurrentFeature.
isValid() )
434 QList<QgsComposerMap*> maps;
435 QList<QgsComposerMap*> atlasMaps;
437 if ( maps.isEmpty() )
441 for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
448 atlasMaps << currentMap;
451 if ( atlasMaps.count() > 0 )
459 computeExtent( atlasMaps[0] );
462 for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
464 if (( *mit )->atlasDriven() )
495 mTransformedFeatureBounds = tgeom.boundingBox();
505 if ( mTransformedFeatureBounds.
isEmpty() )
509 computeExtent( map );
512 double xa1 = mTransformedFeatureBounds.
xMinimum();
513 double xa2 = mTransformedFeatureBounds.
xMaximum();
514 double ya1 = mTransformedFeatureBounds.
yMinimum();
515 double ya2 = mTransformedFeatureBounds.
yMaximum();
520 bool isPointLayer =
false;
521 switch ( mCoverageLayer->
wkbType() )
530 isPointLayer =
false;
539 double originalScale = calc.
calculate( mOrigExtent, map->rect().width() );
540 double geomCenterX = ( xa1 + xa2 ) / 2.0;
541 double geomCenterY = ( ya1 + ya2 ) / 2.0;
546 double xMin = geomCenterX - mOrigExtent.width() / 2.0;
547 double yMin = geomCenterY - mOrigExtent.height() / 2.0;
550 xMin + mOrigExtent.width(),
551 yMin + mOrigExtent.height() );
555 double newScale = calc.
calculate( newExtent, map->rect().width() );
556 newExtent.
scale( originalScale / newScale );
561 double newWidth = mOrigExtent.width();
562 double newHeight = mOrigExtent.height();
563 const QVector<qreal>& scales = mPredefinedScales;
564 for (
int i = 0; i < scales.size(); i++ )
566 double ratio = scales[i] / originalScale;
567 newWidth = mOrigExtent.width() * ratio;
568 newHeight = mOrigExtent.height() * ratio;
571 double xMin = geomCenterX - newWidth / 2.0;
572 double yMin = geomCenterY - newHeight / 2.0;
580 double newScale = calc.
calculate( newExtent, map->rect().width() );
581 newExtent.
scale( scales[i] / newScale );
583 if (( newExtent.
width() >= mTransformedFeatureBounds.
width() ) && ( newExtent.
height() >= mTransformedFeatureBounds.
height() ) )
595 double geomRatio = mTransformedFeatureBounds.
width() / mTransformedFeatureBounds.
height();
596 double mapRatio = mOrigExtent.width() / mOrigExtent.height();
599 if ( geomRatio < mapRatio )
602 double adjWidth = ( mapRatio * mTransformedFeatureBounds.
height() - mTransformedFeatureBounds.
width() ) / 2.0;
607 else if ( geomRatio > mapRatio )
610 double adjHeight = ( mTransformedFeatureBounds.
width() / mapRatio - mTransformedFeatureBounds.
height() ) / 2.0;
628 return mCurrentFilename;
633 QDomElement atlasElem = doc.createElement(
"Atlas" );
634 atlasElem.setAttribute(
"enabled", mEnabled ?
"true" :
"false" );
640 if ( mCoverageLayer )
642 atlasElem.setAttribute(
"coverageLayer", mCoverageLayer->
id() );
646 atlasElem.setAttribute(
"coverageLayer",
"" );
649 atlasElem.setAttribute(
"hideCoverage", mHideCoverage ?
"true" :
"false" );
650 atlasElem.setAttribute(
"singleFile", mSingleFile ?
"true" :
"false" );
651 atlasElem.setAttribute(
"filenamePattern", mFilenamePattern );
653 atlasElem.setAttribute(
"sortFeatures", mSortFeatures ?
"true" :
"false" );
656 atlasElem.setAttribute(
"sortKey", mSortKeyAttributeName );
657 atlasElem.setAttribute(
"sortAscending", mSortAscending ?
"true" :
"false" );
659 atlasElem.setAttribute(
"filterFeatures", mFilterFeatures ?
"true" :
"false" );
660 if ( mFilterFeatures )
662 atlasElem.setAttribute(
"featureFilter", mFeatureFilter );
665 elem.appendChild( atlasElem );
670 mEnabled = atlasElem.attribute(
"enabled",
"false" ) ==
"true" ?
true :
false;
681 for ( QMap<QString, QgsMapLayer*>::const_iterator it = layers.begin(); it != layers.end(); ++it )
683 if ( it.key() == atlasElem.attribute(
"coverageLayer" ) )
690 mSingleFile = atlasElem.attribute(
"singleFile",
"false" ) ==
"true" ?
true :
false;
691 mFilenamePattern = atlasElem.attribute(
"filenamePattern",
"" );
693 mSortFeatures = atlasElem.attribute(
"sortFeatures",
"false" ) ==
"true" ?
true :
false;
696 mSortKeyAttributeName = atlasElem.attribute(
"sortKey",
"" );
701 int idx = mSortKeyAttributeName.toInt( &isIndex );
702 if ( isIndex && mCoverageLayer )
705 if ( idx >= 0 && idx < fields.
count() )
707 mSortKeyAttributeName = fields[idx].name();
710 mSortAscending = atlasElem.attribute(
"sortAscending",
"true" ) ==
"true" ?
true :
false;
712 mFilterFeatures = atlasElem.attribute(
"filterFeatures",
"false" ) ==
"true" ?
true :
false;
713 if ( mFilterFeatures )
715 mFeatureFilter = atlasElem.attribute(
"featureFilter",
"" );
718 mHideCoverage = atlasElem.attribute(
"hideCoverage",
"false" ) ==
"true" ?
true :
false;
727 int composerMapNo = elem.attribute(
"composerMap",
"-1" ).toInt();
729 if ( composerMapNo != -1 )
731 QList<QgsComposerMap*> maps;
733 for ( QList<QgsComposerMap*>::iterator it = maps.begin(); it != maps.end(); ++it )
735 if (( *it )->id() == composerMapNo )
737 composerMap = ( *it );
745 double margin = elem.attribute(
"margin",
"0.0" ).toDouble();
746 if ( composerMap && margin != 0 )
750 bool fixedScale = elem.attribute(
"fixedScale",
"false" ) ==
"true" ?
true :
false;
751 if ( composerMap && fixedScale )
759 mHideCoverage = hide;
765 mComposition->update();
772 mFilenamePattern = pattern;
773 return updateFilenameExpression();
776 bool QgsAtlasComposition::updateFilenameExpression()
778 if ( !mCoverageLayer )
785 if ( mFilenamePattern.size() > 0 )
787 mFilenameExpr.reset(
new QgsExpression( mFilenamePattern ) );
790 if ( mFilenameExpr->hasParserError() )
792 mFilenameParserError = mFilenameExpr->parserErrorString();
797 mFilenameExpr->prepare( fields );
803 evalFeatureFilename();
808 bool QgsAtlasComposition::evalFeatureFilename()
811 if ( mFilenamePattern.size() > 0 && !mFilenameExpr.isNull() )
813 QVariant filenameRes = mFilenameExpr->evaluate( &mCurrentFeature, mCoverageLayer->
pendingFields() );
814 if ( mFilenameExpr->hasEvalError() )
820 mCurrentFilename = filenameRes.toString();
827 mPredefinedScales = scales;
829 qSort( mPredefinedScales.begin(), mPredefinedScales.end() );