18 #include <QtAlgorithms>
33 : mComposition( composition )
35 , mHideCoverage( false )
36 , mFilenamePattern(
"'output_'||@atlas_featurenumber" )
38 , mSingleFile( false )
39 , mSortFeatures( false )
40 , mSortAscending( true )
41 , mCurrentFeatureNo( 0 )
42 , mFilterFeatures( false )
55 if ( enabled == mEnabled )
66 void QgsAtlasComposition::removeLayers(
const QStringList& layers )
68 if ( !mCoverageLayer )
73 Q_FOREACH (
const QString& layerId, layers )
75 if ( layerId == mCoverageLayer->
id() )
87 if ( layer == mCoverageLayer )
92 mCoverageLayer = layer;
98 if ( pageNumber < 0 || pageNumber >= mFeatureIds.
count() )
101 return mFeatureIds.
at( pageNumber ).second;
138 if ( !mCoverageLayer )
147 if ( mCoverageLayer )
150 if ( idx >= 0 && idx < fields.
count() )
152 mSortKeyAttributeName = fields[idx].name();
156 mSortKeyAttributeName =
"";
170 if ( mKeys[ id1.first ].type() == QVariant::Int )
172 result = mKeys[ id1.first ].toInt() < mKeys[ id2.first ].toInt();
174 else if ( mKeys[ id1.first ].type() == QVariant::Double )
176 result = mKeys[ id1.first ].toDouble() < mKeys[ id2.first ].toDouble();
178 else if ( mKeys[ id1.first ].type() == QVariant::String )
183 return mAscending ? result : !result;
194 if ( !mCoverageLayer )
201 updateFilenameExpression();
207 if ( mFilterFeatures && !mFeatureFilter.
isEmpty() )
210 if ( filterExpression->hasParserError() )
212 mFilterParserError = filterExpression->parserErrorString();
219 mFilterParserError =
QString();
224 if ( !mPageNameExpression.
isEmpty() )
227 if ( nameExpression->hasParserError() )
229 nameExpression.
reset( 0 );
231 nameExpression->prepare( &expressionContext );
238 mFeatureKeys.
clear();
239 int sortIdx = mCoverageLayer->
fieldNameIndex( mSortKeyAttributeName );
246 if ( !nameExpression.
isNull() )
248 QVariant result = nameExpression->evaluate( &expressionContext );
249 if ( nameExpression->hasEvalError() )
256 mFeatureIds.
push_back( qMakePair( feat.
id(), pageName ) );
258 if ( mSortFeatures && sortIdx != -1 )
265 if ( mFeatureKeys.
count() )
267 FieldSorter sorter( mFeatureKeys, mSortAscending );
268 qSort( mFeatureIds.
begin(), mFeatureIds.
end(), sorter );
280 return mFeatureIds.
size();
290 if ( !mCoverageLayer )
298 if ( !featuresUpdated )
309 if ( !mCoverageLayer )
321 void QgsAtlasComposition::updateAtlasMaps()
340 return mFeatureIds.
size();
345 int newFeatureNo = mCurrentFeatureNo + 1;
346 if ( newFeatureNo >= mFeatureIds.
size() )
348 newFeatureNo = mFeatureIds.
size() - 1;
356 int newFeatureNo = mCurrentFeatureNo - 1;
357 if ( newFeatureNo < 0 )
380 for ( ; it != mFeatureIds.
constEnd(); ++it, ++currentIdx )
382 if (( *it ).first == feat->
id() )
384 featureI = currentIdx;
405 if ( !mCoverageLayer )
410 if ( mFeatureIds.
size() == 0 )
416 if ( featureI >= mFeatureIds.
size() )
421 mCurrentFeatureNo = featureI;
429 if ( !evalFeatureFilename( expressionContext ) )
438 if ( !mCurrentFeature.
isValid() )
467 atlasMaps << currentMap;
470 if ( atlasMaps.
count() > 0 )
478 computeExtent( atlasMaps[0] );
483 if (( *mit )->atlasDriven() )
516 mTransformedFeatureBounds = tgeom.boundingBox();
526 if ( mTransformedFeatureBounds.
isEmpty() )
530 computeExtent( map );
533 double xa1 = mTransformedFeatureBounds.
xMinimum();
534 double xa2 = mTransformedFeatureBounds.
xMaximum();
535 double ya1 = mTransformedFeatureBounds.
yMinimum();
536 double ya2 = mTransformedFeatureBounds.
yMaximum();
541 bool isPointLayer =
false;
542 switch ( mCoverageLayer->
wkbType() )
551 isPointLayer =
false;
561 double geomCenterX = ( xa1 + xa2 ) / 2.0;
562 double geomCenterY = ( ya1 + ya2 ) / 2.0;
567 double xMin = geomCenterX - mOrigExtent.width() / 2.0;
568 double yMin = geomCenterY - mOrigExtent.height() / 2.0;
571 xMin + mOrigExtent.width(),
572 yMin + mOrigExtent.height() );
577 newExtent.
scale( originalScale / newScale );
582 double newWidth = mOrigExtent.width();
583 double newHeight = mOrigExtent.height();
585 for (
int i = 0; i < scales.
size(); i++ )
587 double ratio = scales[i] / originalScale;
588 newWidth = mOrigExtent.width() * ratio;
589 newHeight = mOrigExtent.height() * ratio;
592 double xMin = geomCenterX - newWidth / 2.0;
593 double yMin = geomCenterY - newHeight / 2.0;
602 newExtent.
scale( scales[i] / newScale );
604 if (( newExtent.
width() >= mTransformedFeatureBounds.
width() ) && ( newExtent.
height() >= mTransformedFeatureBounds.
height() ) )
616 double geomRatio = mTransformedFeatureBounds.
width() / mTransformedFeatureBounds.
height();
617 double mapRatio = mOrigExtent.width() / mOrigExtent.height();
620 if ( geomRatio < mapRatio )
623 double adjWidth = ( mapRatio * mTransformedFeatureBounds.
height() - mTransformedFeatureBounds.
width() ) / 2.0;
628 else if ( geomRatio > mapRatio )
631 double adjHeight = ( mTransformedFeatureBounds.
width() / mapRatio - mTransformedFeatureBounds.
height() ) / 2.0;
649 return mCurrentFilename;
655 atlasElem.
setAttribute(
"enabled", mEnabled ?
"true" :
"false" );
661 if ( mCoverageLayer )
670 atlasElem.
setAttribute(
"hideCoverage", mHideCoverage ?
"true" :
"false" );
671 atlasElem.
setAttribute(
"singleFile", mSingleFile ?
"true" :
"false" );
672 atlasElem.
setAttribute(
"filenamePattern", mFilenamePattern );
673 atlasElem.
setAttribute(
"pageNameExpression", mPageNameExpression );
675 atlasElem.
setAttribute(
"sortFeatures", mSortFeatures ?
"true" :
"false" );
678 atlasElem.
setAttribute(
"sortKey", mSortKeyAttributeName );
679 atlasElem.
setAttribute(
"sortAscending", mSortAscending ?
"true" :
"false" );
681 atlasElem.
setAttribute(
"filterFeatures", mFilterFeatures ?
"true" :
"false" );
682 if ( mFilterFeatures )
684 atlasElem.
setAttribute(
"featureFilter", mFeatureFilter );
692 mEnabled = atlasElem.
attribute(
"enabled",
"false" ) ==
"true" ?
true :
false;
705 if ( it.key() == atlasElem.
attribute(
"coverageLayer" ) )
712 mPageNameExpression = atlasElem.
attribute(
"pageNameExpression",
QString() );
713 mSingleFile = atlasElem.
attribute(
"singleFile",
"false" ) ==
"true" ?
true :
false;
714 mFilenamePattern = atlasElem.
attribute(
"filenamePattern",
"" );
716 mSortFeatures = atlasElem.
attribute(
"sortFeatures",
"false" ) ==
"true" ?
true :
false;
719 mSortKeyAttributeName = atlasElem.
attribute(
"sortKey",
"" );
724 int idx = mSortKeyAttributeName.
toInt( &isIndex );
725 if ( isIndex && mCoverageLayer )
728 if ( idx >= 0 && idx < fields.
count() )
730 mSortKeyAttributeName = fields[idx].name();
733 mSortAscending = atlasElem.
attribute(
"sortAscending",
"true" ) ==
"true" ?
true :
false;
735 mFilterFeatures = atlasElem.
attribute(
"filterFeatures",
"false" ) ==
"true" ?
true :
false;
736 if ( mFilterFeatures )
738 mFeatureFilter = atlasElem.
attribute(
"featureFilter",
"" );
741 mHideCoverage = atlasElem.
attribute(
"hideCoverage",
"false" ) ==
"true" ?
true :
false;
750 int composerMapNo = elem.
attribute(
"composerMap",
"-1" ).
toInt();
752 if ( composerMapNo != -1 )
758 if (( *it )->id() == composerMapNo )
760 composerMap = ( *it );
769 if ( composerMap && margin != 0 )
774 if ( composerMap && fixedScale )
782 mHideCoverage = hide;
795 mFilenamePattern = pattern;
796 return updateFilenameExpression();
808 if ( mCoverageLayer )
813 return expressionContext;
816 bool QgsAtlasComposition::updateFilenameExpression()
818 if ( !mCoverageLayer )
825 if ( mFilenamePattern.
size() > 0 )
830 if ( mFilenameExpr->hasParserError() )
832 mFilenameParserError = mFilenameExpr->parserErrorString();
837 mFilenameExpr->prepare( &expressionContext );
843 evalFeatureFilename( expressionContext );
851 if ( mFilenamePattern.
size() > 0 && !mFilenameExpr.
isNull() )
853 QVariant filenameRes = mFilenameExpr->evaluate( &context );
854 if ( mFilenameExpr->hasEvalError() )
860 mCurrentFilename = filenameRes.
toString();
867 mPredefinedScales = scales;
869 qSort( mPredefinedScales.
begin(), mPredefinedScales.
end() );
bool prepareForFeature(const int i, const bool updateMaps=true)
Prepare the atlas map for the given feature.
QgsFeatureId id() const
Get the feature ID for this feature.
Class for parsing and evaluation of expressions (formerly called "search strings").
void setMapUnits(QGis::UnitType mapUnits)
Set the map units.
Wrapper for iterator of features from vector data provider or vector layer.
QgsComposition::AtlasMode atlasMode() const
Returns the current atlas mode of the composition.
A rectangle specified with double values.
bool isEmpty() const
test if rectangle is empty.
void renderEnded()
Is emitted when atlas rendering has ended.
double atlasMargin(const QgsComposerObject::PropertyValueType valueType=QgsComposerObject::EvaluatedValue)
Returns the margin size (percentage) used when the map is in atlas mode.
Q_DECL_DEPRECATED int sortKeyAttributeIndex() const
int localeAwareCompare(const QString &other) const
bool isValid() const
Returns the validity of this feature.
QDomNode appendChild(const QDomNode &newChild)
static QgsExpressionContextScope * atlasScope(const QgsAtlasComposition *atlas)
Creates a new scope which contains variables and functions relating to a QgsAtlasComposition.
void setNewAtlasFeatureExtent(const QgsRectangle &extent)
Sets new Extent for the current atlas preview and changes width, height (and implicitely also scale)...
QgsAtlasComposition(QgsComposition *composition)
QString attribute(const QString &name, const QString &defValue) const
double yMaximum() const
Get the y maximum value (top side of rectangle)
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
QgsFields fields() const
Returns the list of fields of this layer.
Q_DECL_DEPRECATED bool fixedScale() const
Returns whether the atlas map uses a fixed scale.
const QgsMapSettings & mapSettings() const
Return setting of QGIS map canvas.
QString nameForPage(int pageNumber) const
Returns the calculated name for a specified atlas page number.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
void cache()
Create cache image.
const_iterator constEnd() const
#define Q_NOWARN_DEPRECATED_PUSH
void setDpi(double dpi)
Set the dpi to be used in scale calculations.
QgsComposition * composition()
bool enabled() const
Returns whether the atlas generation is enabled.
Container of fields for a vector layer.
A geometry is the spatial representation of a feature.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the scope.
void toggled(bool)
Emitted when atlas is enabled or disabled.
void setHideCoverage(bool hide)
Sets whether the coverage layer should be hidden in map items in the composition. ...
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
QString currentPageName() const
Returns the name of the page for the current atlas feature.
double toDouble(bool *ok) const
QString tr(const char *sourceText, const char *disambiguation, int n)
void endRender()
Ends the rendering.
void readXML(const QDomElement &elem, const QDomDocument &doc)
Reads general atlas settings from xml.
QGis::WkbType wkbType() const
Returns the WKBType or WKBUnknown in case of error.
Q_DECL_DEPRECATED void setFixedScale(bool fixed)
Sets whether the atlas map should use a fixed scale.
Q_DECL_DEPRECATED float margin() const
Returns the margin for the atlas map.
void setAtlasMargin(double margin)
Sets the margin size (percentage) used when the map is in atlas mode.
bool setFilenamePattern(const QString &pattern)
Sets the filename expression used for generating output filenames for each atlas page.
Q_DECL_DEPRECATED void setSortKeyAttributeIndex(int idx)
void setCoverageLayer(QgsVectorLayer *layer)
Sets the coverage layer to use for the atlas features.
void setAtlasScalingMode(AtlasScalingMode mode)
Sets the current atlas scaling mode.
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
int count(const T &value) const
bool beginRender()
Begins the rendering.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
Q_DECL_DEPRECATED void setComposerMap(QgsComposerMap *map)
Sets the map used by the atlas.
double calculate(const QgsRectangle &mapExtent, int canvasWidth)
Calculate the scale denominator.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
double xMaximum() const
Get the x maximum value (right side of rectangle)
void prepareMap(QgsComposerMap *map)
Recalculates the bounds of an atlas driven map.
void statusMsgChanged(QString message)
Is emitted when the atlas has an updated status bar message for the composer window.
QgsAttributes attributes() const
Returns the feature's attributes.
void setAttribute(const QString &name, const QString &value)
void refreshFeature()
Refreshes the current atlas feature, by refetching its attributes from the vector layer provider...
const QgsComposition * composition() const
Returns the composition the item is attached to.
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
int toInt(bool *ok, int base) const
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static void logMessage(const QString &message, const QString &tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
This class wraps a request for features to a vector layer (or directly its vector data provider)...
int numFeatures() const
Returns the number of features in the coverage layer.
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
int count() const
Return number of items.
Q_DECL_DEPRECATED bool atlasFixedScale() const
Returns true if the map uses a fixed scale when in atlas mode.
void setEnabled(bool enabled)
Sets whether the atlas is enabled.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the scope.
int updateFeatures()
Requeries the current atlas coverage layer and applies filtering and sorting.
void writeXML(QDomElement &elem, QDomDocument &doc) const
Graphics scene for map printing.
Object representing map window.
void featureChanged(QgsFeature *feature)
Is emitted when the current atlas feature changes.
void coverageLayerChanged(QgsVectorLayer *layer)
Is emitted when the coverage layer for an atlas changes.
Calculates scale for a given combination of canvas size, map extent, and monitor dpi.
bool setAtlasMode(const QgsComposition::AtlasMode mode)
Sets the current atlas mode of the composition.
#define Q_NOWARN_DEPRECATED_POP
const T & at(int i) const
const_iterator constBegin() const
void renderBegun()
Is emitted when atlas rendering has begun.
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
QgsRectangle extent() const
FieldSorter(QgsAtlasComposition::SorterKeys &keys, bool ascending=true)
Q_DECL_DEPRECATED QgsComposerMap * composerMap() const
Returns the map used by the atlas.
void readXMLMapSettings(const QDomElement &elem, const QDomDocument &doc)
Reads old (pre 2.2) map related atlas settings from xml.
Q_DECL_DEPRECATED void setMargin(float margin)
Sets the margin for the atlas map.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
AtlasScalingMode atlasScalingMode() const
Returns the current atlas scaling mode.
Class for storing a coordinate reference system (CRS)
void update(qreal x, qreal y, qreal w, qreal h)
int count(const T &value) const
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
const QMap< QString, QgsMapLayer * > & mapLayers()
Retrieve the mapLayers collection (mainly intended for use by projection)
void parameterChanged()
Emitted when one of the parameters changes.
int transform(const QgsCoordinateTransform &ct)
Transform this geometry as described by CoordinateTransform ct.
void push_back(const T &value)
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
const QString & currentFilename() const
Returns the current filename.
iterator insert(const Key &key, const T &value)
void numberFeaturesChanged(int numFeatures)
Is emitted when the number of features for the atlas changes.
bool atlasDriven() const
Returns whether the map extent is set to follow the current atlas feature.
int currentFeatureNumber() const
Returns the current feature number, where a value of 0 corresponds to the first feature.
static QgsExpressionContextScope * projectScope()
Creates a new scope which contains variables and functions relating to the current QGIS project...
void setAtlasDriven(bool enabled)
Sets whether the map extent will follow the current atlas feature.
QDomElement createElement(const QString &tagName)
bool nextFeature(QgsFeature &f)
void composerItems(QList< T * > &itemList)
Return composer items of a specific type.
double width() const
Width of the rectangle.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Represents a vector layer which manages a vector based data sets.
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
double xMinimum() const
Get the x minimum value (left side of rectangle)
int count(const Key &key) const
void setPredefinedScales(const QVector< qreal > &scales)
Sets the list of predefined scales for the atlas.
bool operator()(const QPair< QgsFeatureId, QString > &id1, const QPair< QgsFeatureId, QString > &id2)
double height() const
Height of the rectangle.
void scale(double scaleFactor, const QgsPoint *c=0)
Scale the rectangle around its center point.
static QgsExpressionContextScope * compositionScope(const QgsComposition *composition)
Creates a new scope which contains variables and functions relating to a QgsComposition.