QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
qgsrendererrasterpropertieswidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrendererrasterpropertieswidget.cpp
3  ---------------------
4  begin : May 2016
5  copyright : (C) 2016 by Nathan Woodrow
6  email : woodrow dot nathan at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
16 
17 #include "qgis.h"
18 #include "qgsmapcanvas.h"
19 #include "qgsrasterlayer.h"
30 
31 
33 {
34  static bool initialized = false;
35  if ( initialized )
36  return;
37 
43 
44  initialized = true;
45 }
46 
47 
48 
50  : QgsMapLayerConfigWidget( layer, canvas, parent )
51  , mRendererWidget( nullptr )
52 {
53  mRasterLayer = qobject_cast<QgsRasterLayer*>( layer );
54  if ( !mRasterLayer )
55  return;
56 
57  setupUi( this );
58 
60 
61  mZoomedInResamplingComboBox->insertItem( 0, tr( "Nearest neighbour" ) );
62  mZoomedInResamplingComboBox->insertItem( 1, tr( "Bilinear" ) );
63  mZoomedInResamplingComboBox->insertItem( 2, tr( "Cubic" ) );
64  mZoomedOutResamplingComboBox->insertItem( 0, tr( "Nearest neighbour" ) );
65  mZoomedOutResamplingComboBox->insertItem( 1, tr( "Average" ) );
66 
67  connect( cboRenderers, SIGNAL( currentIndexChanged( int ) ), this, SLOT( rendererChanged() ) );
68 
69  connect( mSliderBrightness, SIGNAL( valueChanged( int ) ), mBrightnessSpinBox, SLOT( setValue( int ) ) );
70  connect( mBrightnessSpinBox, SIGNAL( valueChanged( int ) ), mSliderBrightness, SLOT( setValue( int ) ) );
71 
72  connect( mSliderContrast, SIGNAL( valueChanged( int ) ), mContrastSpinBox, SLOT( setValue( int ) ) );
73  connect( mContrastSpinBox, SIGNAL( valueChanged( int ) ), mSliderContrast, SLOT( setValue( int ) ) );
74 
75  // Connect saturation slider and spin box
76  connect( sliderSaturation, SIGNAL( valueChanged( int ) ), spinBoxSaturation, SLOT( setValue( int ) ) );
77  connect( spinBoxSaturation, SIGNAL( valueChanged( int ) ), sliderSaturation, SLOT( setValue( int ) ) );
78 
79  // Connect colorize strength slider and spin box
80  connect( sliderColorizeStrength, SIGNAL( valueChanged( int ) ), spinColorizeStrength, SLOT( setValue( int ) ) );
81  connect( spinColorizeStrength, SIGNAL( valueChanged( int ) ), sliderColorizeStrength, SLOT( setValue( int ) ) );
82 
83  // enable or disable saturation slider and spin box depending on grayscale combo choice
84  connect( comboGrayscale, SIGNAL( currentIndexChanged( int ) ), this, SLOT( toggleSaturationControls( int ) ) );
85 
86  // enable or disable colorize colorbutton with colorize checkbox
87  connect( mColorizeCheck, SIGNAL( toggled( bool ) ), this, SLOT( toggleColorizeControls( bool ) ) );
88 
89  // Just connect the spin boxes because the sliders update the spinners
90  connect( mBrightnessSpinBox, SIGNAL( valueChanged( int ) ), this, SIGNAL( widgetChanged() ) );
91  connect( mContrastSpinBox, SIGNAL( valueChanged( int ) ), this, SIGNAL( widgetChanged() ) );
92  connect( spinBoxSaturation, SIGNAL( valueChanged( int ) ), this, SIGNAL( widgetChanged() ) );
93  connect( spinColorizeStrength, SIGNAL( valueChanged( int ) ), this, SIGNAL( widgetChanged() ) );
94  connect( btnColorizeColor, SIGNAL( colorChanged( QColor ) ), this, SIGNAL( widgetChanged() ) );
95 
96  connect( mBlendModeComboBox, SIGNAL( currentIndexChanged( int ) ), this, SIGNAL( widgetChanged() ) );
97  connect( mZoomedInResamplingComboBox, SIGNAL( currentIndexChanged( int ) ), this, SIGNAL( widgetChanged() ) );
98  connect( mZoomedOutResamplingComboBox, SIGNAL( currentIndexChanged( int ) ), this, SIGNAL( widgetChanged() ) );
99  connect( mMaximumOversamplingSpinBox, SIGNAL( valueChanged( double ) ), this, SIGNAL( widgetChanged() ) );
100 
101  // finally sync to the layer - even though some actions may emit widgetChanged signal,
102  // this is not a problem - nobody is listening to our signals yet
103  syncToLayer( mRasterLayer );
104 }
105 
107 {
108 
109 }
110 
112 {
113  mMapCanvas = canvas;
114 }
115 
117 {
118  QString rendererName = cboRenderers->itemData( cboRenderers->currentIndex() ).toString();
119  setRendererWidget( rendererName );
120  emit widgetChanged();
121 }
122 
124 {
125  mRasterLayer->brightnessFilter()->setBrightness( mSliderBrightness->value() );
126  mRasterLayer->brightnessFilter()->setContrast( mSliderContrast->value() );
127 
128  QgsRasterRendererWidget* rendererWidget = dynamic_cast<QgsRasterRendererWidget*>( stackedWidget->currentWidget() );
129  if ( rendererWidget )
130  {
131  QgsRasterRenderer* newRenderer = rendererWidget->renderer();
132 
133  // there are transparency related data stored in renderer instances, but they
134  // are not configured in the widget, so we need to copy them over from existing renderer
135  QgsRasterRenderer* oldRenderer = mRasterLayer->renderer();
136  if ( oldRenderer )
137  newRenderer->copyCommonProperties( oldRenderer );
138 
139  mRasterLayer->setRenderer( newRenderer );
140  }
141 
142  // Hue and saturation controls
143  QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
144  if ( hueSaturationFilter )
145  {
146  hueSaturationFilter->setSaturation( sliderSaturation->value() );
147  hueSaturationFilter->setGrayscaleMode(( QgsHueSaturationFilter::GrayscaleMode ) comboGrayscale->currentIndex() );
148  hueSaturationFilter->setColorizeOn( mColorizeCheck->checkState() );
149  hueSaturationFilter->setColorizeColor( btnColorizeColor->color() );
150  hueSaturationFilter->setColorizeStrength( sliderColorizeStrength->value() );
151  }
152 
153  QgsRasterResampleFilter* resampleFilter = mRasterLayer->resampleFilter();
154  if ( resampleFilter )
155  {
156  QgsRasterResampler *zoomedInResampler = nullptr;
157  QString zoomedInResamplingMethod = mZoomedInResamplingComboBox->currentText();
158  if ( zoomedInResamplingMethod == tr( "Bilinear" ) )
159  {
160  zoomedInResampler = new QgsBilinearRasterResampler();
161  }
162  else if ( zoomedInResamplingMethod == tr( "Cubic" ) )
163  {
164  zoomedInResampler = new QgsCubicRasterResampler();
165  }
166 
167  resampleFilter->setZoomedInResampler( zoomedInResampler );
168 
169  //raster resampling
170  QgsRasterResampler *zoomedOutResampler = nullptr;
171  QString zoomedOutResamplingMethod = mZoomedOutResamplingComboBox->currentText();
172  if ( zoomedOutResamplingMethod == tr( "Average" ) )
173  {
174  zoomedOutResampler = new QgsBilinearRasterResampler();
175  }
176 
177  resampleFilter->setZoomedOutResampler( zoomedOutResampler );
178 
179  resampleFilter->setMaxOversampling( mMaximumOversamplingSpinBox->value() );
180  }
181 
182  mRasterLayer->setBlendMode( mBlendModeComboBox->blendMode() );
183 }
184 
186 {
187  mRasterLayer = layer;
188 
189  cboRenderers->blockSignals( true );
190  cboRenderers->clear();
192  Q_FOREACH ( const QString& name, QgsRasterRendererRegistry::instance()->renderersList() )
193  {
194  if ( QgsRasterRendererRegistry::instance()->rendererData( name, entry ) )
195  {
196  if (( mRasterLayer->rasterType() != QgsRasterLayer::ColorLayer && entry.name != "singlebandcolordata" ) ||
197  ( mRasterLayer->rasterType() == QgsRasterLayer::ColorLayer && entry.name == "singlebandcolordata" ) )
198  {
199  cboRenderers->addItem( entry.icon(), entry.visibleName, entry.name );
200  }
201  }
202  }
203  cboRenderers->setCurrentIndex( -1 );
204  cboRenderers->blockSignals( false );
205 
206  QgsRasterRenderer* renderer = mRasterLayer->renderer();
207  if ( renderer )
208  {
209  setRendererWidget( renderer->type() );
210  }
211 
212  QgsBrightnessContrastFilter* brightnessFilter = mRasterLayer->brightnessFilter();
213  if ( brightnessFilter )
214  {
215  mSliderBrightness->setValue( brightnessFilter->brightness() );
216  mSliderContrast->setValue( brightnessFilter->contrast() );
217  }
218 
219  btnColorizeColor->setColorDialogTitle( tr( "Select color" ) );
220  btnColorizeColor->setContext( "symbology" );
221 
222  // Hue and saturation color control
223  const QgsHueSaturationFilter* hueSaturationFilter = mRasterLayer->hueSaturationFilter();
224  //set hue and saturation controls to current values
225  if ( hueSaturationFilter )
226  {
227  sliderSaturation->setValue( hueSaturationFilter->saturation() );
228  comboGrayscale->setCurrentIndex(( int ) hueSaturationFilter->grayscaleMode() );
229 
230  // Set initial state of saturation controls based on grayscale mode choice
231  toggleSaturationControls(( int )hueSaturationFilter->grayscaleMode() );
232 
233  // Set initial state of colorize controls
234  mColorizeCheck->setChecked( hueSaturationFilter->colorizeOn() );
235  btnColorizeColor->setColor( hueSaturationFilter->colorizeColor() );
236  toggleColorizeControls( hueSaturationFilter->colorizeOn() );
237  sliderColorizeStrength->setValue( hueSaturationFilter->colorizeStrength() );
238  }
239 
240  //blend mode
241  mBlendModeComboBox->setBlendMode( mRasterLayer->blendMode() );
242 
243  const QgsRasterResampleFilter* resampleFilter = mRasterLayer->resampleFilter();
244  //set combo boxes to current resampling types
245  if ( resampleFilter )
246  {
247  const QgsRasterResampler* zoomedInResampler = resampleFilter->zoomedInResampler();
248  if ( zoomedInResampler )
249  {
250  if ( zoomedInResampler->type() == "bilinear" )
251  {
252  mZoomedInResamplingComboBox->setCurrentIndex( 1 );
253  }
254  else if ( zoomedInResampler->type() == "cubic" )
255  {
256  mZoomedInResamplingComboBox->setCurrentIndex( 2 );
257  }
258  }
259  else
260  {
261  mZoomedInResamplingComboBox->setCurrentIndex( 0 );
262  }
263 
264  const QgsRasterResampler* zoomedOutResampler = resampleFilter->zoomedOutResampler();
265  if ( zoomedOutResampler )
266  {
267  if ( zoomedOutResampler->type() == "bilinear" ) //bilinear resampler does averaging when zooming out
268  {
269  mZoomedOutResamplingComboBox->setCurrentIndex( 1 );
270  }
271  }
272  else
273  {
274  mZoomedOutResamplingComboBox->setCurrentIndex( 0 );
275  }
276  mMaximumOversamplingSpinBox->setValue( resampleFilter->maxOversampling() );
277  }
278 }
279 
280 void QgsRendererRasterPropertiesWidget::on_mResetColorRenderingBtn_clicked()
281 {
282  mBlendModeComboBox->setBlendMode( QPainter::CompositionMode_SourceOver );
283  mSliderBrightness->setValue( 0 );
284  mSliderContrast->setValue( 0 );
285  sliderSaturation->setValue( 0 );
286  comboGrayscale->setCurrentIndex(( int ) QgsHueSaturationFilter::GrayscaleOff );
287  mColorizeCheck->setChecked( false );
288  sliderColorizeStrength->setValue( 100 );
289 }
290 
291 void QgsRendererRasterPropertiesWidget::toggleSaturationControls( int grayscaleMode )
292 {
293  // Enable or disable saturation controls based on choice of grayscale mode
294  if ( grayscaleMode == 0 )
295  {
296  sliderSaturation->setEnabled( true );
297  spinBoxSaturation->setEnabled( true );
298  }
299  else
300  {
301  sliderSaturation->setEnabled( false );
302  spinBoxSaturation->setEnabled( false );
303  }
304  emit widgetChanged();
305 }
306 
307 void QgsRendererRasterPropertiesWidget::toggleColorizeControls( bool colorizeEnabled )
308 {
309  // Enable or disable colorize controls based on checkbox
310  btnColorizeColor->setEnabled( colorizeEnabled );
311  sliderColorizeStrength->setEnabled( colorizeEnabled );
312  spinColorizeStrength->setEnabled( colorizeEnabled );
313  emit widgetChanged();
314 }
315 
316 void QgsRendererRasterPropertiesWidget::setRendererWidget( const QString &rendererName )
317 {
318  QgsDebugMsg( "rendererName = " + rendererName );
319  QgsRasterRendererWidget* oldWidget = mRendererWidget;
320 
321  QgsRasterRendererRegistryEntry rendererEntry;
322  if ( QgsRasterRendererRegistry::instance()->rendererData( rendererName, rendererEntry ) )
323  {
324  if ( rendererEntry.widgetCreateFunction ) //single band color data renderer e.g. has no widget
325  {
326  QgsDebugMsg( "renderer has widgetCreateFunction" );
327  // Current canvas extent (used to calc min/max) in layer CRS
329  mRendererWidget = rendererEntry.widgetCreateFunction( mRasterLayer, myExtent );
330  mRendererWidget->setMapCanvas( mMapCanvas );
331  connect( mRendererWidget, SIGNAL( widgetChanged() ), this, SIGNAL( widgetChanged() ) );
332  stackedWidget->addWidget( mRendererWidget );
333  stackedWidget->setCurrentWidget( mRendererWidget );
334  if ( oldWidget )
335  {
336  //compare used bands in new and old renderer and reset transparency dialog if different
337  QgsRasterRenderer* oldRenderer = oldWidget->renderer();
338  QgsRasterRenderer* newRenderer = mRendererWidget->renderer();
339  QList<int> oldBands = oldRenderer->usesBands();
340  QList<int> newBands = newRenderer->usesBands();
341 // if ( oldBands != newBands )
342 // {
343 // populateTransparencyTable( newRenderer );
344 // }
345  delete oldRenderer;
346  delete newRenderer;
347  }
348  }
349  }
350 
351  if ( mRendererWidget != oldWidget )
352  delete oldWidget;
353 
354  int widgetIndex = cboRenderers->findData( rendererName );
355  if ( widgetIndex != -1 )
356  {
357  whileBlocking( cboRenderers )->setCurrentIndex( widgetIndex );
358  }
359 
360 }
A panel widget that can be shown in the map style dock.
void setRenderer(QgsRasterRenderer *theRenderer)
Set raster renderer.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
Base class for all map layer types.
Definition: qgsmaplayer.h:49
Cubic Raster Resampler.
void setupUi(QWidget *widget)
Interface for resampling rasters (e.g.
QgsHueSaturationFilter * hueSaturationFilter() const
virtual QList< int > usesBands() const
Returns a list of band numbers used by the renderer.
QgsRasterRendererWidgetCreateFunc widgetCreateFunction
void setColorizeColor(const QColor &colorizeColor)
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
virtual QString type() const
void copyCommonProperties(const QgsRasterRenderer *other)
Copies common properties like opacity / transparency data from other renderer.
QgsRendererRasterPropertiesWidget(QgsMapLayer *layer, QgsMapCanvas *canvas, QWidget *parent=0)
A widget to hold the renderer properties for a raster layer.
Resample filter pipe for rasters.
void syncToLayer(QgsRasterLayer *layer)
Sync the widget to the given layer.
QgsRasterRenderer * renderer() const
void setBlendMode(QPainter::CompositionMode blendMode)
Set the blending mode used for rendering a layer.
QString tr(const char *sourceText, const char *disambiguation, int n)
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:109
virtual void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &theExtent)
QgsBrightnessContrastFilter * brightnessFilter() const
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &theExtent)
const char * name() const
static QgsRasterRendererRegistry * instance()
void apply()
Apply the changes from the dialog to the layer.
virtual QString type() const =0
QgsRectangle extent() const
Returns the current zoom exent of the map canvas.
LayerType rasterType()
Accessor for raster layer type (which is a read only property)
void setColorizeOn(bool colorizeOn)
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &theExtent)
void widgetChanged()
Emitted when the widget state changes.
bool blockSignals(bool block)
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &theExtent)
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
Registry for raster renderer entries.
static void _initRendererWidgetFunctions()
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the dialog.
void rendererChanged()
called when user changes renderer type
QgsHueSaturationFilter::GrayscaleMode grayscaleMode() const
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:333
void setZoomedInResampler(QgsRasterResampler *r)
Set resampler for zoomed in scales.
QgsRasterResampleFilter * resampleFilter() const
Set raster resample filter.
Brightness/contrast filter pipe for rasters.
Bilinear Raster Resampler.
const QgsRasterResampler * zoomedOutResampler() const
Color and saturation filter pipe for rasters.
void setZoomedOutResampler(QgsRasterResampler *r)
Set resampler for zoomed out scales.
void setColorizeStrength(int colorizeStrength)
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
virtual QgsRasterRenderer * renderer()=0
void insertWidgetFunction(const QString &rendererName, QgsRasterRendererWidgetCreateFunc func)
Raster renderer pipe that applies colors to a raster.
QgsRectangle outputExtentToLayerExtent(QgsMapLayer *theLayer, QgsRectangle extent) const
transform bounding box from output CRS to layer&#39;s CRS
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer.
void setGrayscaleMode(QgsHueSaturationFilter::GrayscaleMode grayscaleMode)
void setSaturation(int saturation)
const QgsRasterResampler * zoomedInResampler() const
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &theExtent)
Factory method to create the renderer for this type.