Skip to content

Commit

Permalink
Fix inconcequent use of DPI at generating the WMS legend
Browse files Browse the repository at this point in the history
- Consider DPI of QgsWmsRenderContext what is the OGC default (0.28 mm per pixel) or the passed WMS parameter - this is done by creating the QgsRenderContext by the mapSettings (with BBOX) or applying the dotsPerMm to the scaleFactor.

- Additionally the image size needs to be calculated according to the QgsRenderContext now, what means it needs to be generated before.

- The QPainter needs to be applied after to the context (since it's not passed by creating the context anymore).
  • Loading branch information
signedav authored and nyalldawson committed Apr 1, 2023
1 parent 50adba3 commit f926eb4
Showing 1 changed file with 27 additions and 9 deletions.
36 changes: 27 additions & 9 deletions src/server/services/wms/qgswmsrenderer.cpp
Expand Up @@ -132,27 +132,45 @@ namespace QgsWms
QgsLegendSettings settings = legendSettings();
QgsLegendRenderer renderer( &model, settings );

// create image
// create context
QgsRenderContext context;
if ( !mWmsParameters.bbox().isEmpty() )
{
QgsMapSettings mapSettings;
mapSettings.setFlag( Qgis::MapSettingsFlag::RenderBlocking );
std::unique_ptr<QImage> tmp( createImage( mContext.mapSize( false ) ) );
configureMapSettings( tmp.get(), mapSettings );
context = QgsRenderContext::fromMapSettings( mapSettings );
}
else
{
context.setScaleFactor( mContext.dotsPerMm() );
const double mmPerMapUnit = 1 / QgsServerProjectUtils::wmsDefaultMapUnitsPerMm( *mProject );
context.setMapToPixel( QgsMapToPixel( 1 / ( mmPerMapUnit * context.scaleFactor() ) ) );
}

// create image according to context
std::unique_ptr<QImage> image;
const qreal dpmm = mContext.dotsPerMm();
const QSizeF minSize = renderer.minimumSize();
const QSizeF minSize = renderer.minimumSize( &context );
const QSize size( static_cast<int>( minSize.width() * dpmm ), static_cast<int>( minSize.height() * dpmm ) );
if ( !mContext.isValidWidthHeight( size.width(), size.height() ) )
{
throw QgsServerException( QStringLiteral( "Legend image is too large" ) );
}
image.reset( createImage( size ) );

// configure painter
// configure painter and addapt to the context
QPainter painter( image.get() );
QgsRenderContext context = QgsRenderContext::fromQPainter( &painter );

context.setPainter( &painter );
if ( painter.renderHints() & QPainter::SmoothPixmapTransform )
context.setFlag( Qgis::RenderContextFlag::HighQualityImageTransforms, true );
if ( painter.renderHints() & QPainter::LosslessImageRendering )
context.setFlag( Qgis::RenderContextFlag::LosslessImageRendering, true );

context.setFlag( Qgis::RenderContextFlag::Antialiasing, true );
QgsScopedRenderContextScaleToMm scaleContext( context );
// QGIS 4.0 -- take from real render context instead
Q_NOWARN_DEPRECATED_PUSH
context.setRendererScale( settings.mapScale() );
context.setMapToPixel( QgsMapToPixel( 1 / ( settings.mmPerMapUnit() * context.scaleFactor() ) ) );
Q_NOWARN_DEPRECATED_POP

// rendering
renderer.drawLegend( context );
Expand Down

0 comments on commit f926eb4

Please sign in to comment.