Skip to content

Commit

Permalink
Make raster paletted renderer classify function thread safe
Browse files Browse the repository at this point in the history
In addition to making this correctly thread safe, also avoids a
temporary UI hang during the classification if the layer rendering
is triggered before the classification finishes.
  • Loading branch information
nyalldawson committed Dec 8, 2022
1 parent f5620c3 commit 1d0df14
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 20 deletions.
38 changes: 20 additions & 18 deletions src/gui/raster/qgspalettedrendererwidget.cpp
Expand Up @@ -22,7 +22,6 @@
#include "qgscolordialog.h"
#include "qgssettings.h"
#include "qgsproject.h"
#include "qgscolorrampshaderwidget.h"
#include "qgscolorrampimpl.h"
#include "qgslocaleawarenumericlineeditdelegate.h"

Expand Down Expand Up @@ -840,7 +839,7 @@ void QgsPalettedRendererModel::deleteAll()
//

QgsPalettedRendererClassGatherer::QgsPalettedRendererClassGatherer( QgsRasterLayer *layer, int bandNumber, const QgsPalettedRasterRenderer::ClassData &existingClasses, QgsColorRamp *ramp )
: mLayer( layer )
: mProvider( ( layer && layer->dataProvider() ) ? layer->dataProvider()->clone() : nullptr )
, mBandNumber( bandNumber )
, mRamp( ramp )
, mClasses( existingClasses )
Expand All @@ -855,28 +854,31 @@ void QgsPalettedRendererClassGatherer::run()
mFeedback = new QgsRasterBlockFeedback();
connect( mFeedback, &QgsRasterBlockFeedback::progressChanged, this, &QgsPalettedRendererClassGatherer::progressChanged );

QgsPalettedRasterRenderer::ClassData newClasses = QgsPalettedRasterRenderer::classDataFromRaster( mLayer->dataProvider(), mBandNumber, mRamp.get(), mFeedback );

// combine existing classes with new classes
QgsPalettedRasterRenderer::ClassData::iterator classIt = newClasses.begin();
emit progressChanged( 0 );
qlonglong i = 0;
for ( ; classIt != newClasses.end(); ++classIt )
if ( mProvider )
{
// check if existing classes contains this same class
for ( const QgsPalettedRasterRenderer::Class &existingClass : std::as_const( mClasses ) )
QgsPalettedRasterRenderer::ClassData newClasses = QgsPalettedRasterRenderer::classDataFromRaster( mProvider.get(), mBandNumber, mRamp.get(), mFeedback );

// combine existing classes with new classes
QgsPalettedRasterRenderer::ClassData::iterator classIt = newClasses.begin();
emit progressChanged( 0 );
qlonglong i = 0;
for ( ; classIt != newClasses.end(); ++classIt )
{
if ( existingClass.value == classIt->value )
// check if existing classes contains this same class
for ( const QgsPalettedRasterRenderer::Class &existingClass : std::as_const( mClasses ) )
{
classIt->color = existingClass.color;
classIt->label = existingClass.label;
break;
if ( existingClass.value == classIt->value )
{
classIt->color = existingClass.color;
classIt->label = existingClass.label;
break;
}
}
i ++;
emit progressChanged( 100 * ( i / static_cast<float>( newClasses.count() ) ) );
}
i ++;
emit progressChanged( 100 * ( i / static_cast<float>( newClasses.count() ) ) );
mClasses = newClasses;
}
mClasses = newClasses;

// be overly cautious - it's *possible* stop() might be called between deleting mFeedback and nulling it
mFeedbackMutex.lock();
Expand Down
3 changes: 1 addition & 2 deletions src/gui/raster/qgspalettedrendererwidget.h
Expand Up @@ -23,7 +23,6 @@
#include "qgspalettedrasterrenderer.h"
#include "qgscolorschemelist.h"
#include "qgsrasterlayer.h"
#include "qgsrasterdataprovider.h"
#include "ui_qgspalettedrendererwidgetbase.h"
#include "qgis_gui.h"

Expand Down Expand Up @@ -81,7 +80,7 @@ class QgsPalettedRendererClassGatherer: public QThread

private:

QgsRasterLayer *mLayer = nullptr;
std::unique_ptr< QgsRasterDataProvider > mProvider;
int mBandNumber;
std::unique_ptr< QgsColorRamp > mRamp;
QString mSubstring;
Expand Down

0 comments on commit 1d0df14

Please sign in to comment.