QGIS API Documentation  2.2.0-Valmiera
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsatlascomposition.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsatlascomposition.cpp
3  -----------------------
4  begin : October 2012
5  copyright : (C) 2005 by Hugo Mercier
6  email : hugo dot mercier at oslandia dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 #include <stdexcept>
18 
19 #include "qgsatlascomposition.h"
20 #include "qgsvectorlayer.h"
21 #include "qgscomposermap.h"
22 #include "qgscomposition.h"
23 #include "qgsvectordataprovider.h"
24 #include "qgsexpression.h"
25 #include "qgsgeometry.h"
26 #include "qgscomposerlabel.h"
27 #include "qgscomposershape.h"
28 #include "qgspaperitem.h"
29 #include "qgsmaplayerregistry.h"
30 
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 {
39 
40  // declare special columns with a default value
41  QgsExpression::setSpecialColumn( "$page", QVariant(( int )1 ) );
42  QgsExpression::setSpecialColumn( "$feature", QVariant(( int )0 ) );
43  QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )1 ) );
44  QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )0 ) );
45  QgsExpression::setSpecialColumn( "$atlasfeatureid", QVariant(( int )0 ) );
46  QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( QgsGeometry() ) );
47 }
48 
50 {
51 }
52 
54 {
55  mEnabled = e;
57  emit toggled( e );
58 }
59 
61 {
62  mCoverageLayer = layer;
63 
64  // update the number of features
65  QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )mFeatureIds.size() ) );
66 
67  // Grab the first feature so that user can use it to test the style in rules.
68  QgsFeature fet;
69  layer->getFeatures().nextFeature( fet );
70  QgsExpression::setSpecialColumn( "$atlasfeatureid", fet.id() );
71  QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( *fet.geometry() ) );
72 
73  emit coverageLayerChanged( layer );
74 }
75 
77 {
78  //deprecated method. Until removed just return the first atlas-enabled composer map
79 
80  //build a list of composer maps
81  QList<QgsComposerMap*> maps;
82  mComposition->composerItems( maps );
83  for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
84  {
85  QgsComposerMap* currentMap = ( *mit );
86  if ( currentMap->atlasDriven() )
87  {
88  return currentMap;
89  }
90  }
91 
92  return 0;
93 }
94 
96 {
97  //deprecated
98 
99  if ( !map )
100  {
101  return;
102  }
103 
104  map->setAtlasDriven( true );
105 }
106 
108 {
109  //deprecated method. Until removed just return the property for the first atlas-enabled composer map
110  QgsComposerMap * map = composerMap();
111  if ( !map )
112  {
113  return false;
114  }
115 
116  return map->atlasFixedScale();
117 }
118 
120 {
121  //deprecated method. Until removed just set the property for the first atlas-enabled composer map
122  QgsComposerMap * map = composerMap();
123  if ( !map )
124  {
125  return;
126  }
127 
128  map->setAtlasFixedScale( fixed );
129 }
130 
132 {
133  //deprecated method. Until removed just return the property for the first atlas-enabled composer map
134  QgsComposerMap * map = composerMap();
135  if ( !map )
136  {
137  return 0;
138  }
139 
140  return map->atlasMargin();
141 }
142 
143 void QgsAtlasComposition::setMargin( float margin )
144 {
145  //deprecated method. Until removed just set the property for the first atlas-enabled composer map
146  QgsComposerMap * map = composerMap();
147  if ( !map )
148  {
149  return;
150  }
151 
152  map->setAtlasMargin(( double ) margin );
153 }
154 
155 //
156 // Private class only used for the sorting of features
158 {
159  public:
160  FieldSorter( QgsAtlasComposition::SorterKeys& keys, bool ascending = true ) : mKeys( keys ), mAscending( ascending ) {}
161 
162  bool operator()( const QgsFeatureId& id1, const QgsFeatureId& id2 )
163  {
164  bool result = true;
165 
166  if ( mKeys[ id1 ].type() == QVariant::Int )
167  {
168  result = mKeys[ id1 ].toInt() < mKeys[ id2 ].toInt();
169  }
170  else if ( mKeys[ id1 ].type() == QVariant::Double )
171  {
172  result = mKeys[ id1 ].toDouble() < mKeys[ id2 ].toDouble();
173  }
174  else if ( mKeys[ id1 ].type() == QVariant::String )
175  {
176  result = ( QString::localeAwareCompare( mKeys[ id1 ].toString(), mKeys[ id2 ].toString() ) < 0 );
177  }
178 
179  return mAscending ? result : !result;
180  }
181  private:
184 };
185 
187 {
188  //needs to be called when layer, filter, sort changes
189 
190  if ( !mCoverageLayer )
191  {
192  return 0;
193  }
194 
196 
197  // select all features with all attributes
199 
200  std::auto_ptr<QgsExpression> filterExpression;
201  if ( mFilterFeatures && !mFeatureFilter.isEmpty() )
202  {
203  filterExpression = std::auto_ptr<QgsExpression>( new QgsExpression( mFeatureFilter ) );
204  if ( filterExpression->hasParserError() )
205  {
206  throw std::runtime_error( tr( "Feature filter parser error: %1" ).arg( filterExpression->parserErrorString() ).toLocal8Bit().data() );
207  }
208  }
209 
210  // We cannot use nextFeature() directly since the feature pointer is rewinded by the rendering process
211  // We thus store the feature ids for future extraction
212  QgsFeature feat;
213  mFeatureIds.clear();
214  mFeatureKeys.clear();
215  while ( fit.nextFeature( feat ) )
216  {
217  if ( mFilterFeatures && !mFeatureFilter.isEmpty() )
218  {
219  QVariant result = filterExpression->evaluate( &feat, mCoverageLayer->pendingFields() );
220  if ( filterExpression->hasEvalError() )
221  {
222  throw std::runtime_error( tr( "Feature filter eval error: %1" ).arg( filterExpression->evalErrorString() ).toLocal8Bit().data() );
223  }
224 
225  // skip this feature if the filter evaluation if false
226  if ( !result.toBool() )
227  {
228  continue;
229  }
230  }
231  mFeatureIds.push_back( feat.id() );
232 
233  if ( mSortFeatures )
234  {
235  mFeatureKeys.insert( feat.id(), feat.attributes()[ mSortKeyAttributeIdx ] );
236  }
237  }
238 
239  // sort features, if asked for
240  if ( mSortFeatures )
241  {
243  qSort( mFeatureIds.begin(), mFeatureIds.end(), sorter );
244  }
245 
246  QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )mFeatureIds.size() ) );
247 
248  //jump to first feature if currently using an atlas preview
249  //need to do this in case filtering/layer change has altered matching features
251  {
252  firstFeature();
253  }
254 
255  return mFeatureIds.size();
256 }
257 
258 
260 {
261  if ( !mCoverageLayer )
262  {
263  return false;
264  }
265 
266  bool featuresUpdated = updateFeatures();
267  if ( !featuresUpdated )
268  {
269  //no matching features found
270  return false;
271  }
272 
273  // special columns for expressions
274  QgsExpression::setSpecialColumn( "$numpages", QVariant( mComposition->numPages() ) );
275  QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )mFeatureIds.size() ) );
276 
277  return true;
278 }
279 
281 {
282  if ( !mCoverageLayer )
283  {
284  return;
285  }
286 
287  // reset label expression contexts
288  QList<QgsComposerLabel*> labels;
289  mComposition->composerItems( labels );
290  for ( QList<QgsComposerLabel*>::iterator lit = labels.begin(); lit != labels.end(); ++lit )
291  {
292  ( *lit )->setExpressionContext( 0, 0 );
293  }
294 
295  updateAtlasMaps();
296 }
297 
299 {
300  //update atlas-enabled composer maps
301  QList<QgsComposerMap*> maps;
302  mComposition->composerItems( maps );
303  for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
304  {
305  QgsComposerMap* currentMap = ( *mit );
306  if ( !currentMap->atlasDriven() )
307  {
308  continue;
309  }
310 
311  currentMap->cache();
312  }
313 }
314 
316 {
317  return mFeatureIds.size();
318 }
319 
321 {
323  if ( mCurrentFeatureNo >= mFeatureIds.size() )
324  {
325  mCurrentFeatureNo = mFeatureIds.size() - 1;
326  }
327 
329 }
330 
332 {
334  if ( mCurrentFeatureNo < 0 )
335  {
336  mCurrentFeatureNo = 0;
337  }
338 
340 }
341 
343 {
344  mCurrentFeatureNo = 0;
346 }
347 
349 {
350  mCurrentFeatureNo = mFeatureIds.size() - 1;
352 }
353 
355 {
356  int featureI = mFeatureIds.indexOf( feat->id() );
357  prepareForFeature( featureI );
358 }
359 
361 {
362  if ( !mCoverageLayer )
363  {
364  return;
365  }
366 
367  if ( mFeatureIds.size() == 0 )
368  {
369  emit statusMsgChanged( tr( "No matching atlas features" ) );
370  return;
371  }
372 
373  // retrieve the next feature, based on its id
375 
376  QgsExpression::setSpecialColumn( "$atlasfeatureid", mCurrentFeature.id() );
377  QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( *mCurrentFeature.geometry() ) );
378  QgsExpression::setSpecialColumn( "$feature", QVariant(( int )featureI + 1 ) );
379 
380  // generate filename for current feature
382 
383  // evaluate label expressions
384  QList<QgsComposerLabel*> labels;
385  mComposition->composerItems( labels );
386  for ( QList<QgsComposerLabel*>::iterator lit = labels.begin(); lit != labels.end(); ++lit )
387  {
388  ( *lit )->setExpressionContext( &mCurrentFeature, mCoverageLayer );
389  }
390 
391  // update shapes (in case they use data defined symbology with atlas properties)
392  QList<QgsComposerShape*> shapes;
393  mComposition->composerItems( shapes );
394  for ( QList<QgsComposerShape*>::iterator lit = shapes.begin(); lit != shapes.end(); ++lit )
395  {
396  ( *lit )->update();
397  }
398 
399  // update page background (in case it uses data defined symbology with atlas properties)
400  QList<QgsPaperItem*> pages;
401  mComposition->composerItems( pages );
402  for ( QList<QgsPaperItem*>::iterator pageIt = pages.begin(); pageIt != pages.end(); ++pageIt )
403  {
404  ( *pageIt )->update();
405  }
406 
407  emit statusMsgChanged( QString( tr( "Atlas feature %1 of %2" ) ).arg( featureI + 1 ).arg( mFeatureIds.size() ) );
408 
409  //update composer maps
410 
411  //build a list of atlas-enabled composer maps
412  QList<QgsComposerMap*> maps;
413  QList<QgsComposerMap*> atlasMaps;
414  mComposition->composerItems( maps );
415  for ( QList<QgsComposerMap*>::iterator mit = maps.begin(); mit != maps.end(); ++mit )
416  {
417  QgsComposerMap* currentMap = ( *mit );
418  if ( !currentMap->atlasDriven() )
419  {
420  continue;
421  }
422  atlasMaps << currentMap;
423  }
424 
425  //clear the transformed bounds of the previous feature
427 
428  if ( atlasMaps.isEmpty() )
429  {
430  //no atlas enabled maps
431  return;
432  }
433 
434  // compute extent of current feature in the map CRS. This should be set on a per-atlas map basis,
435  // but given that it's not currently possible to have maps with different CRSes we can just
436  // calculate it once based on the first atlas maps' CRS.
437  computeExtent( atlasMaps[0] );
438 
439  //update atlas bounds of every atlas enabled composer map
440  for ( QList<QgsComposerMap*>::iterator mit = atlasMaps.begin(); mit != atlasMaps.end(); ++mit )
441  {
442  prepareMap( *mit );
443  }
444 }
445 
447 {
448  // compute the extent of the current feature, in the crs of the specified map
449 
450  const QgsCoordinateReferenceSystem& coverage_crs = mCoverageLayer->crs();
451  // transformation needed for feature geometries
452  const QgsCoordinateReferenceSystem& destination_crs = map->mapRenderer()->destinationCrs();
453  mTransform.setSourceCrs( coverage_crs );
454  mTransform.setDestCRS( destination_crs );
455 
456  // QgsGeometry::boundingBox is expressed in the geometry"s native CRS
457  // We have to transform the grometry to the destination CRS and ask for the bounding box
458  // Note: we cannot directly take the transformation of the bounding box, since transformations are not linear
460  tgeom.transform( mTransform );
461  mTransformedFeatureBounds = tgeom.boundingBox();
462 }
463 
465 {
466  if ( !map->atlasDriven() )
467  {
468  return;
469  }
470 
472  {
473  //transformed extent of current feature hasn't been calculated yet. This can happen if
474  //a map has been set to be atlas controlled after prepare feature was called
475  computeExtent( map );
476  }
477 
478  double xa1 = mTransformedFeatureBounds.xMinimum();
479  double xa2 = mTransformedFeatureBounds.xMaximum();
480  double ya1 = mTransformedFeatureBounds.yMinimum();
481  double ya2 = mTransformedFeatureBounds.yMaximum();
483  QgsRectangle mOrigExtent = map->extent();
484 
485  if ( map->atlasFixedScale() )
486  {
487  // only translate, keep the original scale (i.e. width x height)
488 
489  double geom_center_x = ( xa1 + xa2 ) / 2.0;
490  double geom_center_y = ( ya1 + ya2 ) / 2.0;
491  double xx = geom_center_x - mOrigExtent.width() / 2.0;
492  double yy = geom_center_y - mOrigExtent.height() / 2.0;
493  new_extent = QgsRectangle( xx,
494  yy,
495  xx + mOrigExtent.width(),
496  yy + mOrigExtent.height() );
497  }
498  else
499  {
500  // auto scale
501 
503  double map_ratio = mOrigExtent.width() / mOrigExtent.height();
504 
505  // geometry height is too big
506  if ( geom_ratio < map_ratio )
507  {
508  // extent the bbox's width
509  double adj_width = ( map_ratio * mTransformedFeatureBounds.height() - mTransformedFeatureBounds.width() ) / 2.0;
510  xa1 -= adj_width;
511  xa2 += adj_width;
512  }
513  // geometry width is too big
514  else if ( geom_ratio > map_ratio )
515  {
516  // extent the bbox's height
517  double adj_height = ( mTransformedFeatureBounds.width() / map_ratio - mTransformedFeatureBounds.height() ) / 2.0;
518  ya1 -= adj_height;
519  ya2 += adj_height;
520  }
521  new_extent = QgsRectangle( xa1, ya1, xa2, ya2 );
522 
523  if ( map->atlasMargin() > 0.0 )
524  {
525  new_extent.scale( 1 + map->atlasMargin() );
526  }
527  }
528 
529  // set the new extent (and render)
530  map->setNewAtlasFeatureExtent( new_extent );
531 }
532 
534 {
535  return mCurrentFilename;
536 }
537 
538 void QgsAtlasComposition::writeXML( QDomElement& elem, QDomDocument& doc ) const
539 {
540  QDomElement atlasElem = doc.createElement( "Atlas" );
541  atlasElem.setAttribute( "enabled", mEnabled ? "true" : "false" );
542  if ( !mEnabled )
543  {
544  return;
545  }
546 
547  if ( mCoverageLayer )
548  {
549  atlasElem.setAttribute( "coverageLayer", mCoverageLayer->id() );
550  }
551  else
552  {
553  atlasElem.setAttribute( "coverageLayer", "" );
554  }
555 
556  atlasElem.setAttribute( "hideCoverage", mHideCoverage ? "true" : "false" );
557  atlasElem.setAttribute( "singleFile", mSingleFile ? "true" : "false" );
558  atlasElem.setAttribute( "filenamePattern", mFilenamePattern );
559 
560  atlasElem.setAttribute( "sortFeatures", mSortFeatures ? "true" : "false" );
561  if ( mSortFeatures )
562  {
563  atlasElem.setAttribute( "sortKey", QString::number( mSortKeyAttributeIdx ) );
564  atlasElem.setAttribute( "sortAscending", mSortAscending ? "true" : "false" );
565  }
566  atlasElem.setAttribute( "filterFeatures", mFilterFeatures ? "true" : "false" );
567  if ( mFilterFeatures )
568  {
569  atlasElem.setAttribute( "featureFilter", mFeatureFilter );
570  }
571 
572  elem.appendChild( atlasElem );
573 }
574 
575 void QgsAtlasComposition::readXML( const QDomElement& atlasElem, const QDomDocument& )
576 {
577  mEnabled = atlasElem.attribute( "enabled", "false" ) == "true" ? true : false;
578  emit toggled( mEnabled );
579  if ( !mEnabled )
580  {
581  emit parameterChanged();
582  return;
583  }
584 
585  // look for stored layer name
586  mCoverageLayer = 0;
587  QMap<QString, QgsMapLayer*> layers = QgsMapLayerRegistry::instance()->mapLayers();
588  for ( QMap<QString, QgsMapLayer*>::const_iterator it = layers.begin(); it != layers.end(); ++it )
589  {
590  if ( it.key() == atlasElem.attribute( "coverageLayer" ) )
591  {
592  mCoverageLayer = dynamic_cast<QgsVectorLayer*>( it.value() );
593  break;
594  }
595  }
596  //look for stored composer map, to upgrade pre 2.1 projects
597  int composerMapNo = atlasElem.attribute( "composerMap", "-1" ).toInt();
599  if ( composerMapNo != -1 )
600  {
601  QList<QgsComposerMap*> maps;
602  mComposition->composerItems( maps );
603  for ( QList<QgsComposerMap*>::iterator it = maps.begin(); it != maps.end(); ++it )
604  {
605  if (( *it )->id() == composerMapNo )
606  {
607  composerMap = ( *it );
608  composerMap->setAtlasDriven( true );
609  break;
610  }
611  }
612  }
613  mHideCoverage = atlasElem.attribute( "hideCoverage", "false" ) == "true" ? true : false;
614 
615  //upgrade pre 2.1 projects
616  double margin = atlasElem.attribute( "margin", "0.0" ).toDouble();
617  if ( composerMap && margin != 0 )
618  {
619  composerMap->setAtlasMargin( margin );
620  }
621  bool fixedScale = atlasElem.attribute( "fixedScale", "false" ) == "true" ? true : false;
622  if ( composerMap && fixedScale )
623  {
624  composerMap->setAtlasFixedScale( true );
625  }
626 
627  mSingleFile = atlasElem.attribute( "singleFile", "false" ) == "true" ? true : false;
628  mFilenamePattern = atlasElem.attribute( "filenamePattern", "" );
629 
630  mSortFeatures = atlasElem.attribute( "sortFeatures", "false" ) == "true" ? true : false;
631  if ( mSortFeatures )
632  {
633  mSortKeyAttributeIdx = atlasElem.attribute( "sortKey", "0" ).toInt();
634  mSortAscending = atlasElem.attribute( "sortAscending", "true" ) == "true" ? true : false;
635  }
636  mFilterFeatures = atlasElem.attribute( "filterFeatures", "false" ) == "true" ? true : false;
637  if ( mFilterFeatures )
638  {
639  mFeatureFilter = atlasElem.attribute( "featureFilter", "" );
640  }
641 
642  emit parameterChanged();
643 }
644 
646 {
647  mHideCoverage = hide;
648 
650  {
651  //an atlas preview is enabled, so reflect changes in coverage layer visibility immediately
652  updateAtlasMaps();
653  mComposition->update();
654  }
655 
656 }
657 
658 void QgsAtlasComposition::setFilenamePattern( const QString& pattern )
659 {
660  mFilenamePattern = pattern;
662 }
663 
665 {
666  const QgsFields& fields = mCoverageLayer->pendingFields();
667 
668  if ( !mSingleFile && mFilenamePattern.size() > 0 )
669  {
670  mFilenameExpr = std::auto_ptr<QgsExpression>( new QgsExpression( mFilenamePattern ) );
671  // expression used to evaluate each filename
672  // test for evaluation errors
673  if ( mFilenameExpr->hasParserError() )
674  {
675  throw std::runtime_error( tr( "Filename parsing error: %1" ).arg( mFilenameExpr->parserErrorString() ).toLocal8Bit().data() );
676  }
677 
678  // prepare the filename expression
679  mFilenameExpr->prepare( fields );
680  }
681 
682  //if atlas preview is currently enabled, regenerate filename for current feature
684  {
686  }
687 
688 }
689 
691 {
692  //generate filename for current atlas feature
693  if ( !mSingleFile && mFilenamePattern.size() > 0 )
694  {
695  QVariant filenameRes = mFilenameExpr->evaluate( &mCurrentFeature, mCoverageLayer->pendingFields() );
696  if ( mFilenameExpr->hasEvalError() )
697  {
698  throw std::runtime_error( tr( "Filename eval error: %1" ).arg( mFilenameExpr->evalErrorString() ).toLocal8Bit().data() );
699  }
700 
701  mCurrentFilename = filenameRes.toString();
702  }
703 }
704 
705 
QgsFeatureId id() const
Get the feature id for this feature.
Definition: qgsfeature.cpp:101
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:89
QMap< QgsFeatureId, QVariant > SorterKeys
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.
Definition: qgsrectangle.h:35
bool isEmpty() const
test if rectangle is empty
QgsVectorLayer * mCoverageLayer
QVector< QgsFeatureId > mFeatureIds
void setNewAtlasFeatureExtent(const QgsRectangle &extent)
Sets new Extent for the current atlas preview and changes width, height (and implicitely also scale)...
QgsAtlasComposition(QgsComposition *composition)
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:189
double atlasMargin() const
Returns the margin size (percentage) used when the map is in atlas mode.
void setSourceCrs(const QgsCoordinateReferenceSystem &theCRS)
void computeExtent(QgsComposerMap *map)
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
QgsGeometry * geometry() const
Get the geometry object associated with this feature.
Definition: qgsfeature.cpp:113
void cache()
Create cache image.
bool fixedScale() const
Returns whether the atlas map uses a fixed scale.
Container of fields for a vector layer.
Definition: qgsfield.h:162
QgsCoordinateTransform mTransform
void toggled(bool)
emitted when atlas is enabled or disabled
void setHideCoverage(bool hide)
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:114
void evalFeatureFilename()
Evaluates filename for current feature.
int numPages() const
Note: added in version 1.9.
void endRender()
Ends the rendering.
void readXML(const QDomElement &elem, const QDomDocument &doc)
void setFixedScale(bool fixed)
Sets whether the atlas map should use a fixed scale.
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.
QgsRectangle mTransformedFeatureBounds
bool beginRender()
Begins the rendering.
void setComposerMap(QgsComposerMap *map)
Sets the map used by the atlas.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:194
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:179
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.
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
const QgsMapRenderer * mapRenderer() const
bool setAtlasMode(QgsComposition::AtlasMode mode)
Sets the current atlas mode of the composition.
void prepareForFeature(int i)
Prepare the atlas map for the given feature.
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.
const QgsAttributes & attributes() const
Definition: qgsfeature.h:143
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
Definition: qgsmaplayer.cpp:94
void updateFilenameExpression()
Updates the filename expression.
bool atlasFixedScale() const
Returns true if the map uses a fixed scale when in atlas mode.
void setCoverageLayer(QgsVectorLayer *lmap)
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.
QgsComposition * mComposition
void coverageLayerChanged(QgsVectorLayer *layer)
Is emitted when the coverage layer for an atlas changes.
bool operator()(const QgsFeatureId &id1, const QgsFeatureId &id2)
void setDestCRS(const QgsCoordinateReferenceSystem &theCRS)
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
QgsRectangle extent() const
FieldSorter(QgsAtlasComposition::SorterKeys &keys, bool ascending=true)
QgsComposerMap * composerMap() const
Returns the map used by the atlas.
void setMargin(float margin)
Sets the margin for the atlas map.
Class for storing a coordinate reference system (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 CoordinateTranasform ct.
void setFilenamePattern(const QString &pattern)
void setAtlasFixedScale(bool fixed)
Set to true if the map should use a fixed scale when in atlas mode.
qint64 QgsFeatureId
Definition: qgsfeature.h:30
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
const QString & currentFilename() const
Returns the current filename.
std::auto_ptr< QgsExpression > mFilenameExpr
bool atlasDriven() const
Returns true if 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)
Set to true if the map extents should be set by the current atlas feature.
bool nextFeature(QgsFeature &f)
void composerItems(QList< T * > &itemList)
Return composer items of a specific type.
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:199
Represents a vector layer which manages a vector based data sets.
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:184
QgsAtlasComposition::SorterKeys & mKeys
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:204
#define tr(sourceText)
void scale(double scaleFactor, const QgsPoint *c=0)
Scale the rectangle around its center point.