Skip to content

Commit dc7198a

Browse files
authored
Merge pull request #4488 from nirvn/saveasimage_fix_rotated
2 parents a2327d3 + 747c2e2 commit dc7198a

File tree

4 files changed

+59
-22
lines changed

4 files changed

+59
-22
lines changed

src/app/qgisapp.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5804,14 +5804,6 @@ void QgisApp::saveMapAsImage()
58045804
QPair< QString, QString> myFileNameAndFilter = QgisGui::getSaveAsImageName( this, tr( "Choose a file name to save the map image as" ) );
58055805
if ( myFileNameAndFilter.first != QLatin1String( "" ) )
58065806
{
5807-
QSize size = mMapCanvas->size();
5808-
if ( dlg.extent() != mMapCanvas->extent() )
5809-
{
5810-
size.setWidth( mMapCanvas->size().width() * dlg.extent().width() / mMapCanvas->extent().width() );
5811-
size.setHeight( mMapCanvas->size().height() * dlg.extent().height() / mMapCanvas->extent().height() );
5812-
}
5813-
size *= dlg.dpi() / qt_defaultDpiX();
5814-
58155807
QgsMapSettings ms = QgsMapSettings();
58165808
ms.setDestinationCrs( QgsProject::instance()->crs() );
58175809
ms.setExtent( dlg.extent() );

src/app/qgsmapsavedialog.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,23 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
3131

3232
QgsMapSaveDialog::QgsMapSaveDialog( QWidget *parent, QgsMapCanvas *mapCanvas, const QString &activeDecorations )
3333
: QDialog( parent )
34-
, mExtent( mapCanvas->mapSettings().visibleExtent() )
35-
, mDpi( mapCanvas->mapSettings().outputDpi() )
36-
, mSize( mapCanvas->mapSettings().outputSize() )
3734
{
3835
setupUi( this );
3936

37+
// Use unrotated visible extent to insure output size and scale matches canvas
38+
QgsMapSettings ms = mapCanvas->mapSettings();
39+
ms.setRotation( 0 );
40+
mExtent = ms.visibleExtent();
41+
mDpi = ms.outputDpi();
42+
mSize = ms.outputSize();
43+
4044
mResolutionSpinBox->setValue( qt_defaultDpiX() );
4145

42-
mExtentGroupBox->setOutputCrs( mapCanvas->mapSettings().destinationCrs() );
43-
mExtentGroupBox->setCurrentExtent( mExtent, mapCanvas->mapSettings().destinationCrs() );
46+
mExtentGroupBox->setOutputCrs( ms.destinationCrs() );
47+
mExtentGroupBox->setCurrentExtent( mExtent, ms.destinationCrs() );
4448
mExtentGroupBox->setOutputExtentFromCurrent();
4549

46-
mScaleWidget->setScale( 1 / mapCanvas->mapSettings().scale() );
50+
mScaleWidget->setScale( 1 / ms.scale() );
4751
mScaleWidget->setMapCanvas( mapCanvas );
4852
mScaleWidget->setShowCurrentScaleButton( true );
4953

src/core/qgsmapsettingsutils.cpp

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,60 @@
2222

2323
QString QgsMapSettingsUtils::worldFileContent( const QgsMapSettings &mapSettings )
2424
{
25-
double xOrigin = mapSettings.visiblePolygon().at( 0 ).x() + ( mapSettings.mapUnitsPerPixel() / 2 );
26-
double yOrigin = mapSettings.visiblePolygon().at( 0 ).y() - ( mapSettings.mapUnitsPerPixel() / 2 );
25+
QgsMapSettings ms = mapSettings;
26+
27+
double rotation = ms.rotation();
28+
double alpha = rotation / 180 * M_PI;
29+
30+
// reset rotation to 0 to calculate world file parameters
31+
ms.setRotation( 0 );
32+
33+
double xOrigin = ms.visibleExtent().xMinimum() + ( ms.mapUnitsPerPixel() / 2 );
34+
double yOrigin = ms.visibleExtent().yMaximum() - ( ms.mapUnitsPerPixel() / 2 );
35+
36+
double xCenter = ms.visibleExtent().center().x();
37+
double yCenter = ms.visibleExtent().center().y();
38+
39+
// scaling matrix
40+
double s[6];
41+
s[0] = ms.mapUnitsPerPixel();
42+
s[1] = 0;
43+
s[2] = xOrigin;
44+
s[3] = 0;
45+
s[4] = ms.mapUnitsPerPixel();
46+
s[5] = yOrigin;
47+
48+
// rotation matrix
49+
double r[6];
50+
r[0] = cos( alpha );
51+
r[1] = -sin( alpha );
52+
r[2] = xCenter * ( 1 - cos( alpha ) ) + yCenter * sin( alpha );
53+
r[3] = sin( alpha );
54+
r[4] = cos( alpha );
55+
r[5] = - xCenter * sin( alpha ) + yCenter * ( 1 - cos( alpha ) );
56+
57+
// result = rotation x scaling = rotation(scaling(X))
58+
double a = r[0] * s[0] + r[1] * s[3];
59+
double b = r[0] * s[1] + r[1] * s[4];
60+
double c = r[0] * s[2] + r[1] * s[5] + r[2];
61+
double d = r[3] * s[0] + r[4] * s[3];
62+
double e = r[3] * s[1] + r[4] * s[4];
63+
double f = r[3] * s[2] + r[4] * s[5] + r[5];
2764

2865
QString content;
2966
// Pixel XDim
30-
content += qgsDoubleToString( mapSettings.mapUnitsPerPixel() ) + "\r\n";
67+
content += qgsDoubleToString( a ) + "\r\n";
3168
// Rotation on y axis
32-
content += QString( "%1\r\n" ).arg( mapSettings.rotation() );
69+
content += qgsDoubleToString( d ) + "\r\n";
3370
// Rotation on x axis
34-
content += QString( "%1\r\n" ).arg( mapSettings.rotation() );
71+
content += qgsDoubleToString( -b ) + "\r\n";
3572
// Pixel YDim - almost always negative
3673
// See https://en.wikipedia.org/wiki/World_file#cite_ref-3
37-
content += '-' + qgsDoubleToString( mapSettings.mapUnitsPerPixel() ) + "\r\n";
74+
content += "-" + qgsDoubleToString( e ) + "\r\n";
3875
// Origin X (center of top left cell)
39-
content += qgsDoubleToString( xOrigin ) + "\r\n";
76+
content += qgsDoubleToString( c ) + "\r\n";
4077
// Origin Y (center of top left cell)
41-
content += qgsDoubleToString( yOrigin ) + "\r\n";
78+
content += qgsDoubleToString( f ) + "\r\n";
4279

4380
return content;
4481
}

tests/src/core/testqgsmapsettingsutils.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,15 @@ class TestQgsMapSettingsUtils : public QObject
4343
void TestQgsMapSettingsUtils::initTestCase()
4444
{
4545
mMapSettings.setExtent( QgsRectangle( 0, 0, 1, 1 ) );
46+
mMapSettings.setOutputSize( QSize( 1, 1 ) );
4647
}
4748

4849
void TestQgsMapSettingsUtils::createWorldFileContent()
4950
{
5051
QCOMPARE( QgsMapSettingsUtils::worldFileContent( mMapSettings ), QString( "1\r\n0\r\n0\r\n-1\r\n0.5\r\n0.5\r\n" ) );
52+
53+
mMapSettings.setRotation( 45 );
54+
QCOMPARE( QgsMapSettingsUtils::worldFileContent( mMapSettings ), QString( "0.70710678118654757\r\n0.70710678118654746\r\n0.70710678118654746\r\n-0.70710678118654757\r\n0.5\r\n0.49999999999999994\r\n" ) );
5155
}
5256

5357
QGSTEST_MAIN( TestQgsMapSettingsUtils )

0 commit comments

Comments
 (0)