From d904da4ce1898c3e86d02dc0143c3e550c46b56e Mon Sep 17 00:00:00 2001 From: Hugo Mercier Date: Fri, 5 Oct 2012 16:25:11 +0200 Subject: [PATCH] Update of QgsAtlasComposition SIP (with Python unit tests as well) --- python/core/composer/qgsatlascomposition.sip | 63 ++++++++ python/core/composer/qgscomposermap.sip | 20 --- python/core/composer/qgscomposition.sip | 29 ---- python/core/core.sip | 1 + tests/src/python/CMakeLists.txt | 2 +- ...apatlas.py => test_qgsatlascomposition.py} | 141 +++++++++--------- 6 files changed, 132 insertions(+), 124 deletions(-) create mode 100644 python/core/composer/qgsatlascomposition.sip rename tests/src/python/{test_qgscomposermapatlas.py => test_qgsatlascomposition.py} (52%) diff --git a/python/core/composer/qgsatlascomposition.sip b/python/core/composer/qgsatlascomposition.sip new file mode 100644 index 00000000000..a1f4ecbd0b9 --- /dev/null +++ b/python/core/composer/qgsatlascomposition.sip @@ -0,0 +1,63 @@ +/** \ingroup MapComposer + * Class used to render an Atlas, iterating over geometry features. + * prepareForFeature() modifies the atlas map's extent to zoom on the given feature. + * This class is used for printing, exporting to PDF and images. + * */ +class QgsAtlasComposition : public QObject +{ +%TypeHeaderCode +#include +%End + +public: + QgsAtlasComposition( QgsComposition* composition ); + ~QgsAtlasComposition(); + + /** Is the atlas generation enabled ? */ + bool enabled() const; + void setEnabled( bool e ); + + QgsComposerMap* composerMap() const; + void setComposerMap( QgsComposerMap* map ); + + bool hideCoverage() const; + void setHideCoverage( bool hide ); + + bool fixedScale() const; + void setFixedScale( bool fixed ); + + float margin() const; + void setMargin( float margin ); + + QString filenamePattern() const; + void setFilenamePattern( const QString& pattern ); + + QgsVectorLayer* coverageLayer() const; + void setCoverageLayer( QgsVectorLayer* lmap ); + + bool singleFile() const; + void setSingleFile( bool single ); + + /** Begins the rendering. */ + void beginRender(); + /** Ends the rendering. Restores original extent */ + void endRender(); + + /** Returns the number of features in the coverage layer */ + size_t numFeatures() const; + + /** Prepare the atlas map for the given feature. Sets the extent and context variables */ + void prepareForFeature( size_t i ); + + /** Returns the current filename. Must be called after prepareForFeature( i ) */ + const QString& currentFilename() const; + + void writeXML( QDomElement& elem, QDomDocument& doc ) const; + void readXML( const QDomElement& elem, const QDomDocument& doc ); + + QgsComposition* composition(); + + signals: + /** emitted when one of the parameters changes */ + void parameterChanged(); +}; \ No newline at end of file diff --git a/python/core/composer/qgscomposermap.sip b/python/core/composer/qgscomposermap.sip index 7d4b2bab0bd..fcc5a81113b 100644 --- a/python/core/composer/qgscomposermap.sip +++ b/python/core/composer/qgscomposermap.sip @@ -285,29 +285,9 @@ class QgsComposerMap : QgsComposerItem Usually, this function is called before adding the composer map to the composition*/ void assignFreeId(); - bool atlasHideCoverage() const; - void setAtlasHideCoverage( bool hide ); - - bool atlasFixedScale() const; - void setAtlasFixedScale( bool fixed ); - - float atlasMargin() const; - void setAtlasMargin( float margin ); - - QString atlasFilenamePattern() const; - void setAtlasFilenamePattern( const QString& pattern ); - - QgsVectorLayer* atlasCoverageLayer() const; - void setAtlasCoverageLayer( QgsVectorLayer* lmap ); - - bool atlasSingleFile() const; - void setAtlasSingleFile( bool single ); - signals: void extentChanged(); - void atlasCoverageLayerChanged( QgsVectorLayer* ); - public slots: /**Called if map canvas has changed*/ diff --git a/python/core/composer/qgscomposition.sip b/python/core/composer/qgscomposition.sip index e3700d88107..9e26c0764dc 100644 --- a/python/core/composer/qgscomposition.sip +++ b/python/core/composer/qgscomposition.sip @@ -1,29 +1,3 @@ -/** \ingroup MapComposer - * Class used to render an Atlas, iterating over geometry features. - * prepareForFeature() modifies the atlas map's extent to zoom on the given feature. - * This class is used for printing, exporting to PDF and images. - * */ -class QgsAtlasRendering -{ - public: - QgsAtlasRendering( QgsComposition* composition ); - ~QgsAtlasRendering(); - - /** Begins the rendering. Sets an optional output filename pattern */ - void begin( const QString& filenamePattern = "" ); - /** Ends the rendering. Restores original extent*/ - void end(); - - /** Returns the number of features in the coverage layer */ - size_t numFeatures() const; - - /** Prepare the atlas map for the given feature. Sets the extent and context variables */ - void prepareForFeature( size_t i ); - - /** Returns the current filename. Must be called after prepareForFeature( i ) */ - const QString& currentFilename() const; -}; - /** \ingroup MapComposer * Graphics scene for map printing. The class manages the paper item which always * is the item in the back (z-value 0). It maintains the z-Values of the items and stores @@ -145,9 +119,6 @@ class QgsComposition : QGraphicsScene /**Returns pointer to map renderer of qgis map canvas*/ QgsMapRenderer* mapRenderer(); - QgsComposerMap* atlasMap(); - void setAtlasMap( QgsComposerMap* map ); - QgsComposition::PlotStyle plotStyle() const; void setPlotStyle( QgsComposition::PlotStyle style ); diff --git a/python/core/core.sip b/python/core/core.sip index 11af96a8591..43f9c9a302c 100644 --- a/python/core/core.sip +++ b/python/core/core.sip @@ -98,6 +98,7 @@ %Include composer/qgscomposershape.sip %Include composer/qgscomposertable.sip %Include composer/qgscomposition.sip +%Include composer/qgsatlascomposition.sip %Include composer/qgsdoubleboxscalebarstyle.sip %Include composer/qgslegendmodel.sip %Include composer/qgsnumericscalebarstyle.sip diff --git a/tests/src/python/CMakeLists.txt b/tests/src/python/CMakeLists.txt index 9fd32a02450..57c3f2de556 100644 --- a/tests/src/python/CMakeLists.txt +++ b/tests/src/python/CMakeLists.txt @@ -14,5 +14,5 @@ ADD_PYTHON_TEST(PyQgsComposition test_qgscomposition.py) ADD_PYTHON_TEST(PyQgsAnalysis test_qgsanalysis.py) #ADD_PYTHON_TEST(PyQgsComposerMap test_qgscomposermap.py) ADD_PYTHON_TEST(PyQgsSymbolLayerV2 test_qgssymbollayerv2.py) -ADD_PYTHON_TEST(PyQgsComposerMapAtlas test_qgscomposermapatlas.py) +ADD_PYTHON_TEST(PyQgsAtlasComposition test_qgsatlascomposition.py) ADD_PYTHON_TEST(PyQgsComposerLabel test_qgscomposerlabel.py) diff --git a/tests/src/python/test_qgscomposermapatlas.py b/tests/src/python/test_qgsatlascomposition.py similarity index 52% rename from tests/src/python/test_qgscomposermapatlas.py rename to tests/src/python/test_qgsatlascomposition.py index afb0e420b6c..c48e365931d 100644 --- a/tests/src/python/test_qgscomposermapatlas.py +++ b/tests/src/python/test_qgsatlascomposition.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ''' -test_qgscomposermapatlas.py +test_qgsatlascomposition.py -------------------------------------- Date : Oct 2012 Copyright : (C) 2012 by Dr. Hugo Mercier @@ -24,11 +24,11 @@ from qgscompositionchecker import QgsCompositionChecker QGISAPP, CANVAS, IFACE, PARENT = getQgisTestApp() -class TestQgsComposerMapAtlas(unittest.TestCase): +class TestQgsAtlasComposition(unittest.TestCase): def testCase(self): - TEST_DATA_DIR = unitTestDataPath() - vectorFileInfo = QFileInfo( TEST_DATA_DIR + QDir().separator().toAscii() + "france_parts.shp") + self.TEST_DATA_DIR = unitTestDataPath() + vectorFileInfo = QFileInfo( self.TEST_DATA_DIR + QDir().separator().toAscii() + "france_parts.shp") mVectorLayer = QgsVectorLayer( vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr" ) QgsMapLayerRegistry.instance().addMapLayer( mVectorLayer ) @@ -45,8 +45,8 @@ class TestQgsComposerMapAtlas(unittest.TestCase): crs.createFromSrid( 2154 ) mMapRenderer.setDestinationCrs( crs ) - mComposition = QgsComposition( mMapRenderer ) - mComposition.setPaperSize( 297, 210 ) + self.mComposition = QgsComposition( mMapRenderer ) + self.mComposition.setPaperSize( 297, 210 ) # fix the renderer, fill with green props = { "color": "0,127,0" } @@ -55,17 +55,20 @@ class TestQgsComposerMapAtlas(unittest.TestCase): mVectorLayer.setRendererV2( renderer ) # the atlas map - mAtlasMap = QgsComposerMap( mComposition, 20, 20, 130, 130 ) - mAtlasMap.setFrameEnabled( True ) - mAtlasMap.setAtlasCoverageLayer( mVectorLayer ) - mComposition.addComposerMap( mAtlasMap ) - mComposition.setAtlasMap( mAtlasMap ) + self.mAtlasMap = QgsComposerMap( self.mComposition, 20, 20, 130, 130 ) + self.mAtlasMap.setFrameEnabled( True ) + self.mComposition.addComposerMap( self.mAtlasMap ) + + # the atlas + self.mAtlas = QgsAtlasComposition( self.mComposition ) + self.mAtlas.setCoverageLayer( mVectorLayer ) + self.mAtlas.setComposerMap( self.mAtlasMap ) # an overview - mOverview = QgsComposerMap( mComposition, 180, 20, 50, 50 ) + mOverview = QgsComposerMap( self.mComposition, 180, 20, 50, 50 ) mOverview.setFrameEnabled( True ) - mOverview.setOverviewFrameMap( mAtlasMap.id() ) - mComposition.addComposerMap( mOverview ) + mOverview.setOverviewFrameMap( self.mAtlasMap.id() ) + self.mComposition.addComposerMap( mOverview ) nextent = QgsRectangle( 49670.718, 6415139.086, 699672.519, 7065140.887 ) mOverview.setNewExtent( nextent ) @@ -73,103 +76,93 @@ class TestQgsComposerMapAtlas(unittest.TestCase): props2 = { "color": "127,0,0,127" } fillSymbol2 = QgsFillSymbolV2.createSimple( props2 ) mOverview.setOverviewFrameMapSymbol( fillSymbol2 ); - # header label - mLabel1 = QgsComposerLabel( mComposition ) - mComposition.addComposerLabel( mLabel1 ) - mLabel1.setText( "[% \"NAME_1\" %] area" ) - mLabel1.adjustSizeToText() - mLabel1.setItemPosition( 150, 5 ) + self.mLabel1 = QgsComposerLabel( self.mComposition ) + self.mComposition.addComposerLabel( self.mLabel1 ) + self.mLabel1.setText( "[% \"NAME_1\" %] area" ) + self.mLabel1.adjustSizeToText() + self.mLabel1.setItemPosition( 150, 5 ) # feature number label - mLabel2 = QgsComposerLabel( mComposition ) - mComposition.addComposerLabel( mLabel2 ) - mLabel2.setText( "# [%$feature || ' / ' || $numfeatures%]" ) - mLabel2.adjustSizeToText() - mLabel2.setItemPosition( 150, 200 ) + self.mLabel2 = QgsComposerLabel( self.mComposition ) + self.mComposition.addComposerLabel( self.mLabel2 ) + self.mLabel2.setText( "# [%$feature || ' / ' || $numfeatures%]" ) + self.mLabel2.adjustSizeToText() + self.mLabel2.setItemPosition( 150, 200 ) - self.filename_test( mComposition ) - self.autoscale_render_test( mComposition, mLabel1, TEST_DATA_DIR ) - self.fixedscale_render_test( mComposition, mLabel1, TEST_DATA_DIR ) - self.hidden_render_test( mComposition, mLabel1, TEST_DATA_DIR ) + self.filename_test() + self.autoscale_render_test() + self.fixedscale_render_test() + self.hidden_render_test() - def filename_test( self, mComposition ): - atlasRender = QgsAtlasRendering( mComposition ) - atlasRender.begin( "'output_' || $feature" ) - for i in range(0, atlasRender.numFeatures()): - atlasRender.prepareForFeature( i ) + def filename_test( self ): + + self.mAtlas.setFilenamePattern( "'output_' || $feature" ) + self.mAtlas.beginRender() + for i in range(0, self.mAtlas.numFeatures()): + self.mAtlas.prepareForFeature( i ) expected = QString( "output_%1" ).arg(i+1) - print atlasRender.currentFilename() - assert atlasRender.currentFilename() == expected - atlasRender.end() + assert self.mAtlas.currentFilename() == expected + self.mAtlas.endRender() - def autoscale_render_test( self, mComposition, mLabel1, TEST_DATA_DIR ): - atlasMap = mComposition.atlasMap() - atlasMap.setAtlasFixedScale( False ) - atlasMap.setAtlasMargin( 0.10 ) + def autoscale_render_test( self ): + self.mAtlas.setFixedScale( False ) + self.mAtlas.setMargin( 0.10 ) - atlasRender = QgsAtlasRendering( mComposition ) - - atlasRender.begin() + self.mAtlas.beginRender() for i in range(0, 2): - atlasRender.prepareForFeature( i ) - mLabel1.adjustSizeToText() + self.mAtlas.prepareForFeature( i ) + self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker() - res = checker.testComposition( "Atlas autoscale test", mComposition, \ - QString( TEST_DATA_DIR ) + QDir.separator() + \ + res = checker.testComposition( "Atlas autoscale test", self.mComposition, \ + QString( self.TEST_DATA_DIR ) + QDir.separator() + \ "control_images" + QDir.separator() + \ "expected_composermapatlas" + QDir.separator() + \ QString( "autoscale_%1.png" ).arg( i ) ) assert res[0] == True - atlasRender.end() + self.mAtlas.endRender() - def fixedscale_render_test( self, mComposition, mLabel1, TEST_DATA_DIR ): - atlasMap = mComposition.atlasMap() - atlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) ); - atlasMap.setAtlasFixedScale( True ) + def fixedscale_render_test( self ): + self.mAtlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) ); + self.mAtlas.setFixedScale( True ) - atlasRender = QgsAtlasRendering( mComposition ) - - atlasRender.begin() + self.mAtlas.beginRender() for i in range(0, 2): - atlasRender.prepareForFeature( i ) - mLabel1.adjustSizeToText() + self.mAtlas.prepareForFeature( i ) + self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker() - res = checker.testComposition( "Atlas fixed scale test", mComposition, \ - QString( TEST_DATA_DIR ) + QDir.separator() + \ + res = checker.testComposition( "Atlas fixed scale test", self.mComposition, \ + QString( self.TEST_DATA_DIR ) + QDir.separator() + \ "control_images" + QDir.separator() + \ "expected_composermapatlas" + QDir.separator() + \ QString( "fixedscale_%1.png" ).arg( i ) ) assert res[0] == True - atlasRender.end() + self.mAtlas.endRender() - def hidden_render_test( self, mComposition, mLabel1, TEST_DATA_DIR ): - atlasMap = mComposition.atlasMap() - atlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) ); - atlasMap.setAtlasFixedScale( True ) - atlasMap.setAtlasHideCoverage( True ) + def hidden_render_test( self ): + self.mAtlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) ); + self.mAtlas.setFixedScale( True ) + self.mAtlas.setHideCoverage( True ) - atlasRender = QgsAtlasRendering( mComposition ) - - atlasRender.begin() + self.mAtlas.beginRender() for i in range(0, 2): - atlasRender.prepareForFeature( i ) - mLabel1.adjustSizeToText() + self.mAtlas.prepareForFeature( i ) + self.mLabel1.adjustSizeToText() checker = QgsCompositionChecker() - res = checker.testComposition( "Atlas hidden test", mComposition, \ - QString( TEST_DATA_DIR ) + QDir.separator() + \ + res = checker.testComposition( "Atlas hidden test", self.mComposition, \ + QString( self.TEST_DATA_DIR ) + QDir.separator() + \ "control_images" + QDir.separator() + \ "expected_composermapatlas" + QDir.separator() + \ QString( "hiding_%1.png" ).arg( i ) ) assert res[0] == True - atlasRender.end() + self.mAtlas.endRender() if __name__ == '__main__': unittest.main()