Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge remote-tracking branch 'upstream/master'
  • Loading branch information
luipir committed Sep 8, 2013
2 parents feb79a8 + 5d093f4 commit 3216390
Show file tree
Hide file tree
Showing 10 changed files with 322 additions and 4 deletions.
9 changes: 9 additions & 0 deletions python/core/composer/qgscomposition.sip
Expand Up @@ -133,6 +133,12 @@ class QgsComposition : QGraphicsScene
@note: added in version 1.9*/
void setUseAdvancedEffects( bool effectsEnabled );

bool generateWorldFile() const;
void setGenerateWorldFile( bool enabled );

QgsComposerMap* worldFileMap();
void setWorldFileMap( QgsComposerMap* map );

double selectionTolerance() const;
void setSelectionTolerance( double tol );

Expand Down Expand Up @@ -303,6 +309,9 @@ class QgsComposition : QGraphicsScene
@note added in version 1.9*/
void renderPage( QPainter* p, int page );

/** Compute world file parameters */
void computeWorldFileParameters( double& a, double& b, double& c, double& d, double& e, double& f ) const;

QgsAtlasComposition& atlasComposition();

public slots:
Expand Down
68 changes: 68 additions & 0 deletions src/app/composer/qgscomposer.cpp
Expand Up @@ -995,6 +995,22 @@ void QgsComposer::on_mActionExportAsImage_triggered()
image.save( outputFilePath, fileNExt.second.toLocal8Bit().constData() );
}
}

//
// Write the world file if asked to
if ( mComposition->generateWorldFile() )
{
double a, b, c, d, e, f;
mComposition->computeWorldFileParameters( a, b, c, d, e, f );

QFileInfo fi( fileNExt.first );
// build the world file name
QString worldFileName = fi.absolutePath() + "/" + fi.baseName() + "."
+ fi.suffix()[0] + fi.suffix()[fi.suffix().size()-1] + "w";

writeWorldFile( worldFileName, a, b, c, d, e, f );
}

mView->setPaintingEnabled( true );
}
else
Expand Down Expand Up @@ -1137,6 +1153,21 @@ void QgsComposer::on_mActionExportAsImage_triggered()
image.save( outputFilePath, format.toLocal8Bit().constData() );
}
}

//
// Write the world file if asked to
if ( mComposition->generateWorldFile() )
{
double a, b, c, d, e, f;
mComposition->computeWorldFileParameters( a, b, c, d, e, f );

QFileInfo fi( filename );
// build the world file name
QString worldFileName = fi.absolutePath() + "/" + fi.baseName() + "."
+ fi.suffix()[0] + fi.suffix()[fi.suffix().size()-1] + "w";

writeWorldFile( worldFileName, a, b, c, d, e, f );
}
}
atlasMap->endRender();
mView->setPaintingEnabled( true );
Expand Down Expand Up @@ -1881,6 +1912,24 @@ void QgsComposer::readXML( const QDomElement& composerElem, const QDomDocument&
mComposition->addItemsFromXML( composerElem, doc, &mMapsToRestore );
}

// look for world file composer map, if needed
// Note: this must be done after maps have been added by addItemsFromXML
if ( mComposition->generateWorldFile() )
{
QDomElement compositionElem = compositionNodeList.at( 0 ).toElement();
QgsComposerMap* worldFileMap = 0;
QList<const QgsComposerMap*> maps = mComposition->composerMapItems();
for ( QList<const QgsComposerMap*>::const_iterator it = maps.begin(); it != maps.end(); ++it )
{
if (( *it )->id() == compositionElem.attribute( "worldFileMap" ).toInt() )
{
worldFileMap = const_cast<QgsComposerMap*>( *it );
break;
}
}
mComposition->setWorldFileMap( worldFileMap );
}

mComposition->sortZList();
mView->setComposition( mComposition );

Expand Down Expand Up @@ -2304,3 +2353,22 @@ void QgsComposer::createComposerView()
mView->setVerticalRuler( mVerticalRuler );
mViewLayout->addWidget( mView, 1, 1 );
}

void QgsComposer::writeWorldFile( QString worldFileName, double a, double b, double c, double d, double e, double f ) const
{
QFile worldFile( worldFileName );
if ( !worldFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
{
return;
}
QTextStream fout( &worldFile );

// QString::number does not use locale settings (for the decimal point)
// which is what we want here
fout << QString::number( a, 'f' ) << "\r\n";
fout << QString::number( d, 'f' ) << "\r\n";
fout << QString::number( b, 'f' ) << "\r\n";
fout << QString::number( e, 'f' ) << "\r\n";
fout << QString::number( c, 'f' ) << "\r\n";
fout << QString::number( f, 'f' ) << "\r\n";
}
3 changes: 3 additions & 0 deletions src/app/composer/qgscomposer.h
Expand Up @@ -334,6 +334,9 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
//! Create composer view and rulers
void createComposerView();

//! Write a world file
void writeWorldFile( QString fileName, double a, double b, double c, double d, double e, double f ) const;

/**Composer title*/
QString mTitle;

Expand Down
89 changes: 89 additions & 0 deletions src/app/composer/qgscompositionwidget.cpp
Expand Up @@ -17,6 +17,8 @@
#include <qgis.h>
#include "qgscompositionwidget.h"
#include "qgscomposition.h"
#include "qgscomposermap.h"
#include "qgscomposeritem.h"
#include <QColorDialog>
#include <QWidget>
#include <QPrinter> //for screen resolution
Expand Down Expand Up @@ -49,6 +51,29 @@ QgsCompositionWidget::QgsCompositionWidget( QWidget* parent, QgsComposition* c )
//print as raster
mPrintAsRasterCheckBox->setChecked( mComposition->printAsRaster() );

// world file generation
mGenerateWorldFileCheckBox->setChecked( mComposition->generateWorldFile() );

// populate the map list
mWorldFileMapComboBox->clear();
QList<const QgsComposerMap*> availableMaps = mComposition->composerMapItems();
QList<const QgsComposerMap*>::const_iterator mapItemIt = availableMaps.constBegin();
for ( ; mapItemIt != availableMaps.constEnd(); ++mapItemIt )
{
mWorldFileMapComboBox->addItem( tr( "Map %1" ).arg(( *mapItemIt )->id() ), qVariantFromValue(( void* )*mapItemIt ) );
}

int idx = mWorldFileMapComboBox->findData( qVariantFromValue(( void* )mComposition->worldFileMap() ) );
if ( idx != -1 )
{
mWorldFileMapComboBox->setCurrentIndex( idx );
}

// Connect to addition / removal of maps
connect( mComposition, SIGNAL( composerMapAdded( QgsComposerMap* ) ), this, SLOT( onComposerMapAdded( QgsComposerMap* ) ) );
connect( mComposition, SIGNAL( itemRemoved( QgsComposerItem* ) ), this, SLOT( onItemRemoved( QgsComposerItem* ) ) );


mAlignmentSnapGroupCheckBox->setChecked( mComposition->alignmentSnap() );
mAlignmentToleranceSpinBox->setValue( mComposition->alignmentSnapTolerance() );

Expand Down Expand Up @@ -412,6 +437,70 @@ void QgsCompositionWidget::on_mPrintAsRasterCheckBox_toggled( bool state )
mComposition->setPrintAsRaster( state );
}

void QgsCompositionWidget::on_mGenerateWorldFileCheckBox_toggled( bool state )
{
if ( !mComposition )
{
return;
}

mComposition->setGenerateWorldFile( state );
mWorldFileMapComboBox->setEnabled( state );
}

void QgsCompositionWidget::onComposerMapAdded( QgsComposerMap* map )
{
if ( !mComposition )
{
return;
}

mWorldFileMapComboBox->addItem( tr( "Map %1" ).arg( map->id() ), qVariantFromValue(( void* )map ) );
if ( mWorldFileMapComboBox->count() == 1 )
{
mComposition->setWorldFileMap( map );
}
}

void QgsCompositionWidget::onItemRemoved( QgsComposerItem* item )
{
if ( !mComposition )
{
return;
}

QgsComposerMap* map = dynamic_cast<QgsComposerMap*>( item );
if ( map )
{
int idx = mWorldFileMapComboBox->findData( qVariantFromValue(( void* )map ) );
if ( idx != -1 )
{
mWorldFileMapComboBox->removeItem( idx );
}
}
if ( mWorldFileMapComboBox->count() == 0 )
{
mComposition->setWorldFileMap( 0 );
}
}

void QgsCompositionWidget::on_mWorldFileMapComboBox_currentIndexChanged( int index )
{
if ( !mComposition )
{
return;
}
if ( index == -1 )
{
mComposition->setWorldFileMap( 0 );
}
else
{
QgsComposerMap* map = reinterpret_cast<QgsComposerMap*>( mWorldFileMapComboBox->itemData( index ).value<void*>() );
mComposition->setWorldFileMap( map );
}
}

void QgsCompositionWidget::on_mSnapToGridGroupCheckBox_toggled( bool state )
{
if ( mComposition )
Expand Down
10 changes: 10 additions & 0 deletions src/app/composer/qgscompositionwidget.h
Expand Up @@ -17,6 +17,8 @@
#include "ui_qgscompositionwidgetbase.h"

class QgsComposition;
class QgsComposerMap;
class QgsComposerItem;

/** \ingroup MapComposer
* Struct to hold map composer paper properties.
Expand Down Expand Up @@ -48,6 +50,8 @@ class QgsCompositionWidget: public QWidget, private Ui::QgsCompositionWidgetBase
void on_mNumPagesSpinBox_valueChanged( int value );
void on_mResolutionSpinBox_valueChanged( const int value );
void on_mPrintAsRasterCheckBox_toggled( bool state );
void on_mGenerateWorldFileCheckBox_toggled( bool state );
void on_mWorldFileMapComboBox_currentIndexChanged( int index );

void on_mSnapToGridGroupCheckBox_toggled( bool state );
void on_mGridResolutionSpinBox_valueChanged( double d );
Expand All @@ -65,6 +69,12 @@ class QgsCompositionWidget: public QWidget, private Ui::QgsCompositionWidgetBase
/**Sets Print as raster checkbox value*/
void setPrintAsRasterCheckBox( bool state );

private slots:
/* when a new map is added */
void onComposerMapAdded( QgsComposerMap* );
/* when a map is deleted */
void onItemRemoved( QgsComposerItem* );

private:
QgsComposition* mComposition;
QMap<QString, QgsCompositionPaper> mPaperMap;
Expand Down
73 changes: 73 additions & 0 deletions src/core/composer/qgscomposition.cpp
Expand Up @@ -54,6 +54,8 @@ QgsComposition::QgsComposition( QgsMapRenderer* mapRenderer )
, mPageHeight( 210 )
, mSpaceBetweenPages( 10 )
, mPrintAsRaster( false )
, mGenerateWorldFile( false )
, mWorldFileMap( 0 )
, mUseAdvancedEffects( true )
, mSelectionTolerance( 0.0 )
, mSnapToGrid( false )
Expand Down Expand Up @@ -81,6 +83,8 @@ QgsComposition::QgsComposition()
mPageHeight( 210 ),
mSpaceBetweenPages( 10 ),
mPrintAsRaster( false ),
mGenerateWorldFile( false ),
mWorldFileMap( 0 ),
mUseAdvancedEffects( true ),
mSelectionTolerance( 0.0 ),
mSnapToGrid( false ),
Expand Down Expand Up @@ -420,6 +424,12 @@ bool QgsComposition::writeXML( QDomElement& composerElem, QDomDocument& doc )
compositionElem.setAttribute( "printResolution", mPrintResolution );
compositionElem.setAttribute( "printAsRaster", mPrintAsRaster );

compositionElem.setAttribute( "generateWorldFile", mGenerateWorldFile ? 1 : 0 );
if ( mGenerateWorldFile && mWorldFileMap )
{
compositionElem.setAttribute( "worldFileMap", mWorldFileMap->id() );
}

compositionElem.setAttribute( "alignmentSnap", mAlignmentSnap ? 1 : 0 );
compositionElem.setAttribute( "alignmentSnapTolerance", mAlignmentSnapTolerance );

Expand Down Expand Up @@ -505,6 +515,8 @@ bool QgsComposition::readXML( const QDomElement& compositionElem, const QDomDocu
mPrintAsRaster = compositionElem.attribute( "printAsRaster" ).toInt();
mPrintResolution = compositionElem.attribute( "printResolution", "300" ).toInt();

mGenerateWorldFile = compositionElem.attribute( "generateWorldFile", "0" ).toInt() == 1 ? true : false;

updatePaperItems();

return true;
Expand Down Expand Up @@ -2174,3 +2186,64 @@ bool QgsComposition::nearestItem( const QMap< double, const QgsComposerItem* >&
}
}

void QgsComposition::computeWorldFileParameters( double& a, double& b, double& c, double& d, double& e, double& f ) const
{
//
// Word file parameters : affine transformation parameters from pixel coordinates to map coordinates

if ( !mWorldFileMap )
{
return;
}

QRectF brect = mWorldFileMap->boundingRect();
QgsRectangle extent = mWorldFileMap->extent();

double alpha = mWorldFileMap->rotation() / 180 * M_PI;

double xr = extent.width() / brect.width();
double yr = extent.height() / brect.height();

double XC = extent.center().x();
double YC = extent.center().y();

// get the extent for the page
double xmin = extent.xMinimum() - mWorldFileMap->transform().dx() * xr;
double ymax = extent.yMaximum() + mWorldFileMap->transform().dy() * yr;
QgsRectangle paperExtent( xmin, ymax - paperHeight() * yr, xmin + paperWidth() * xr, ymax );

double X0 = paperExtent.xMinimum();
double Y0 = paperExtent.yMinimum();

int widthPx = ( int )( printResolution() * paperWidth() / 25.4 );
int heightPx = ( int )( printResolution() * paperHeight() / 25.4 );

double Ww = paperExtent.width() / widthPx;
double Hh = paperExtent.height() / heightPx;

// scaling matrix
double s[6];
s[0] = Ww;
s[1] = 0;
s[2] = X0;
s[3] = 0;
s[4] = -Hh;
s[5] = Y0 + paperExtent.height();

// rotation matrix
double r[6];
r[0] = cos( alpha );
r[1] = -sin( alpha );
r[2] = XC * ( 1 - cos( alpha ) ) + YC * sin( alpha );
r[3] = sin( alpha );
r[4] = cos( alpha );
r[5] = - XC * sin( alpha ) + YC * ( 1 - cos( alpha ) );

// result = rotation x scaling = rotation(scaling(X))
a = r[0] * s[0] + r[1] * s[3];
b = r[0] * s[1] + r[1] * s[4];
c = r[0] * s[2] + r[1] * s[5] + r[2];
d = r[3] * s[0] + r[4] * s[3];
e = r[3] * s[1] + r[4] * s[4];
f = r[3] * s[2] + r[4] * s[5] + r[5];
}

0 comments on commit 3216390

Please sign in to comment.