Skip to content

Commit

Permalink
Merge pull request #42245 from m-kuhn/getprint_size
Browse files Browse the repository at this point in the history
Allow specifying width and height for GetPrint images
  • Loading branch information
m-kuhn committed Mar 22, 2021
2 parents c0633e8 + 7efbb69 commit c260136
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 3 deletions.
6 changes: 4 additions & 2 deletions src/core/layout/qgslayoutexporter.cpp
Expand Up @@ -199,12 +199,14 @@ QImage QgsLayoutExporter::renderPageToImage( int page, QSize imageSize, double d

QRectF paperRect = QRectF( pageItem->pos().x(), pageItem->pos().y(), pageItem->rect().width(), pageItem->rect().height() );

if ( imageSize.isValid() && ( !qgsDoubleNear( static_cast< double >( imageSize.width() ) / imageSize.height(),
paperRect.width() / paperRect.height(), 0.008 ) ) )
const double imageAspectRatio = static_cast< double >( imageSize.width() ) / imageSize.height();
const double paperAspectRatio = paperRect.width() / paperRect.height();
if ( imageSize.isValid() && ( !qgsDoubleNear( imageAspectRatio, paperAspectRatio, 0.008 ) ) )
{
// specified image size is wrong aspect ratio for paper rect - so ignore it and just use dpi
// this can happen e.g. as a result of data defined page sizes
// see https://github.com/qgis/QGIS/issues/26422
QgsMessageLog::logMessage( QObject::tr( "Ignoring custom image size because aspect ratio %1 does not match paper ratio %2" ).arg( QString::number( imageAspectRatio, 'g', 3 ), QString::number( paperAspectRatio, 'g', 3 ) ), QStringLiteral( "Layout" ), Qgis::Warning );
imageSize = QSize();
}

Expand Down
28 changes: 27 additions & 1 deletion src/server/services/wms/qgswmsrenderer.cpp
Expand Up @@ -495,9 +495,35 @@ namespace QgsWms
exportSettings.flags |= QgsLayoutRenderContext::FlagDrawSelection;
// Destination image size in px
QgsLayoutSize layoutSize( layout->pageCollection()->page( 0 )->sizeWithUnits() );

QgsLayoutMeasurement width( layout->convertFromLayoutUnits( layoutSize.width(), QgsUnitTypes::LayoutUnit::LayoutMillimeters ) );
QgsLayoutMeasurement height( layout->convertFromLayoutUnits( layoutSize.height(), QgsUnitTypes::LayoutUnit::LayoutMillimeters ) );
exportSettings.imageSize = QSize( static_cast<int>( width.length() * dpi / 25.4 ), static_cast<int>( height.length() * dpi / 25.4 ) );

const QSize imageSize = QSize( static_cast<int>( width.length() * dpi / 25.4 ), static_cast<int>( height.length() * dpi / 25.4 ) );

const QString paramWidth = mWmsParameters.width();
const QString paramHeight = mWmsParameters.height();

// Prefer width and height from the http request
// Fallback to predefined values from layout
// Preserve aspect ratio if only one value is specified
if ( !paramWidth.isEmpty() && !paramHeight.isEmpty() )
{
exportSettings.imageSize = QSize( paramWidth.toInt(), paramHeight.toInt() );
}
else if ( !paramWidth.isEmpty() && paramHeight.isEmpty() )
{
exportSettings.imageSize = QSize( paramWidth.toInt(), static_cast<double>( paramWidth.toInt() ) / imageSize.width() * imageSize.height() );
}
else if ( paramWidth.isEmpty() && !paramHeight.isEmpty() )
{
exportSettings.imageSize = QSize( static_cast<double>( paramHeight.toInt() ) / imageSize.height() * imageSize.width(), paramHeight.toInt() );
}
else
{
exportSettings.imageSize = imageSize;
}

// Export first page only (unless it's a pdf, see below)
exportSettings.pages.append( 0 );
if ( atlas )
Expand Down
20 changes: 20 additions & 0 deletions tests/src/python/test_qgsserver_wms_getprint.py
Expand Up @@ -25,6 +25,8 @@

from test_qgsserver import QgsServerTestBase

from qgis.PyQt.QtCore import QSize


class TestQgsServerWMSGetPrint(QgsServerTestBase):
"""QGIS Server WMS Tests for GetPrint request"""
Expand Down Expand Up @@ -274,6 +276,24 @@ def test_wms_getprint_scale(self):
r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetPrint_Scale")

def test_wms_getprint_size(self):
qs = "?" + "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetPrint",
"TEMPLATE": "layoutA4",
"FORMAT": "png",
"map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
"map0:LAYERS": "Country,Hello",
"map0:SCALE": "36293562",
"CRS": "EPSG:3857",
"HEIGHT": "100"
}.items())])

r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetPrint_Size", max_size_diff=QSize(1, 1))

def test_wms_getprint_grid(self):
qs = "?" + "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit c260136

Please sign in to comment.