Skip to content

Commit e2bcba5

Browse files
committed
WMTS preview - require a temporary image for updates of the raster
Otherwise we would end up with rendering artifacts due to overpainting
1 parent 6214f6d commit e2bcba5

8 files changed

+32
-2
lines changed

src/core/qgsmaprenderercustompainterjob.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,12 @@ bool QgsMapRendererJob::needTemporaryImage( QgsMapLayer* ml )
333333
return true;
334334
}
335335
}
336+
else if ( ml->type() == QgsMapLayer::RasterLayer )
337+
{
338+
// preview of intermediate raster rendering results requires a temporary output image
339+
if ( mSettings.testFlag( QgsMapSettings::RenderPartialOutput ) )
340+
return true;
341+
}
336342

337343
return false;
338344
}

src/core/qgsmapsettings.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ class CORE_EXPORT QgsMapSettings
164164
UseRenderingOptimization = 0x20, //!< Enable vector simplification and other rendering optimizations
165165
DrawSelection = 0x40, //!< Whether vector selections should be shown in the rendered map
166166
DrawSymbolBounds = 0x80, //!< Draw bounds of symbols (for debugging/testing)
167-
RenderMapTile = 0x100 //!< Draw map such that there are no problems between adjacent tiles
167+
RenderMapTile = 0x100, //!< Draw map such that there are no problems between adjacent tiles
168+
RenderPartialOutput = 0x200, //!< Whether to make extra effort to update map image with partially rendered layers (better for interactive map canvas). Added in QGIS 3.0
168169
// TODO: ignore scale-based visibility (overview)
169170
};
170171
Q_DECLARE_FLAGS( Flags, Flag )

src/core/qgsrendercontext.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ QgsRenderContext QgsRenderContext::fromMapSettings( const QgsMapSettings& mapSet
129129
ctx.setFlag( DrawSymbolBounds, mapSettings.testFlag( QgsMapSettings::DrawSymbolBounds ) );
130130
ctx.setFlag( RenderMapTile, mapSettings.testFlag( QgsMapSettings::RenderMapTile ) );
131131
ctx.setFlag( Antialiasing, mapSettings.testFlag( QgsMapSettings::Antialiasing ) );
132+
ctx.setFlag( RenderPartialOutput, mapSettings.testFlag( QgsMapSettings::RenderPartialOutput ) );
132133
ctx.setRasterScaleFactor( 1.0 );
133134
ctx.setScaleFactor( mapSettings.outputDpi() / 25.4 ); // = pixels per mm
134135
ctx.setRendererScale( mapSettings.scale() );

src/core/qgsrendercontext.h

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class CORE_EXPORT QgsRenderContext
6565
DrawSymbolBounds = 0x20, //!< Draw bounds of symbols (for debugging/testing)
6666
RenderMapTile = 0x40, //!< Draw map such that there are no problems between adjacent tiles
6767
Antialiasing = 0x80, //!< Use antialiasing while drawing
68+
RenderPartialOutput = 0x100, //!< Whether to make extra effort to update map image with partially rendered layers (better for interactive map canvas). Added in QGIS 3.0
6869
};
6970
Q_DECLARE_FLAGS( Flags, Flag )
7071

src/core/raster/qgsrasterdrawer.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,20 @@ void QgsRasterDrawer::draw( QPainter* p, QgsRasterViewPort* viewPort, const QgsM
8888
}
8989
}
9090

91+
if ( feedback && feedback->render_partial_output )
92+
{
93+
// there could have been partial preview written before
94+
// so overwrite anything with the resulting image.
95+
// (we are guaranteed to have a temporary image for this layer, see QgsMapRendererJob::needTemporaryImage)
96+
p->setCompositionMode( QPainter::CompositionMode_Source );
97+
}
98+
9199
drawImage( p, viewPort, img, topLeftCol, topLeftRow, theQgsMapToPixel );
92100

93101
delete block;
94102

103+
p->setCompositionMode( QPainter::CompositionMode_SourceOver ); // go back to the default composition mode
104+
95105
// ok this does not matter much anyway as the tile size quite big so most of the time
96106
// there would be just one tile for the whole display area, but it won't hurt...
97107
if ( feedback && feedback->isCancelled() )

src/core/raster/qgsrasterinterface.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,15 @@
3737
class CORE_EXPORT QgsRasterBlockFeedback : public QgsFeedback
3838
{
3939
public:
40-
QgsRasterBlockFeedback( QObject* parent = nullptr ) : QgsFeedback( parent ), preview_only( false ) {}
40+
QgsRasterBlockFeedback( QObject* parent = nullptr ) : QgsFeedback( parent ), preview_only( false ), render_partial_output( false ) {}
4141

4242
//! whether the raster provider should return only data that are already available
4343
//! without waiting for full result
4444
bool preview_only;
4545

46+
//! whether our painter is drawing to a temporary image used just by this layer
47+
bool render_partial_output;
48+
4649
//! may be emitted by raster data provider to indicate that some partial data are available
4750
//! and a new preview image may be produced
4851
virtual void onNewData() {}

src/core/raster/qgsrasterlayerrenderer.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -231,22 +231,29 @@ MyFeedback::MyFeedback( QgsRasterLayerRenderer *r )
231231
: mR( r )
232232
, mMinimalPreviewInterval( 250 )
233233
{
234+
render_partial_output = r->mContext.testFlag( QgsRenderContext::RenderPartialOutput );
234235
}
235236

236237
void MyFeedback::onNewData()
237238
{
238239
qDebug( "\nGOT NEW DATA!\n" );
239240

241+
if ( !render_partial_output )
242+
return; // we were not asked for partial renders and we may not have a temporary image for overwriting...
243+
240244
// update only once upon a time
241245
// (preview itself takes some time)
242246
if ( mLastPreview.msecsTo( QTime::currentTime() ) < mMinimalPreviewInterval )
243247
return;
244248

249+
// TODO: update only the area that got new data
250+
245251
qDebug( "new raster preview! %d", mLastPreview.msecsTo( QTime::currentTime() ) );
246252
QTime t;
247253
t.start();
248254
QgsRasterBlockFeedback feedback;
249255
feedback.preview_only = true;
256+
feedback.render_partial_output = true;
250257
QgsRasterIterator iterator( mR->mPipe->last() );
251258
QgsRasterDrawer drawer( &iterator );
252259
drawer.draw( mR->mPainter, mR->mRasterViewPort, mR->mMapToPixel, &feedback );

src/gui/qgsmapcanvas.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ QgsMapCanvas::QgsMapCanvas( QWidget * parent )
143143

144144
mSettings.setFlag( QgsMapSettings::DrawEditingInfo );
145145
mSettings.setFlag( QgsMapSettings::UseRenderingOptimization );
146+
mSettings.setFlag( QgsMapSettings::RenderPartialOutput );
146147

147148
//segmentation parameters
148149
QSettings settings;

0 commit comments

Comments
 (0)