QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgspointcloudclassifiedrendererwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgspointcloudclassifiedrendererwidget.cpp
3  ---------------------
4  begin : November 2020
5  copyright : (C) 2020 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
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 
19 #include "qgscontrastenhancement.h"
20 #include "qgspointcloudlayer.h"
22 #include "qgsdoublevalidator.h"
23 #include "qgsstyle.h"
24 #include "qgsguiutils.h"
25 #include "qgscompoundcolorwidget.h"
26 #include "qgscolordialog.h"
27 #include "qgsapplication.h"
28 #include "qgscolorschemeregistry.h"
30 
31 #include <QMimeData>
32 
34 
35 QgsPointCloudClassifiedRendererModel::QgsPointCloudClassifiedRendererModel( QObject *parent )
36  : QAbstractItemModel( parent )
37  , mMimeFormat( QStringLiteral( "application/x-qgspointcloudclassifiedrenderermodel" ) )
38 {
39 }
40 
41 void QgsPointCloudClassifiedRendererModel::setRendererCategories( const QgsPointCloudCategoryList &categories )
42 {
43  if ( !mCategories.empty() )
44  {
45  beginRemoveRows( QModelIndex(), 0, std::max< int >( mCategories.size() - 1, 0 ) );
46  mCategories.clear();
47  endRemoveRows();
48  }
49  if ( categories.size() > 0 )
50  {
51  beginInsertRows( QModelIndex(), 0, categories.size() - 1 );
52  mCategories = categories;
53  endInsertRows();
54  }
55 }
56 
57 void QgsPointCloudClassifiedRendererModel::addCategory( const QgsPointCloudCategory &cat )
58 {
59  const int idx = mCategories.size();
60  beginInsertRows( QModelIndex(), idx, idx );
61  mCategories.append( cat );
62  endInsertRows();
63 
64  emit categoriesChanged();
65 }
66 
67 QgsPointCloudCategory QgsPointCloudClassifiedRendererModel::category( const QModelIndex &index )
68 {
69  const int row = index.row();
70  if ( row >= mCategories.size() )
71  {
72  return QgsPointCloudCategory();
73  }
74  return mCategories.at( row );
75 }
76 
77 Qt::ItemFlags QgsPointCloudClassifiedRendererModel::flags( const QModelIndex &index ) const
78 {
79  if ( !index.isValid() || mCategories.empty() )
80  {
81  return Qt::ItemIsDropEnabled;
82  }
83 
84  Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable;
85  if ( index.column() == 1 )
86  {
87  flags |= Qt::ItemIsEditable;
88  }
89  else if ( index.column() == 2 )
90  {
91  flags |= Qt::ItemIsEditable;
92  }
93  return flags;
94 }
95 
96 Qt::DropActions QgsPointCloudClassifiedRendererModel::supportedDropActions() const
97 {
98  return Qt::MoveAction;
99 }
100 
101 QVariant QgsPointCloudClassifiedRendererModel::data( const QModelIndex &index, int role ) const
102 {
103  if ( !index.isValid() || mCategories.empty() )
104  return QVariant();
105 
106  const QgsPointCloudCategory category = mCategories.value( index.row() );
107 
108  switch ( role )
109  {
110  case Qt::CheckStateRole:
111  {
112  if ( index.column() == 0 )
113  {
114  return category.renderState() ? Qt::Checked : Qt::Unchecked;
115  }
116  break;
117  }
118 
119  case Qt::DisplayRole:
120  case Qt::ToolTipRole:
121  {
122  switch ( index.column() )
123  {
124  case 1:
125  {
126  return QString::number( category.value() );
127  }
128  case 2:
129  return category.label();
130  case 3:
131  const float value = mPercentages.value( category.value(), -1 );
132  QString str;
133  if ( value < 0 )
134  str = tr( "N/A" );
135  else if ( value != 0 && std::round( value * 10 ) < 1 )
136  str = QStringLiteral( "< " ) + QLocale().toString( 0.1, 'f', 1 );
137  else
138  str = QLocale().toString( mPercentages.value( category.value() ), 'f', 1 );
139  return str;
140  }
141  break;
142  }
143 
144  case Qt::DecorationRole:
145  {
146  if ( index.column() == 0 )
147  {
148  const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
149  QPixmap pix( iconSize, iconSize );
150  pix.fill( category.color() );
151  return QIcon( pix );
152  }
153  break;
154  }
155 
156  case Qt::TextAlignmentRole:
157  {
158  if ( index.column() == 0 )
159  return static_cast<Qt::Alignment::Int>( Qt::AlignHCenter );
160  if ( index.column() == 3 )
161  return static_cast<Qt::Alignment::Int>( Qt::AlignRight );
162  return static_cast<Qt::Alignment::Int>( Qt::AlignLeft );
163  }
164 
165  case Qt::EditRole:
166  {
167  switch ( index.column() )
168  {
169  case 1:
170  {
171  return QString::number( category.value() );
172  }
173 
174  case 2:
175  return category.label();
176  }
177  break;
178  }
179  }
180 
181  return QVariant();
182 }
183 
184 bool QgsPointCloudClassifiedRendererModel::setData( const QModelIndex &index, const QVariant &value, int role )
185 {
186  if ( !index.isValid() )
187  return false;
188 
189  if ( index.column() == 0 && role == Qt::CheckStateRole )
190  {
191  mCategories[ index.row() ].setRenderState( value == Qt::Checked );
192  emit dataChanged( index, index );
193  emit categoriesChanged();
194  return true;
195  }
196 
197  if ( role != Qt::EditRole )
198  return false;
199 
200  switch ( index.column() )
201  {
202  case 1: // value
203  {
204  const int val = value.toInt();
205  mCategories[ index.row() ].setValue( val );
206  break;
207  }
208  case 2: // label
209  {
210  mCategories[ index.row() ].setLabel( value.toString() );
211  break;
212  }
213  default:
214  return false;
215  }
216 
217  emit dataChanged( index, index );
218  emit categoriesChanged();
219  return true;
220 }
221 
222 QVariant QgsPointCloudClassifiedRendererModel::headerData( int section, Qt::Orientation orientation, int role ) const
223 {
224  if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 && section < 4 )
225  {
226  QStringList lst;
227  lst << tr( "Color" ) << tr( "Value" ) << tr( "Legend" ) << tr( "Percentage" );
228  return lst.value( section );
229  }
230  return QVariant();
231 }
232 
233 int QgsPointCloudClassifiedRendererModel::rowCount( const QModelIndex &parent ) const
234 {
235  if ( parent.isValid() )
236  {
237  return 0;
238  }
239  return mCategories.size();
240 }
241 
242 int QgsPointCloudClassifiedRendererModel::columnCount( const QModelIndex &index ) const
243 {
244  Q_UNUSED( index )
245  return 4;
246 }
247 
248 QModelIndex QgsPointCloudClassifiedRendererModel::index( int row, int column, const QModelIndex &parent ) const
249 {
250  if ( hasIndex( row, column, parent ) )
251  {
252  return createIndex( row, column );
253  }
254  return QModelIndex();
255 }
256 
257 QModelIndex QgsPointCloudClassifiedRendererModel::parent( const QModelIndex &index ) const
258 {
259  Q_UNUSED( index )
260  return QModelIndex();
261 }
262 
263 QStringList QgsPointCloudClassifiedRendererModel::mimeTypes() const
264 {
265  QStringList types;
266  types << mMimeFormat;
267  return types;
268 }
269 
270 QMimeData *QgsPointCloudClassifiedRendererModel::mimeData( const QModelIndexList &indexes ) const
271 {
272  QMimeData *mimeData = new QMimeData();
273  QByteArray encodedData;
274 
275  QDataStream stream( &encodedData, QIODevice::WriteOnly );
276 
277  // Create list of rows
278  const auto constIndexes = indexes;
279  for ( const QModelIndex &index : constIndexes )
280  {
281  if ( !index.isValid() || index.column() != 0 )
282  continue;
283 
284  stream << index.row();
285  }
286  mimeData->setData( mMimeFormat, encodedData );
287  return mimeData;
288 }
289 
290 bool QgsPointCloudClassifiedRendererModel::dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent )
291 {
292  Q_UNUSED( row )
293  Q_UNUSED( column )
294  if ( action != Qt::MoveAction )
295  return true;
296 
297  if ( !data->hasFormat( mMimeFormat ) )
298  return false;
299 
300  QByteArray encodedData = data->data( mMimeFormat );
301  QDataStream stream( &encodedData, QIODevice::ReadOnly );
302 
303  QVector<int> rows;
304  while ( !stream.atEnd() )
305  {
306  int r;
307  stream >> r;
308  rows.append( r );
309  }
310 
311  int to = parent.row();
312  // to is -1 if dragged outside items, i.e. below any item,
313  // then move to the last position
314  if ( to == -1 )
315  to = mCategories.size(); // out of rang ok, will be decreased
316  for ( int i = rows.size() - 1; i >= 0; i-- )
317  {
318  int t = to;
319  if ( rows[i] < t )
320  t--;
321 
322  if ( !( rows[i] < 0 || rows[i] >= mCategories.size() || t < 0 || t >= mCategories.size() ) )
323  {
324  mCategories.move( rows[i], t );
325  }
326 
327  // current moved under another, shift its index up
328  for ( int j = 0; j < i; j++ )
329  {
330  if ( to < rows[j] && rows[i] > rows[j] )
331  rows[j] += 1;
332  }
333  // removed under 'to' so the target shifted down
334  if ( rows[i] < to )
335  to--;
336  }
337  emit dataChanged( createIndex( 0, 0 ), createIndex( mCategories.size(), 0 ) );
338  emit categoriesChanged();
339  return false;
340 }
341 
342 void QgsPointCloudClassifiedRendererModel::deleteRows( QList<int> rows )
343 {
344  std::sort( rows.begin(), rows.end() ); // list might be unsorted, depending on how the user selected the rows
345  for ( int i = rows.size() - 1; i >= 0; i-- )
346  {
347  beginRemoveRows( QModelIndex(), rows[i], rows[i] );
348  mCategories.removeAt( rows[i] );
349  endRemoveRows();
350  }
351  emit categoriesChanged();
352 }
353 
354 void QgsPointCloudClassifiedRendererModel::removeAllRows()
355 {
356  beginRemoveRows( QModelIndex(), 0, mCategories.size() - 1 );
357  mCategories.clear();
358  endRemoveRows();
359  emit categoriesChanged();
360 }
361 
362 void QgsPointCloudClassifiedRendererModel::setCategoryColor( int row, const QColor &color )
363 {
364  mCategories[row].setColor( color );
365  emit dataChanged( createIndex( row, 0 ), createIndex( row, 0 ) );
366  emit categoriesChanged();
367 }
368 
369 // ------------------------------ View style --------------------------------
370 QgsPointCloudClassifiedRendererViewStyle::QgsPointCloudClassifiedRendererViewStyle( QWidget *parent )
371  : QgsProxyStyle( parent )
372 {}
373 
374 void QgsPointCloudClassifiedRendererViewStyle::drawPrimitive( PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget ) const
375 {
376  if ( element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull() )
377  {
378  QStyleOption opt( *option );
379  opt.rect.setLeft( 0 );
380  // draw always as line above, because we move item to that index
381  opt.rect.setHeight( 0 );
382  if ( widget )
383  opt.rect.setRight( widget->width() );
384  QProxyStyle::drawPrimitive( element, &opt, painter, widget );
385  return;
386  }
387  QProxyStyle::drawPrimitive( element, option, painter, widget );
388 }
389 
390 
391 QgsPointCloudClassifiedRendererWidget::QgsPointCloudClassifiedRendererWidget( QgsPointCloudLayer *layer, QgsStyle *style )
392  : QgsPointCloudRendererWidget( layer, style )
393 {
394  setupUi( this );
395 
396  mAttributeComboBox->setAllowEmptyAttributeName( true );
398 
399  mModel = new QgsPointCloudClassifiedRendererModel( this );
400 
401  if ( layer )
402  {
403  mAttributeComboBox->setLayer( layer );
404 
405  setFromRenderer( layer->renderer() );
406  }
407 
408  viewCategories->setModel( mModel );
409  viewCategories->resizeColumnToContents( 0 );
410  viewCategories->resizeColumnToContents( 1 );
411  viewCategories->resizeColumnToContents( 2 );
412 
413  viewCategories->setStyle( new QgsPointCloudClassifiedRendererViewStyle( viewCategories ) );
414 
415  connect( mAttributeComboBox, &QgsPointCloudAttributeComboBox::attributeChanged,
416  this, &QgsPointCloudClassifiedRendererWidget::attributeChanged );
417  connect( mModel, &QgsPointCloudClassifiedRendererModel::categoriesChanged, this, &QgsPointCloudClassifiedRendererWidget::emitWidgetChanged );
418 
419  connect( viewCategories, &QAbstractItemView::doubleClicked, this, &QgsPointCloudClassifiedRendererWidget::categoriesDoubleClicked );
420  connect( btnAddCategories, &QAbstractButton::clicked, this, &QgsPointCloudClassifiedRendererWidget::addCategories );
421  connect( btnDeleteCategories, &QAbstractButton::clicked, this, &QgsPointCloudClassifiedRendererWidget::deleteCategories );
422  connect( btnDeleteAllCategories, &QAbstractButton::clicked, this, &QgsPointCloudClassifiedRendererWidget::deleteAllCategories );
423  connect( btnAddCategory, &QAbstractButton::clicked, this, &QgsPointCloudClassifiedRendererWidget::addCategory );
424 
425 }
426 
427 QgsPointCloudRendererWidget *QgsPointCloudClassifiedRendererWidget::create( QgsPointCloudLayer *layer, QgsStyle *style, QgsPointCloudRenderer * )
428 {
429  return new QgsPointCloudClassifiedRendererWidget( layer, style );
430 }
431 
432 QgsPointCloudRenderer *QgsPointCloudClassifiedRendererWidget::renderer()
433 {
434  if ( !mLayer )
435  {
436  return nullptr;
437  }
438 
439  std::unique_ptr< QgsPointCloudClassifiedRenderer > renderer = std::make_unique< QgsPointCloudClassifiedRenderer >();
440  renderer->setAttribute( mAttributeComboBox->currentAttribute() );
441  renderer->setCategories( mModel->categories() );
442 
443  return renderer.release();
444 }
445 
446 QgsPointCloudCategoryList QgsPointCloudClassifiedRendererWidget::categoriesList()
447 {
448  return mModel->categories();
449 }
450 
451 QString QgsPointCloudClassifiedRendererWidget::attribute()
452 {
453  return mAttributeComboBox->currentAttribute();
454 }
455 
456 void QgsPointCloudClassifiedRendererWidget::attributeChanged()
457 {
458  if ( mBlockChangedSignal )
459  return;
460 
461  mBlockChangedSignal = true;
462  mModel->removeAllRows();
463  mBlockChangedSignal = false;
464  addCategories();
465 }
466 
467 void QgsPointCloudClassifiedRendererWidget::emitWidgetChanged()
468 {
469  if ( mBlockChangedSignal )
470  return;
471 
472  updateCategoriesPercentages();
473  emit widgetChanged();
474 }
475 
476 void QgsPointCloudClassifiedRendererWidget::categoriesDoubleClicked( const QModelIndex &idx )
477 {
478  if ( idx.isValid() && idx.column() == 0 )
479  changeCategorySymbol();
480 }
481 
482 void QgsPointCloudClassifiedRendererWidget::addCategories()
483 {
484  if ( !mLayer || !mLayer->dataProvider() )
485  return;
486 
487 
488  const QString currentAttribute = mAttributeComboBox->currentAttribute();
489  const QgsPointCloudStatistics stats = mLayer->statistics();
490  const QList<int> providerCategories = stats.classesOf( currentAttribute );
491 
492  const QgsPointCloudCategoryList currentCategories = mModel->categories();
493 
494  const bool isClassificationAttribute = ! currentAttribute.compare( QStringLiteral( "Classification" ), Qt::CaseInsensitive );
495  const QgsPointCloudCategoryList defaultLayerCategories = isClassificationAttribute ? QgsPointCloudRendererRegistry::classificationAttributeCategories( mLayer ) : QgsPointCloudCategoryList();
496 
497  mBlockChangedSignal = true;
498  for ( const int &providerCategory : providerCategories )
499  {
500  // does this category already exist?
501  bool found = false;
502  for ( const QgsPointCloudCategory &c : currentCategories )
503  {
504  if ( c.value() == providerCategory )
505  {
506  found = true;
507  break;
508  }
509  }
510 
511  if ( found )
512  continue;
513 
514  QgsPointCloudCategory category;
515  if ( isClassificationAttribute )
516  {
517  for ( const QgsPointCloudCategory &c : defaultLayerCategories )
518  {
519  if ( c.value() == providerCategory )
520  category = c;
521  }
522  }
523  else
524  {
525  category = QgsPointCloudCategory( providerCategory, QgsApplication::colorSchemeRegistry()->fetchRandomStyleColor(), QString::number( providerCategory ) );
526  }
527  mModel->addCategory( category );
528  }
529  mBlockChangedSignal = false;
530  emitWidgetChanged();
531 }
532 
533 void QgsPointCloudClassifiedRendererWidget::addCategory()
534 {
535  if ( !mModel )
536  return;
537 
538  const QgsPointCloudCategory cat( mModel->categories().size(), QgsApplication::colorSchemeRegistry()->fetchRandomStyleColor(), QString(), true );
539  mModel->addCategory( cat );
540 }
541 
542 void QgsPointCloudClassifiedRendererWidget::deleteCategories()
543 {
544  const QList<int> categoryIndexes = selectedCategories();
545  mModel->deleteRows( categoryIndexes );
546 }
547 
548 void QgsPointCloudClassifiedRendererWidget::deleteAllCategories()
549 {
550  mModel->removeAllRows();
551 }
552 
553 void QgsPointCloudClassifiedRendererWidget::setFromRenderer( const QgsPointCloudRenderer *r )
554 {
555  mBlockChangedSignal = true;
556  if ( const QgsPointCloudClassifiedRenderer *classifiedRenderer = dynamic_cast< const QgsPointCloudClassifiedRenderer *>( r ) )
557  {
558  mModel->setRendererCategories( classifiedRenderer->categories() );
559  mAttributeComboBox->setAttribute( classifiedRenderer->attribute() );
560  }
561  else
562  {
563  initialize();
564  }
565  mBlockChangedSignal = false;
566  emitWidgetChanged();
567 }
568 
569 void QgsPointCloudClassifiedRendererWidget::setFromCategories( QgsPointCloudCategoryList categories, const QString &attribute )
570 {
571  mBlockChangedSignal = true;
572  mModel->setRendererCategories( categories );
573  if ( !attribute.isEmpty() )
574  {
575  mAttributeComboBox->setAttribute( attribute );
576  }
577  else
578  {
579  initialize();
580  }
581  mBlockChangedSignal = false;
582  emitWidgetChanged();
583 }
584 
585 void QgsPointCloudClassifiedRendererWidget::initialize()
586 {
587  if ( mAttributeComboBox->findText( QStringLiteral( "Classification" ) ) > -1 )
588  {
589  mAttributeComboBox->setAttribute( QStringLiteral( "Classification" ) );
590  }
591  else
592  {
593  mAttributeComboBox->setCurrentIndex( mAttributeComboBox->count() > 1 ? 1 : 0 );
594  }
595  mModel->removeAllRows();
596  addCategories();
597 }
598 
599 void QgsPointCloudClassifiedRendererWidget::changeCategorySymbol()
600 {
601  const int row = currentCategoryRow();
602  if ( row < 0 )
603  return;
604 
605  const QgsPointCloudCategory category = mModel->categories().value( row );
606 
608  if ( panel && panel->dockMode() )
609  {
611  colorWidget->setPanelTitle( category.label() );
612  colorWidget->setAllowOpacity( true );
613  colorWidget->setPreviousColor( category.color() );
614 
615  connect( colorWidget, &QgsCompoundColorWidget::currentColorChanged, this, [ = ]( const QColor & newColor )
616  {
617  mModel->setCategoryColor( row, newColor );
618  } );
619  panel->openPanel( colorWidget );
620  }
621  else
622  {
623  const QColor newColor = QgsColorDialog::getColor( category.color(), this, category.label(), true );
624  if ( newColor.isValid() )
625  {
626  mModel->setCategoryColor( row, newColor );
627  }
628  }
629 }
630 
631 QList<int> QgsPointCloudClassifiedRendererWidget::selectedCategories()
632 {
633  QList<int> rows;
634  const QModelIndexList selectedRows = viewCategories->selectionModel()->selectedRows();
635  for ( const QModelIndex &r : selectedRows )
636  {
637  if ( r.isValid() )
638  {
639  rows.append( r.row() );
640  }
641  }
642  return rows;
643 }
644 
645 int QgsPointCloudClassifiedRendererWidget::currentCategoryRow()
646 {
647  const QModelIndex idx = viewCategories->selectionModel()->currentIndex();
648  if ( !idx.isValid() )
649  return -1;
650  return idx.row();
651 }
652 
653 void QgsPointCloudClassifiedRendererWidget::updateCategoriesPercentages()
654 {
655  QMap < int, float > percentages;
656 
657  const QgsPointCloudStatistics stats = mLayer->statistics();
658  const QMap<int, int> classes = stats.availableClasses( attribute() );
659  const int pointCount = stats.sampledPointsCount();
660  const QgsPointCloudCategoryList currentCategories = mModel->categories();
661 
662  // when the stats are 100% accurate, we are sure that missing classes have a 0% of points
663  const bool statsExact = stats.sampledPointsCount() == mLayer->pointCount();
664  for ( const QgsPointCloudCategory &category : currentCategories )
665  {
666  if ( classes.contains( category.value() ) || statsExact )
667  percentages.insert( category.value(), ( double ) classes.value( category.value() ) / pointCount * 100 );
668  }
669  mModel->updateCategoriesPercentages( percentages );
670 }
QgsPointCloudRendererWidget
Base class for point cloud 2D renderer settings widgets.
Definition: qgspointcloudrendererwidget.h:36
QgsCompoundColorWidget::setAllowOpacity
void setAllowOpacity(bool allowOpacity)
Sets whether opacity modification (transparency) is permitted for the color dialog.
Definition: qgscompoundcolorwidget.cpp:303
QgsColorSchemeRegistry::fetchRandomStyleColor
QColor fetchRandomStyleColor() const
Returns a random color for use with a new symbol style (e.g.
Definition: qgscolorschemeregistry.cpp:141
QgsPanelWidget::findParentPanel
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
Definition: qgspanelwidget.cpp:54
QgsPointCloudLayer
Represents a map layer supporting display of point clouds.
Definition: qgspointcloudlayer.h:45
qgscontrastenhancement.h
QgsPointCloudCategoryList
QList< QgsPointCloudCategory > QgsPointCloudCategoryList
Definition: qgspointcloudclassifiedrenderer.h:116
QgsPanelWidget::openPanel
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
Definition: qgspanelwidget.cpp:84
QgsApplication::colorSchemeRegistry
static QgsColorSchemeRegistry * colorSchemeRegistry()
Returns the application's color scheme registry, used for managing color schemes.
Definition: qgsapplication.cpp:2310
QgsPointCloudCategory
Represents an individual category (class) from a QgsPointCloudClassifiedRenderer.
Definition: qgspointcloudclassifiedrenderer.h:32
QgsPointCloudStatistics
Class used to store statistics of a point cloud dataset.
Definition: qgspointcloudstatistics.h:61
QgsPointCloudAttributeProxyModel::Char
@ Char
Character attributes.
Definition: qgspointcloudattributemodel.h:145
QgsPointCloudCategory::color
QColor color() const
Returns the color which will be used to render this category.
Definition: qgspointcloudclassifiedrenderer.h:80
QgsPointCloudLayer::renderer
QgsPointCloudRenderer * renderer()
Returns the 2D renderer for the point cloud.
Definition: qgspointcloudlayer.cpp:706
QgsPanelWidget::dockMode
bool dockMode()
Returns the dock mode state.
Definition: qgspanelwidget.h:93
QgsCompoundColorWidget::setPreviousColor
void setPreviousColor(const QColor &color)
Sets the color to show in an optional "previous color" section.
Definition: qgscompoundcolorwidget.cpp:732
QgsGuiUtils::iconSize
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
Definition: qgsguiutils.cpp:264
QgsPointCloudCategory::label
QString label() const
Returns the label for this category, which is used to represent the category within legends and the l...
Definition: qgspointcloudclassifiedrenderer.h:87
qgsapplication.h
QgsCompoundColorWidget
A custom QGIS widget for selecting a color, including options for selecting colors via hue wheel,...
Definition: qgscompoundcolorwidget.h:33
QgsPointCloudStatistics::sampledPointsCount
int sampledPointsCount() const
Returns the number of points used to calculate the statistics.
Definition: qgspointcloudstatistics.h:73
QgsPointCloudAttributeProxyModel::Short
@ Short
Short attributes.
Definition: qgspointcloudattributemodel.h:146
QgsCompoundColorWidget::LayoutVertical
@ LayoutVertical
Use a narrower, vertically stacked layout.
Definition: qgscompoundcolorwidget.h:44
QgsCompoundColorWidget::currentColorChanged
void currentColorChanged(const QColor &color)
Emitted when the dialog's color changes.
QgsPointCloudStatistics::classesOf
QList< int > classesOf(const QString &attribute) const
Returns a list of existing classes which are present for the specified attribute.
Definition: qgspointcloudstatistics.cpp:88
QgsPanelWidget
Base class for any widget that can be shown as a inline panel.
Definition: qgspanelwidget.h:29
qgspointcloudlayer.h
QgsPointCloudCategory::renderState
bool renderState() const
Returns true if the category is currently enabled and should be rendered.
Definition: qgspointcloudclassifiedrenderer.h:114
QgsPointCloudClassifiedRenderer
Renders point clouds by a classification attribute.
Definition: qgspointcloudclassifiedrenderer.h:149
qgspointcloudclassifiedrenderer.h
QgsPointCloudAttributeProxyModel::Int32
@ Int32
Int32 attributes.
Definition: qgspointcloudattributemodel.h:147
qgspointcloudrendererregistry.h
qgspointcloudclassifiedrendererwidget.h
QgsPointCloudAttributeComboBox::attributeChanged
void attributeChanged(const QString &name)
Emitted when the currently selected attribute changes.
QgsPointCloudRendererRegistry::classificationAttributeCategories
static QgsPointCloudCategoryList classificationAttributeCategories(const QgsPointCloudLayer *layer)
Returns a list of categories using the available Classification classes of a specified layer,...
Definition: qgspointcloudrendererregistry.cpp:199
QgsPanelWidget::setPanelTitle
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
Definition: qgspanelwidget.h:44
qgsstyle.h
qgscompoundcolorwidget.h
qgscolordialog.h
QgsPointCloudStatistics::availableClasses
QMap< int, int > availableClasses(const QString &attribute) const
Returns a map containing the count of each class of the attribute attribute If no matching statistic ...
Definition: qgspointcloudstatistics.cpp:96
c
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
Definition: porting_processing.dox:1
QgsStyle
Definition: qgsstyle.h:159
str
#define str(x)
Definition: qgis.cpp:37
QgsPointCloudRenderer
Abstract base class for 2d point cloud renderers.
Definition: qgspointcloudrenderer.h:296
qgscolorschemeregistry.h
QgsPointCloudCategory::value
int value() const
Returns the value corresponding to this category.
Definition: qgspointcloudclassifiedrenderer.h:74
qgsdoublevalidator.h
qgsguiutils.h
QgsGuiUtils::scaleIconSize
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
Definition: qgsguiutils.cpp:259
QgsColorDialog::getColor
static QColor getColor(const QColor &initialColor, QWidget *parent, const QString &title=QString(), bool allowOpacity=false)
Returns a color selection from a color dialog.
Definition: qgscolordialog.cpp:81
QgsProxyStyle
A QProxyStyle subclass which correctly sets the base style to match the QGIS application style,...
Definition: qgsproxystyle.h:30