QGIS API Documentation  2.99.0-Master (d55fa22)
qgspalettedrendererwidget.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgspalettedrendererwidget.h
3  ---------------------------
4  begin : February 2012
5  copyright : (C) 2012 by Marco Hugentobler
6  email : marco at sourcepole dot ch
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #ifndef QGSPALETTEDRENDERERWIDGET_H
19 #define QGSPALETTEDRENDERERWIDGET_H
20 
23 #include "qgscolorschemelist.h"
24 #include "qgsrasterlayer.h"
25 #include "qgsrasterdataprovider.h"
26 #include "ui_qgspalettedrendererwidgetbase.h"
27 #include "qgis_gui.h"
28 
29 class QgsRasterLayer;
30 
32 
36 class QgsPalettedRendererClassGatherer: public QThread
37 {
38  Q_OBJECT
39 
40  public:
41  QgsPalettedRendererClassGatherer( QgsRasterLayer *layer, int bandNumber, const QgsPalettedRasterRenderer::ClassData &existingClasses, QgsColorRamp *ramp = nullptr )
42  : mLayer( layer )
43  , mBandNumber( bandNumber )
44  , mRamp( ramp )
45  , mClasses( existingClasses )
46  , mFeedback( nullptr )
47  , mWasCanceled( false )
48  {}
49 
50  virtual void run() override
51  {
52  mWasCanceled = false;
53 
54  // allow responsive cancelation
55  mFeedback = new QgsRasterBlockFeedback();
56  connect( mFeedback, &QgsRasterBlockFeedback::progressChanged, this, &QgsPalettedRendererClassGatherer::progressChanged );
57 
58  QgsPalettedRasterRenderer::ClassData newClasses = QgsPalettedRasterRenderer::classDataFromRaster( mLayer->dataProvider(), mBandNumber, mRamp.get(), mFeedback );
59 
60  // combine existing classes with new classes
61  QgsPalettedRasterRenderer::ClassData::iterator classIt = newClasses.begin();
62  for ( ; classIt != newClasses.end(); ++classIt )
63  {
64  // check if existing classes contains this same class
65  Q_FOREACH ( const QgsPalettedRasterRenderer::Class &existingClass, mClasses )
66  {
67  if ( existingClass.value == classIt->value )
68  {
69  classIt->color = existingClass.color;
70  classIt->label = existingClass.label;
71  break;
72  }
73  }
74  }
75  mClasses = newClasses;
76 
77  // be overly cautious - it's *possible* stop() might be called between deleting mFeedback and nulling it
78  mFeedbackMutex.lock();
79  delete mFeedback;
80  mFeedback = nullptr;
81  mFeedbackMutex.unlock();
82 
83  emit collectedClasses();
84  }
85 
87  void stop()
88  {
89  // be cautious, in case gatherer stops naturally just as we are canceling it and mFeedback gets deleted
90  mFeedbackMutex.lock();
91  if ( mFeedback )
92  mFeedback->cancel();
93  mFeedbackMutex.unlock();
94 
95  mWasCanceled = true;
96  }
97 
99  bool wasCanceled() const { return mWasCanceled; }
100 
101  QgsPalettedRasterRenderer::ClassData classes() const { return mClasses; }
102 
103  signals:
104 
107  void collectedClasses();
108 
109  signals:
111  void canceled();
112 
113  void progressChanged( double progress );
114 
115  private:
116 
117  QgsRasterLayer *mLayer = nullptr;
118  int mBandNumber;
119  std::unique_ptr< QgsColorRamp > mRamp;
120  QString mSubstring;
122  QgsRasterBlockFeedback *mFeedback = nullptr;
123  QMutex mFeedbackMutex;
124  bool mWasCanceled;
125 };
126 
127 class QgsPalettedRendererModel : public QAbstractItemModel
128 {
129  Q_OBJECT
130 
131  public:
132 
133  enum Column
134  {
135  ValueColumn = 0,
136  ColorColumn = 1,
137  LabelColumn = 2,
138  };
139 
140  QgsPalettedRendererModel( QObject *parent = nullptr );
141 
142  void setClassData( const QgsPalettedRasterRenderer::ClassData &data );
143 
144  QgsPalettedRasterRenderer::ClassData classData() const { return mData; }
145 
146  QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const override;
147  QModelIndex parent( const QModelIndex &index ) const override;
148  int columnCount( const QModelIndex &parent = QModelIndex() ) const override;
149  int rowCount( const QModelIndex &parent = QModelIndex() ) const override;
150  QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override;
151  QVariant headerData( int section, Qt::Orientation orientation, int role ) const override;
152  bool setData( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole ) override;
153  Qt::ItemFlags flags( const QModelIndex &index ) const override;
154  bool removeRows( int row, int count, const QModelIndex &parent = QModelIndex() ) override;
155  virtual bool insertRows( int row, int count, const QModelIndex &parent = QModelIndex() ) override;
156  Qt::DropActions supportedDropActions() const override;
157  QStringList mimeTypes() const override;
158  QMimeData *mimeData( const QModelIndexList &indexes ) const override;
159  bool dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent ) override;
160 
161  void addEntry( const QColor &color );
162 
163  signals:
164 
165  void classesChanged();
166 
167  private:
168 
170 
171 
172 };
174 
178 class GUI_EXPORT QgsPalettedRendererWidget: public QgsRasterRendererWidget, private Ui::QgsPalettedRendererWidgetBase
179 {
180  Q_OBJECT
181 
182  public:
183 
186  static QgsRasterRendererWidget *create( QgsRasterLayer *layer, const QgsRectangle &extent ) { return new QgsPalettedRendererWidget( layer, extent ); }
187 
188  QgsRasterRenderer *renderer() override;
189 
190  void setFromRenderer( const QgsRasterRenderer *r );
191 
192  private:
193 
194  QMenu *contextMenu = nullptr;
195  QgsPalettedRendererModel *mModel = nullptr;
196  QgsColorSwatchDelegate *mSwatchDelegate = nullptr;
197 
199  QgsPalettedRendererClassGatherer *mGatherer = nullptr;
200 
201  void setSelectionColor( const QItemSelection &selection, const QColor &color );
202 
203  private slots:
204 
205  void deleteEntry();
206  void addEntry();
207  void changeColor();
208  void changeOpacity();
209  void changeLabel();
210  void applyColorRamp();
211  void loadColorTable();
212  void saveColorTable();
213  void classify();
214  void loadFromLayer();
215 
216  void gatheredClasses();
217  void gathererThreadFinished();
218  void layerWillBeRemoved( QgsMapLayer *layer );
219 
220 };
221 
222 #endif // QGSPALETTEDRENDERERWIDGET_H
A rectangle specified with double values.
Definition: qgsrectangle.h:38
Base class for all map layer types.
Definition: qgsmaplayer.h:54
QColor color
Color to render value.
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
Abstract base class for color ramps.
Definition: qgscolorramp.h:30
Properties of a single value class.
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
static QgsPalettedRasterRenderer::ClassData classDataFromRaster(QgsRasterInterface *raster, int bandNumber, QgsColorRamp *ramp=nullptr, QgsRasterBlockFeedback *feedback=nullptr)
Generates class data from a raster, for the specified bandNumber.
QList< Class > ClassData
Map of value to class properties.
Feedback object tailored for raster block reading.
Raster renderer pipe that applies colors to a raster.
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &extent)
A delegate for showing a color swatch in a list.