Skip to content
Permalink
Browse files

Update of QgsAtlasComposition SIP (with Python unit tests as well)

  • Loading branch information
Hugo Mercier
Hugo Mercier committed Oct 5, 2012
1 parent e4371d8 commit d904da4ce1898c3e86d02dc0143c3e550c46b56e
@@ -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 <qgsatlascomposition.h>
%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();
};
@@ -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*/
@@ -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 );

@@ -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
@@ -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)
@@ -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 @@

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 @@ def testCase(self):
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,121 +55,114 @@ def testCase(self):
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 )

# set the fill symbol of the overview map
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.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.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()
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 )
expected = QString( "output_%1" ).arg(i+1)
print atlasRender.currentFilename()
assert atlasRender.currentFilename() == expected
atlasRender.end()
def filename_test( self ):

def autoscale_render_test( self, mComposition, mLabel1, TEST_DATA_DIR ):
atlasMap = mComposition.atlasMap()
atlasMap.setAtlasFixedScale( False )
atlasMap.setAtlasMargin( 0.10 )
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)
assert self.mAtlas.currentFilename() == expected
self.mAtlas.endRender()

atlasRender = QgsAtlasRendering( mComposition )
def autoscale_render_test( self ):
self.mAtlas.setFixedScale( False )
self.mAtlas.setMargin( 0.10 )

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 )

atlasRender = QgsAtlasRendering( mComposition )
def fixedscale_render_test( self ):
self.mAtlasMap.setNewExtent( QgsRectangle( 209838.166, 6528781.020, 610491.166, 6920530.620 ) );
self.mAtlas.setFixedScale( True )

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()

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 )
self.mAtlas.endRender()

atlasRender = QgsAtlasRendering( mComposition )
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.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()

0 comments on commit d904da4

Please sign in to comment.
You can’t perform that action at this time.