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() ),
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;
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 )
195 return mAscending ? result : !result;
206 if ( !mCoverageLayer )
211 updateFilenameExpression();
217 if ( mFilterFeatures && !mFeatureFilter.
isEmpty() )
220 if ( filterExpression->hasParserError() )
222 mFilterParserError = filterExpression->parserErrorString();
226 mFilterParserError =
QString();
232 mFeatureKeys.
clear();
233 int sortIdx = mCoverageLayer->
fieldNameIndex( mSortKeyAttributeName );
236 if ( !filterExpression.
isNull() )
239 if ( filterExpression->hasEvalError() )
252 if ( mSortFeatures && sortIdx != -1 )
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()
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;
410 if ( !evalFeatureFilename() )
419 if ( !mCurrentFeature.
isValid() )
448 atlasMaps << currentMap;
451 if ( atlasMaps.
count() > 0 )
459 computeExtent( atlasMaps[0] );
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;
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() );
556 newExtent.
scale( originalScale / newScale );
561 double newWidth = mOrigExtent.width();
562 double newHeight = mOrigExtent.height();
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;
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;
634 atlasElem.
setAttribute(
"enabled", mEnabled ?
"true" :
"false" );
640 if ( mCoverageLayer )
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 );
670 mEnabled = atlasElem.
attribute(
"enabled",
"false" ) ==
"true" ?
true :
false;
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 )
735 if (( *it )->id() == composerMapNo )
737 composerMap = ( *it );
746 if ( composerMap && margin != 0 )
751 if ( composerMap && fixedScale )
759 mHideCoverage = hide;
772 mFilenamePattern = pattern;
773 return updateFilenameExpression();
776 bool QgsAtlasComposition::updateFilenameExpression()
778 if ( !mCoverageLayer )
785 if ( mFilenamePattern.
size() > 0 )
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() )
814 if ( mFilenameExpr->hasEvalError() )
820 mCurrentFilename = filenameRes.
toString();
827 mPredefinedScales = scales;
829 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)
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)
Q_DECL_DEPRECATED bool fixedScale() const
Returns whether the atlas map uses a fixed scale.
int indexOf(const T &value, int from) const
const QgsMapSettings & mapSettings() const
Return setting of QGIS map canvas.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
void cache()
Create cache image.
#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 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...
double toDouble(bool *ok) const
QString tr(const char *sourceText, const char *disambiguation, int n)
int numPages() const
Returns the number of pages in the composition.
void endRender()
Ends the rendering.
static void logMessage(QString message, QString tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
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.
int count(const T &value) const
bool beginRender()
Begins the rendering.
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
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.
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.
QVariant fromValue(const T &value)
bool setAtlasMode(const QgsComposition::AtlasMode mode)
Sets the current atlas mode of the composition.
bool operator()(const QgsFeatureId &id1, const QgsFeatureId &id2)
#define Q_NOWARN_DEPRECATED_POP
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.
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)
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)
bool atlasDriven() const
Returns whether the map extent is set to follow the current atlas feature.
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
static void setSpecialColumn(const QString &name, QVariant value)
Assign a special column.
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.
double height() const
Height of the rectangle.
void scale(double scaleFactor, const QgsPoint *c=0)
Scale the rectangle around its center point.