Skip to content
Permalink
Browse files

WMTS preview - require a temporary image for updates of the raster

Otherwise we would end up with rendering artifacts due to overpainting
  • Loading branch information
wonder-sk committed Aug 30, 2016
1 parent 6214f6d commit e2bcba54d68eee196740e973a6869ab10e1c3785
@@ -333,6 +333,12 @@ bool QgsMapRendererJob::needTemporaryImage( QgsMapLayer* ml )
return true;
}
}
else if ( ml->type() == QgsMapLayer::RasterLayer )
{
// preview of intermediate raster rendering results requires a temporary output image
if ( mSettings.testFlag( QgsMapSettings::RenderPartialOutput ) )
return true;
}

return false;
}
@@ -164,7 +164,8 @@ class CORE_EXPORT QgsMapSettings
UseRenderingOptimization = 0x20, //!< Enable vector simplification and other rendering optimizations
DrawSelection = 0x40, //!< Whether vector selections should be shown in the rendered map
DrawSymbolBounds = 0x80, //!< Draw bounds of symbols (for debugging/testing)
RenderMapTile = 0x100 //!< Draw map such that there are no problems between adjacent tiles
RenderMapTile = 0x100, //!< Draw map such that there are no problems between adjacent tiles
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
// TODO: ignore scale-based visibility (overview)
};
Q_DECLARE_FLAGS( Flags, Flag )
@@ -129,6 +129,7 @@ QgsRenderContext QgsRenderContext::fromMapSettings( const QgsMapSettings& mapSet
ctx.setFlag( DrawSymbolBounds, mapSettings.testFlag( QgsMapSettings::DrawSymbolBounds ) );
ctx.setFlag( RenderMapTile, mapSettings.testFlag( QgsMapSettings::RenderMapTile ) );
ctx.setFlag( Antialiasing, mapSettings.testFlag( QgsMapSettings::Antialiasing ) );
ctx.setFlag( RenderPartialOutput, mapSettings.testFlag( QgsMapSettings::RenderPartialOutput ) );
ctx.setRasterScaleFactor( 1.0 );
ctx.setScaleFactor( mapSettings.outputDpi() / 25.4 ); // = pixels per mm
ctx.setRendererScale( mapSettings.scale() );
@@ -65,6 +65,7 @@ class CORE_EXPORT QgsRenderContext
DrawSymbolBounds = 0x20, //!< Draw bounds of symbols (for debugging/testing)
RenderMapTile = 0x40, //!< Draw map such that there are no problems between adjacent tiles
Antialiasing = 0x80, //!< Use antialiasing while drawing
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
};
Q_DECLARE_FLAGS( Flags, Flag )

@@ -88,10 +88,20 @@ void QgsRasterDrawer::draw( QPainter* p, QgsRasterViewPort* viewPort, const QgsM
}
}

if ( feedback && feedback->render_partial_output )
{
// there could have been partial preview written before
// so overwrite anything with the resulting image.
// (we are guaranteed to have a temporary image for this layer, see QgsMapRendererJob::needTemporaryImage)
p->setCompositionMode( QPainter::CompositionMode_Source );
}

drawImage( p, viewPort, img, topLeftCol, topLeftRow, theQgsMapToPixel );

delete block;

p->setCompositionMode( QPainter::CompositionMode_SourceOver ); // go back to the default composition mode

// ok this does not matter much anyway as the tile size quite big so most of the time
// there would be just one tile for the whole display area, but it won't hurt...
if ( feedback && feedback->isCancelled() )
@@ -37,12 +37,15 @@
class CORE_EXPORT QgsRasterBlockFeedback : public QgsFeedback
{
public:
QgsRasterBlockFeedback( QObject* parent = nullptr ) : QgsFeedback( parent ), preview_only( false ) {}
QgsRasterBlockFeedback( QObject* parent = nullptr ) : QgsFeedback( parent ), preview_only( false ), render_partial_output( false ) {}

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

//! whether our painter is drawing to a temporary image used just by this layer
bool render_partial_output;

//! may be emitted by raster data provider to indicate that some partial data are available
//! and a new preview image may be produced
virtual void onNewData() {}
@@ -231,22 +231,29 @@ MyFeedback::MyFeedback( QgsRasterLayerRenderer *r )
: mR( r )
, mMinimalPreviewInterval( 250 )
{
render_partial_output = r->mContext.testFlag( QgsRenderContext::RenderPartialOutput );
}

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

if ( !render_partial_output )
return; // we were not asked for partial renders and we may not have a temporary image for overwriting...

// update only once upon a time
// (preview itself takes some time)
if ( mLastPreview.msecsTo( QTime::currentTime() ) < mMinimalPreviewInterval )
return;

// TODO: update only the area that got new data

qDebug( "new raster preview! %d", mLastPreview.msecsTo( QTime::currentTime() ) );
QTime t;
t.start();
QgsRasterBlockFeedback feedback;
feedback.preview_only = true;
feedback.render_partial_output = true;
QgsRasterIterator iterator( mR->mPipe->last() );
QgsRasterDrawer drawer( &iterator );
drawer.draw( mR->mPainter, mR->mRasterViewPort, mR->mMapToPixel, &feedback );
@@ -143,6 +143,7 @@ QgsMapCanvas::QgsMapCanvas( QWidget * parent )

mSettings.setFlag( QgsMapSettings::DrawEditingInfo );
mSettings.setFlag( QgsMapSettings::UseRenderingOptimization );
mSettings.setFlag( QgsMapSettings::RenderPartialOutput );

//segmentation parameters
QSettings settings;

0 comments on commit e2bcba5

Please sign in to comment.
You can’t perform that action at this time.