18 #include <QtAlgorithms>
34 : mComposition( composition )
36 , mHideCoverage( false )
37 , mFilenamePattern(
"'output_'||@atlas_featurenumber" )
38 , mCoverageLayer( nullptr )
39 , mSingleFile( false )
40 , mSortFeatures( false )
41 , mSortAscending( true )
42 , mCurrentFeatureNo( 0 )
43 , mFilterFeatures( false )
56 if ( enabled == mEnabled )
67 void QgsAtlasComposition::removeLayers(
const QStringList& layers )
69 if ( !mCoverageLayer )
74 Q_FOREACH (
const QString& layerId, layers )
76 if ( layerId == mCoverageLayer->
id() )
79 mCoverageLayer =
nullptr;
88 if ( layer == mCoverageLayer )
93 mCoverageLayer = layer;
99 if ( pageNumber < 0 || pageNumber >= mFeatureIds.
count() )
102 return mFeatureIds.
at( pageNumber ).second;
139 if ( !mCoverageLayer )
148 if ( mCoverageLayer )
151 if ( idx >= 0 && idx < fields.
count() )
153 mSortKeyAttributeName = fields[idx].name();
157 mSortKeyAttributeName =
"";
182 if ( !mCoverageLayer )
189 updateFilenameExpression();
195 if ( mFilterFeatures && !mFeatureFilter.
isEmpty() )
198 if ( filterExpression->hasParserError() )
200 mFilterParserError = filterExpression->parserErrorString();
207 mFilterParserError =
QString();
212 if ( !mPageNameExpression.
isEmpty() )
215 if ( nameExpression->hasParserError() )
217 nameExpression.
reset(
nullptr );
221 nameExpression->prepare( &expressionContext );
229 mFeatureKeys.
clear();
230 int sortIdx = mCoverageLayer->
fieldNameIndex( mSortKeyAttributeName );
237 if ( !nameExpression.
isNull() )
239 QVariant result = nameExpression->evaluate( &expressionContext );
240 if ( nameExpression->hasEvalError() )
247 mFeatureIds.
push_back( qMakePair( feat.
id(), pageName ) );
249 if ( mSortFeatures && sortIdx != -1 )
258 FieldSorter sorter( mFeatureKeys, mSortAscending );
259 qSort( mFeatureIds.
begin(), mFeatureIds.
end(), sorter );
271 return mFeatureIds.
size();
281 if ( !mCoverageLayer )
289 if ( !featuresUpdated )
300 if ( !mCoverageLayer )
312 void QgsAtlasComposition::updateAtlasMaps()
331 return mFeatureIds.
size();
336 int newFeatureNo = mCurrentFeatureNo + 1;
337 if ( newFeatureNo >= mFeatureIds.
size() )
339 newFeatureNo = mFeatureIds.
size() - 1;
347 int newFeatureNo = mCurrentFeatureNo - 1;
348 if ( newFeatureNo < 0 )
371 for ( ; it != mFeatureIds.
constEnd(); ++it, ++currentIdx )
373 if (( *it ).first == feat->
id() )
375 featureI = currentIdx;
396 if ( !mCoverageLayer )
407 if ( featureI >= mFeatureIds.
size() )
412 mCurrentFeatureNo = featureI;
420 if ( !evalFeatureFilename( expressionContext ) )
426 mGeometryCache.
clear();
430 if ( !mCurrentFeature.
isValid() )
459 atlasMaps << currentMap;
470 computeExtent( atlasMaps[0] );
475 if (( *mit )->atlasDriven() )
506 if ( mTransformedFeatureBounds.
isEmpty() )
510 computeExtent( map );
513 double xa1 = mTransformedFeatureBounds.
xMinimum();
514 double xa2 = mTransformedFeatureBounds.
xMaximum();
515 double ya1 = mTransformedFeatureBounds.
yMinimum();
516 double ya2 = mTransformedFeatureBounds.
yMaximum();
521 bool isPointLayer =
false;
522 switch ( mCoverageLayer->
wkbType() )
531 isPointLayer =
false;
541 double geomCenterX = ( xa1 + xa2 ) / 2.0;
542 double geomCenterY = ( ya1 + ya2 ) / 2.0;
547 double xMin = geomCenterX - mOrigExtent.width() / 2.0;
548 double yMin = geomCenterY - mOrigExtent.height() / 2.0;
551 xMin + mOrigExtent.width(),
552 yMin + mOrigExtent.height() );
557 newExtent.
scale( originalScale / newScale );
562 double newWidth = mOrigExtent.width();
563 double newHeight = mOrigExtent.height();
565 for (
int i = 0; i < scales.
size(); i++ )
567 double ratio = scales[i] / originalScale;
568 newWidth = mOrigExtent.width() * ratio;
569 newHeight = mOrigExtent.height() * ratio;
572 double xMin = geomCenterX - newWidth / 2.0;
573 double yMin = geomCenterY - newHeight / 2.0;
582 newExtent.
scale( scales[i] / newScale );
584 if (( newExtent.
width() >= mTransformedFeatureBounds.
width() ) && ( newExtent.
height() >= mTransformedFeatureBounds.
height() ) )
596 double geomRatio = mTransformedFeatureBounds.
width() / mTransformedFeatureBounds.
height();
597 double mapRatio = mOrigExtent.width() / mOrigExtent.height();
600 if ( geomRatio < mapRatio )
603 double adjWidth = ( mapRatio * mTransformedFeatureBounds.
height() - mTransformedFeatureBounds.
width() ) / 2.0;
608 else if ( geomRatio > mapRatio )
611 double adjHeight = ( mTransformedFeatureBounds.
width() / mapRatio - mTransformedFeatureBounds.
height() ) / 2.0;
629 return mCurrentFilename;
635 atlasElem.
setAttribute(
"enabled", mEnabled ?
"true" :
"false" );
641 if ( mCoverageLayer )
650 atlasElem.
setAttribute(
"hideCoverage", mHideCoverage ?
"true" :
"false" );
651 atlasElem.
setAttribute(
"singleFile", mSingleFile ?
"true" :
"false" );
652 atlasElem.
setAttribute(
"filenamePattern", mFilenamePattern );
653 atlasElem.
setAttribute(
"pageNameExpression", mPageNameExpression );
655 atlasElem.
setAttribute(
"sortFeatures", mSortFeatures ?
"true" :
"false" );
658 atlasElem.
setAttribute(
"sortKey", mSortKeyAttributeName );
659 atlasElem.
setAttribute(
"sortAscending", mSortAscending ?
"true" :
"false" );
661 atlasElem.
setAttribute(
"filterFeatures", mFilterFeatures ?
"true" :
"false" );
662 if ( mFilterFeatures )
664 atlasElem.
setAttribute(
"featureFilter", mFeatureFilter );
672 mEnabled = atlasElem.
attribute(
"enabled",
"false" ) ==
"true" ?
true :
false;
681 mCoverageLayer =
nullptr;
685 if ( it.key() == atlasElem.
attribute(
"coverageLayer" ) )
692 mPageNameExpression = atlasElem.
attribute(
"pageNameExpression",
QString() );
693 mSingleFile = atlasElem.
attribute(
"singleFile",
"false" ) ==
"true" ?
true :
false;
694 mFilenamePattern = atlasElem.
attribute(
"filenamePattern",
"" );
696 mSortFeatures = atlasElem.
attribute(
"sortFeatures",
"false" ) ==
"true" ?
true :
false;
699 mSortKeyAttributeName = atlasElem.
attribute(
"sortKey",
"" );
704 int idx = mSortKeyAttributeName.
toInt( &isIndex );
705 if ( isIndex && mCoverageLayer )
708 if ( idx >= 0 && idx < fields.
count() )
710 mSortKeyAttributeName = fields[idx].name();
713 mSortAscending = atlasElem.
attribute(
"sortAscending",
"true" ) ==
"true" ?
true :
false;
715 mFilterFeatures = atlasElem.
attribute(
"filterFeatures",
"false" ) ==
"true" ?
true :
false;
716 if ( mFilterFeatures )
718 mFeatureFilter = atlasElem.
attribute(
"featureFilter",
"" );
721 mHideCoverage = atlasElem.
attribute(
"hideCoverage",
"false" ) ==
"true" ?
true :
false;
730 int composerMapNo = elem.
attribute(
"composerMap",
"-1" ).
toInt();
732 if ( composerMapNo != -1 )
738 if (( *it )->id() == composerMapNo )
740 composerMap = ( *it );
754 if ( composerMap && fixedScale )
762 mHideCoverage = hide;
775 mFilenamePattern = pattern;
776 return updateFilenameExpression();
788 if ( mCoverageLayer )
793 return expressionContext;
796 bool QgsAtlasComposition::updateFilenameExpression()
798 if ( !mCoverageLayer )
805 if ( !mFilenamePattern.
isEmpty() )
810 if ( mFilenameExpr->hasParserError() )
812 mFilenameParserError = mFilenameExpr->parserErrorString();
817 mFilenameExpr->prepare( &expressionContext );
823 evalFeatureFilename( expressionContext );
831 if ( !mFilenamePattern.
isEmpty() && !mFilenameExpr.
isNull() )
833 QVariant filenameRes = mFilenameExpr->evaluate( &context );
834 if ( mFilenameExpr->hasEvalError() )
840 mCurrentFilename = filenameRes.
toString();
847 mPredefinedScales = scales;
849 qSort( mPredefinedScales.
begin(), mPredefinedScales.
end() );
915 if ( it != mGeometryCache.
constEnd() )
921 if ( mCoverageLayer->
crs() == crs )
928 mGeometryCache[crs.
srsid()] = transformed;
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
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.
long srsid() const
Returns the SrsId, if available.
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
void scale(double scaleFactor, const QgsPoint *c=nullptr)
Scale the rectangle around its center point.
#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.
const_iterator constFind(const Key &key) const
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.
bool qgsVariantGreaterThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is greater than the second.
double toDouble(bool *ok) const
QString tr(const char *sourceText, const char *disambiguation, int n)
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
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.
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.
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...
const_iterator constEnd() const
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.
QString currentFilename() const
Returns the current filename.
Object representing map window.
QgsGeometry currentGeometry(const QgsCoordinateReferenceSystem &projectedTo=QgsCoordinateReferenceSystem()) const
Returns the current atlas geometry in the given projection system (default to the coverage layer's CR...
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
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
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.
QString authid() const
Returns the authority identifier for the CRS, which includes both the authority (eg EPSG) and the CRS...
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.
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)
void statusMsgChanged(const QString &message)
Is emitted when the atlas has an updated status bar message for the composer window.
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.
const T value(const Key &key) const
static QgsExpressionContextScope * compositionScope(const QgsComposition *composition)
Creates a new scope which contains variables and functions relating to a QgsComposition.