Skip to content

Commit

Permalink
fix destruction of private members in atlas and add sip bindings (als…
Browse files Browse the repository at this point in the history
…o adds

CORE_EXPORT)
  • Loading branch information
jef-n committed Sep 29, 2012
1 parent 0c29b4b commit 686f632
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 81 deletions.
57 changes: 50 additions & 7 deletions python/core/composer/qgscomposition.sip
@@ -1,10 +1,36 @@
/** \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
* them in a list in ascending z-Order. This list can be changed to lower/raise items one position
* or to bring them to front/back.
* */
class QgsComposition: QGraphicsScene
class QgsComposition : QGraphicsScene
{
%TypeHeaderCode
#include <qgscomposition.h>
Expand Down Expand Up @@ -67,20 +93,25 @@ class QgsComposition: QGraphicsScene
/**Returns pointer to undo/redo command storage*/
QUndoStack* undoStack();

/**Returns the topmose composer item. Ignores mPaperItem*/
/**Returns the topmost composer item. Ignores mPaperItem*/
QgsComposerItem* composerItemAt( const QPointF & position );

/** Returns the page number (0-bsaed) given a coordinate */
int pageNumberAt( const QPointF& position ) const;

/** Returns on which page number (0-based) is displayed an item */
int itemPageNumber( const QgsComposerItem* ) const;

QList<QgsComposerItem*> selectedComposerItems();

/**Returns pointers to all composer maps in the scene*/
//todo: needs a new mapping for QList<const T*> ?
// QList<const QgsComposerMap*> composerMapItems() const;
QList<const QgsComposerMap*> composerMapItems() const;

/**Return composer items of a specific type*/
// template<class T> void composerItems( QList<T*>& itemList );

/**Returns the composer map with specified id
@return id or 0 pointer if the composer map item does not exist*/
@return QgsComposerMap or 0 pointer if the composer map item does not exist*/
const QgsComposerMap* getComposerMapById( int id ) const;

/*Returns the composer html with specified id (a string as named in the
Expand Down Expand Up @@ -111,7 +142,10 @@ class QgsComposition: QGraphicsScene
/**Returns pointer to map renderer of qgis map canvas*/
QgsMapRenderer* mapRenderer();

QgsComposition::PlotStyle plotStyle();
QgsComposerMap* atlasMap();
void setAtlasMap( QgsComposerMap* map );

QgsComposition::PlotStyle plotStyle() const;
void setPlotStyle( QgsComposition::PlotStyle style );

/**Returns the pixel font size for a font that has point size set.
Expand Down Expand Up @@ -219,10 +253,19 @@ class QgsComposition: QGraphicsScene

//printing

void exportAsPDF( const QString& file );
/** Prepare the printer for printing */
void beginPrint( QPrinter& printer );
/** Prepare the printer for printing in a PDF */
void beginPrintAsPDF( QPrinter& printer, const QString& file );
/** Print on a preconfigured printer */
void doPrint( QPrinter& printer, QPainter& painter );

/** Convenience function that prepares the printer and prints */
void print( QPrinter &printer );

/** Convenience function that prepares the printer for printing in PDF and prints */
void exportAsPDF( const QString& file );

//! print composer page to image
//! If the image does not fit into memory, a null image is returned
QImage printPageAsRaster( int page );
Expand Down
117 changes: 61 additions & 56 deletions src/core/composer/qgscomposition.cpp
Expand Up @@ -67,11 +67,16 @@ struct QgsAtlasRendering::QgsAtlasRenderingImpl

QgsAtlasRendering::QgsAtlasRendering( QgsComposition* composition )
{
impl = std::auto_ptr<QgsAtlasRendering::QgsAtlasRenderingImpl>( new QgsAtlasRendering::QgsAtlasRenderingImpl() );
impl = new QgsAtlasRendering::QgsAtlasRenderingImpl();
impl->composition = composition;
impl->nFeatures = 0;
}

QgsAtlasRendering::~QgsAtlasRendering()
{
delete impl;
}

void QgsAtlasRendering::begin( const QString& filenamePattern )
{
if ( !impl->composition || !impl->composition->atlasMap() || !impl->composition->atlasMap()->atlasCoverageLayer() )
Expand Down Expand Up @@ -131,7 +136,7 @@ void QgsAtlasRendering::begin( const QString& filenamePattern )
}

// special columns for expressions
QgsExpression::setSpecialColumn( "$numfeatures", QVariant( (int)impl->nFeatures ) );
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )impl->nFeatures ) );
}

void QgsAtlasRendering::prepareForFeature( size_t featureI )
Expand All @@ -140,24 +145,24 @@ void QgsAtlasRendering::prepareForFeature( size_t featureI )
return;

QgsFeature* fit = &impl->features[featureI];

if ( impl->filenamePattern.size() > 0 )
{
QgsExpression::setSpecialColumn( "$feature", QVariant( (int)featureI + 1 ) );
QgsExpression::setSpecialColumn( "$feature", QVariant(( int )featureI + 1 ) );
QVariant filenameRes = impl->filenameExpr->evaluate( &*fit );
if ( impl->filenameExpr->hasEvalError() )
{
throw std::runtime_error( "Filename eval error: " + impl->filenameExpr->evalErrorString().toStdString() );
}

impl->currentFilename = filenameRes.toString();
}

//
// compute the new extent
// keep the original aspect ratio
// and apply a margin

// QgsGeometry::boundingBox is expressed in the geometry"s native CRS
// We have to transform the grometry to the destination CRS and ask for the bounding box
// Note: we cannot directly take the transformation of the bounding box, since transformations are not linear
Expand All @@ -171,63 +176,63 @@ void QgsAtlasRendering::prepareForFeature( size_t featureI )
double ya1 = geom_rect.yMinimum();
double ya2 = geom_rect.yMaximum();
QgsRectangle new_extent = geom_rect;

// restore the original extent
// (successive calls to setNewExtent tend to deform the original rectangle)
impl->composition->atlasMap()->setNewExtent( impl->origExtent );

if ( impl->composition->atlasMap()->atlasFixedScale() )
{
// only translate, keep the original scale (i.e. width x height)
double geom_center_x = (xa1 + xa2) / 2.0;
double geom_center_y = (ya1 + ya2) / 2.0;

double geom_center_x = ( xa1 + xa2 ) / 2.0;
double geom_center_y = ( ya1 + ya2 ) / 2.0;
double xx = geom_center_x - impl->origExtent.width() / 2.0;
double yy = geom_center_y - impl->origExtent.height() / 2.0;
new_extent = QgsRectangle( xx,
yy,
xx + impl->origExtent.width(),
yy + impl->origExtent.height() );
yy,
xx + impl->origExtent.width(),
yy + impl->origExtent.height() );
}
else
{
// auto scale

double geom_ratio = geom_rect.width() / geom_rect.height();
double map_ratio = impl->origExtent.width() / impl->origExtent.height();

// geometry height is too big
if ( geom_ratio < map_ratio )
{
new_extent = QgsRectangle( (xa1 + xa2 + map_ratio * (ya1 - ya2)) / 2.0,
ya1,
xa1 + map_ratio * (ya2 - ya1),
ya2);
new_extent = QgsRectangle(( xa1 + xa2 + map_ratio * ( ya1 - ya2 ) ) / 2.0,
ya1,
xa1 + map_ratio * ( ya2 - ya1 ),
ya2 );
}
// geometry width is too big
else if ( geom_ratio > map_ratio )
{
new_extent = QgsRectangle( xa1,
(ya1 + ya2 + (xa1 - xa2) / map_ratio) / 2.0,
xa2,
ya1 + (xa2 - xa1) / map_ratio);
( ya1 + ya2 + ( xa1 - xa2 ) / map_ratio ) / 2.0,
xa2,
ya1 + ( xa2 - xa1 ) / map_ratio );
}
if ( impl->composition->atlasMap()->atlasMargin() > 0.0 )
{
new_extent.scale( 1 + impl->composition->atlasMap()->atlasMargin() );
}
}

// evaluate label expressions
QList<QgsComposerLabel*> labels;
impl->composition->composerItems( labels );
QgsExpression::setSpecialColumn( "$feature", QVariant( (int)featureI + 1 ) );
QgsExpression::setSpecialColumn( "$feature", QVariant(( int )featureI + 1 ) );

for ( QList<QgsComposerLabel*>::iterator lit = labels.begin(); lit != labels.end(); ++lit )
{
(*lit)->setExpressionContext( fit, impl->composition->atlasMap()->atlasCoverageLayer() );
( *lit )->setExpressionContext( fit, impl->composition->atlasMap()->atlasCoverageLayer() );
}

// set the new extent (and render)
impl->composition->atlasMap()->setNewExtent( new_extent );
}
Expand All @@ -252,7 +257,7 @@ void QgsAtlasRendering::end()
impl->composition->composerItems( labels );
for ( QList<QgsComposerLabel*>::iterator lit = labels.begin(); lit != labels.end(); ++lit )
{
(*lit)->setExpressionContext( 0, 0 );
( *lit )->setExpressionContext( 0, 0 );
}

// restore the coverage visibility
Expand All @@ -269,9 +274,9 @@ void QgsAtlasRendering::end()
}

QgsComposition::QgsComposition( QgsMapRenderer* mapRenderer ) :
QGraphicsScene( 0 ), mMapRenderer( mapRenderer ), mPlotStyle( QgsComposition::Preview ), mPageWidth( 297 ), mPageHeight( 210 ), mSpaceBetweenPages( 10 ), mPrintAsRaster( false ), mSelectionTolerance( 0.0 ),
mSnapToGrid( false ), mSnapGridResolution( 0.0 ), mSnapGridOffsetX( 0.0 ), mSnapGridOffsetY( 0.0 ), mActiveItemCommand( 0 ), mActiveMultiFrameCommand( 0 ),
mAtlasMap( 0 )
QGraphicsScene( 0 ), mMapRenderer( mapRenderer ), mPlotStyle( QgsComposition::Preview ), mPageWidth( 297 ), mPageHeight( 210 ), mSpaceBetweenPages( 10 ), mPrintAsRaster( false ), mSelectionTolerance( 0.0 ),
mSnapToGrid( false ), mSnapGridResolution( 0.0 ), mSnapGridOffsetX( 0.0 ), mSnapGridOffsetY( 0.0 ), mActiveItemCommand( 0 ), mActiveMultiFrameCommand( 0 ),
mAtlasMap( 0 )
{
setBackgroundBrush( Qt::gray );
addPaperItem();
Expand All @@ -280,23 +285,23 @@ QgsComposition::QgsComposition( QgsMapRenderer* mapRenderer ) :
loadSettings();

// declare special columns with a default value
QgsExpression::setSpecialColumn( "$page", QVariant((int)0) );
QgsExpression::setSpecialColumn( "$feature", QVariant((int)0) );
QgsExpression::setSpecialColumn( "$numpages", QVariant((int)0) );
QgsExpression::setSpecialColumn( "$numfeatures", QVariant((int)0) );
QgsExpression::setSpecialColumn( "$page", QVariant(( int )0 ) );
QgsExpression::setSpecialColumn( "$feature", QVariant(( int )0 ) );
QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )0 ) );
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )0 ) );
}

QgsComposition::QgsComposition():
QGraphicsScene( 0 ), mMapRenderer( 0 ), mPlotStyle( QgsComposition::Preview ), mPageWidth( 297 ), mPageHeight( 210 ), mSpaceBetweenPages( 10 ), mPrintAsRaster( false ),
mSelectionTolerance( 0.0 ), mSnapToGrid( false ), mSnapGridResolution( 0.0 ), mSnapGridOffsetX( 0.0 ), mSnapGridOffsetY( 0.0 ), mActiveItemCommand( 0 ), mActiveMultiFrameCommand( 0 ),
mAtlasMap( 0 )
QGraphicsScene( 0 ), mMapRenderer( 0 ), mPlotStyle( QgsComposition::Preview ), mPageWidth( 297 ), mPageHeight( 210 ), mSpaceBetweenPages( 10 ), mPrintAsRaster( false ),
mSelectionTolerance( 0.0 ), mSnapToGrid( false ), mSnapGridResolution( 0.0 ), mSnapGridOffsetX( 0.0 ), mSnapGridOffsetY( 0.0 ), mActiveItemCommand( 0 ), mActiveMultiFrameCommand( 0 ),
mAtlasMap( 0 )
{
loadSettings();

QgsExpression::setSpecialColumn( "$page", QVariant((int)0) );
QgsExpression::setSpecialColumn( "$feature", QVariant((int)0) );
QgsExpression::setSpecialColumn( "$numpages", QVariant((int)0) );
QgsExpression::setSpecialColumn( "$numfeatures", QVariant((int)0) );
QgsExpression::setSpecialColumn( "$page", QVariant(( int )0 ) );
QgsExpression::setSpecialColumn( "$feature", QVariant(( int )0 ) );
QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )0 ) );
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )0 ) );
}

QgsComposition::~QgsComposition()
Expand Down Expand Up @@ -356,7 +361,7 @@ void QgsComposition::setNumPages( int pages )
}

// update the corresponding variable
QgsExpression::setSpecialColumn( "$numpages", QVariant((int)numPages()) );
QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )numPages() ) );

emit nPagesChanged();
}
Expand Down Expand Up @@ -394,12 +399,12 @@ QgsComposerItem* QgsComposition::composerItemAt( const QPointF & position )

int QgsComposition::pageNumberAt( const QPointF& position ) const
{
return position.y() / (paperHeight() + spaceBetweenPages() );
return position.y() / ( paperHeight() + spaceBetweenPages() );
}

int QgsComposition::itemPageNumber( const QgsComposerItem* item ) const
{
return pageNumberAt( QPointF( item->transform().dx(), item->transform().dy()) );
return pageNumberAt( QPointF( item->transform().dx(), item->transform().dy() ) );
}

QList<QgsComposerItem*> QgsComposition::selectedComposerItems()
Expand Down Expand Up @@ -1715,7 +1720,7 @@ void QgsComposition::addPaperItem()
paperItem->setZValue( 0 );
mPages.push_back( paperItem );

QgsExpression::setSpecialColumn( "$numpages", QVariant((int)mPages.size()) );
QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )mPages.size() ) );
}

void QgsComposition::removePaperItems()
Expand All @@ -1725,7 +1730,7 @@ void QgsComposition::removePaperItems()
delete mPages.at( i );
}
mPages.clear();
QgsExpression::setSpecialColumn( "$numpages", QVariant((int)0) );
QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )0 ) );
}

void QgsComposition::deleteAndRemoveMultiFrames()
Expand Down Expand Up @@ -1756,7 +1761,7 @@ void QgsComposition::exportAsPDF( const QString& file )

void QgsComposition::doPrint( QPrinter& printer, QPainter& p )
{
//QgsComposition starts page numbering at 0
//QgsComposition starts page numbering at 0
int fromPage = ( printer.fromPage() < 1 ) ? 0 : printer.fromPage() - 1 ;
int toPage = ( printer.toPage() < 1 ) ? numPages() - 1 : printer.toPage() - 1;

Expand Down Expand Up @@ -1859,11 +1864,11 @@ void QgsComposition::setAtlasMap( QgsComposerMap* map )
mAtlasMap = map;
if ( map != 0 )
{
QObject::connect( map, SIGNAL( atlasCoverageLayerChanged( QgsVectorLayer* )), this, SLOT( onAtlasCoverageChanged( QgsVectorLayer* ) ) );
QObject::connect( map, SIGNAL( atlasCoverageLayerChanged( QgsVectorLayer* ) ), this, SLOT( onAtlasCoverageChanged( QgsVectorLayer* ) ) );
}
else
{
QObject::disconnect( map, SIGNAL( atlasCoverageLayerChanged( QgsVectorLayer* )), this, SLOT( onAtlasCoverageChanged( QgsVectorLayer* ) ) );
QObject::disconnect( map, SIGNAL( atlasCoverageLayerChanged( QgsVectorLayer* ) ), this, SLOT( onAtlasCoverageChanged( QgsVectorLayer* ) ) );
}
}

Expand All @@ -1873,14 +1878,14 @@ void QgsComposition::onAtlasCoverageChanged( QgsVectorLayer* )
if ( mAtlasMap != 0 && mAtlasMap->atlasCoverageLayer() != 0 )
{
QgsVectorDataProvider* provider = mAtlasMap->atlasCoverageLayer()->dataProvider();
QgsExpression::setSpecialColumn( "$numfeatures", QVariant( (int)provider->featureCount() ) );
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )provider->featureCount() ) );
}
else
{
QgsExpression::setSpecialColumn( "$numfeatures", QVariant( (int)0 ) );
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )0 ) );
}
//
QgsExpression::setSpecialColumn( "$numpages", QVariant( (int)numPages() ) );
//
QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )numPages() ) );
}

QString QgsComposition::encodeStringForXML( const QString& str )
Expand Down

0 comments on commit 686f632

Please sign in to comment.