Skip to content

Commit

Permalink
qgsrasterlayerrenderer: Change the logic to refresh the renderers
Browse files Browse the repository at this point in the history
This replaces the existing logic in `QgsRasterLayerRenderer` which
calls `QgsRasterLayer::refreshRendererIfNeeded()` to refresh the
renderer associated `QgsRasterLayerRenderer` and the raster associated
with `QgsRasterLayer`. It also makes GUI updates.

With this approach, the following new logic is done:
 1. `QgsRasterRenderer::needsRefresh()` is called to check if
 `rasterRenderer` needs to be updated.
 2. If a refresh is needed, the new min/max values are computed by
 calling `QgsRasterLayer::computeMinMax()`
 3. The min/max values are used to refresh `rasterRenderer`
 4. The min/max values are stored in a `QgsRenderedLayerStatistics`
 and propagated to `QgisApp`
 5. In QgisApp, `QgsRenderedLayerStatistics` is used to refresh the
 renderer of `QgsRasterLayer` and force a refresh of the style and the
 legend if the change comes from the main canvas.
  • Loading branch information
ptitjano authored and nyalldawson committed Nov 28, 2024
1 parent 76cbf8b commit e123726
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 6 deletions.
38 changes: 36 additions & 2 deletions src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,11 @@
#include "qgsbrightnesscontrastfilter.h"
#include "qgsrasterlayersaveasdialog.h"
#include "qgsrasterprojector.h"
#include "qgsrasterrenderer.h"
#include "qgsreadwritecontext.h"
#include "qgsrectangle.h"
#include "qgsrendereditemresults.h"
#include "qgsrenderedlayerstatistics.h"
#include "qgsreport.h"
#include "qgsscalevisibilitydialog.h"
#include "qgsgroupwmsdatadialog.h"
Expand Down Expand Up @@ -5212,12 +5215,19 @@ void QgisApp::createDecorations()
addDecorationItem( decorationScaleBar );
addDecorationItem( decorationLayoutExtent );

connect( mMapCanvas, &QgsMapCanvas::renderComplete, this, &QgisApp::renderDecorationItems );
connect( mMapCanvas, &QgsMapCanvas::renderComplete, this, &QgisApp::onRenderComplete );
connect( this, &QgisApp::newProject, this, &QgisApp::projectReadDecorationItems );
connect( this, &QgisApp::projectRead, this, &QgisApp::projectReadDecorationItems );
}

void QgisApp::renderDecorationItems( QPainter *p )
void QgisApp::onRenderComplete( QPainter *p )
{
renderDecorationItems( p );
handleRenderedLayerStatistics();
}


void QgisApp::renderDecorationItems( QPainter *p ) const
{
QgsRenderContext context = QgsRenderContext::fromMapSettings( mMapCanvas->mapSettings() );
context.setPainter( p );
Expand Down Expand Up @@ -17581,3 +17591,27 @@ void QgisApp::showEvent( QShowEvent *event )
}
} );
}

void QgisApp::handleRenderedLayerStatistics() const
{
const QgsRenderedItemResults *renderedItemResults = mMapCanvas->renderedItemResults( false );
if ( !renderedItemResults )
{
return;
}

for ( const QgsRenderedItemDetails *item : renderedItemResults->renderedItems() )
{
if ( const QgsRenderedLayerStatistics *layerStatistics = dynamic_cast< const QgsRenderedLayerStatistics *>( item ) )
{
QgsRasterLayer *rasterLayer = qobject_cast<QgsRasterLayer *>( QgsProject::instance()->mapLayer( layerStatistics->layerId() ) );
if ( rasterLayer )
{
// refresh the renderer of the layer, the style and the legend of the main canvas
rasterLayer->renderer()->refresh( layerStatistics->boundingBox(), layerStatistics->minimum(), layerStatistics->maximum() );
rasterLayer->emitStyleChanged();
emit rasterLayer->rendererChanged();
}
}
}
}
6 changes: 5 additions & 1 deletion src/app/qgisapp.h
Original file line number Diff line number Diff line change
Expand Up @@ -2050,7 +2050,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
//! Activates label property tool
void changeLabelProperties();

void renderDecorationItems( QPainter *p );
void onRenderComplete( QPainter *p );
void projectReadDecorationItems();

//! clear out any stuff from project
Expand Down Expand Up @@ -2430,6 +2430,10 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
*/
QList< QgsMapToolCapture * > captureTools();

void renderDecorationItems( QPainter *p ) const;

void handleRenderedLayerStatistics() const;

QgsScreenHelper *mScreenHelper = nullptr;

QgisAppStyleSheet *mStyleSheetBuilder = nullptr;
Expand Down
16 changes: 15 additions & 1 deletion src/core/raster/qgsrasterlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1695,7 +1695,21 @@ bool QgsRasterLayer::setSubsetString( const QString &subset )
if ( res )
{
setExtent( mDataProvider->extent() );
refreshRenderer( renderer(), extent() );
QList<double> minValues;
QList<double> maxValues;
const QgsRasterMinMaxOrigin &minMaxOrigin = renderer()->minMaxOrigin();
for ( const int bandIdx : renderer()->usesBands() )
{
double min;
double max;

computeMinMax( bandIdx, minMaxOrigin, minMaxOrigin.limits(),
extent(), static_cast<int>( QgsRasterLayer::SAMPLE_SIZE ),
min, max );
minValues.append( min );
maxValues.append( max );
}
renderer()->refresh( extent(), minValues, maxValues, true );
emit subsetStringChanged();
}

Expand Down
23 changes: 22 additions & 1 deletion src/core/raster/qgsrasterlayerrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "qgsinterval.h"
#include "qgsunittypes.h"
#include "qgsrasternuller.h"
#include "qgsrenderedlayerstatistics.h"

#include <QElapsedTimer>
#include <QPointer>
Expand Down Expand Up @@ -273,7 +274,27 @@ QgsRasterLayerRenderer::QgsRasterLayerRenderer( QgsRasterLayer *layer, QgsRender
&& !( rendererContext.flags() & Qgis::RenderContextFlag::RenderPreviewJob )
&& !( rendererContext.flags() & Qgis::RenderContextFlag::Render3DMap ) )
{
layer->refreshRendererIfNeeded( rasterRenderer, rendererContext.extent() );
if ( rasterRenderer->needsRefresh( rendererContext.extent() ) )
{
QList<double> minValues;
QList<double> maxValues;
const QgsRasterMinMaxOrigin &minMaxOrigin = rasterRenderer->minMaxOrigin();
for ( const int bandIdx : rasterRenderer->usesBands() )
{
double min;
double max;
layer->computeMinMax( bandIdx, minMaxOrigin, minMaxOrigin.limits(),
rendererContext.extent(), static_cast<int>( QgsRasterLayer::SAMPLE_SIZE ),
min, max );
minValues.append( min );
maxValues.append( max );
}

rasterRenderer->refresh( rendererContext.extent(), minValues, maxValues );
QgsRenderedLayerStatistics *layerStatistics = new QgsRenderedLayerStatistics( layer->id(), minValues, maxValues );
layerStatistics->setBoundingBox( rendererContext.extent() );
appendRenderedItemDetails( layerStatistics );
}
}

mPipe->evaluateDataDefinedProperties( rendererContext.expressionContext() );
Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgsmapcanvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,7 @@ void QgsMapCanvas::rendererJobFinished()

QImage img = mJob->renderedImage();

// emit renderComplete to get our decorations drawn
// emit renderComplete to get our decorations drawn and to handle computed statistics
QPainter p( &img );
emit renderComplete( &p );

Expand Down

0 comments on commit e123726

Please sign in to comment.