QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgspointcloudrendererregistry.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgspointcloudrendererregistry.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  * 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 #include "qgspointcloudrenderer.h"
17 #include "qgsapplication.h"
18 #include "qgscolorschemeregistry.h"
19 
20 // default renderers
24 #include "qgspointcloudlayer.h"
26 
28 {
29  // add default renderers
30  addRenderer( new QgsPointCloudRendererMetadata( QStringLiteral( "extent" ),
31  QObject::tr( "Extent Only" ),
33  addRenderer( new QgsPointCloudRendererMetadata( QStringLiteral( "ramp" ),
34  QObject::tr( "Attribute by Ramp" ),
36  addRenderer( new QgsPointCloudRendererMetadata( QStringLiteral( "rgb" ),
37  QObject::tr( "RGB" ),
39  addRenderer( new QgsPointCloudRendererMetadata( QStringLiteral( "classified" ),
40  QObject::tr( "Classification" ),
42 }
43 
45 {
46  qDeleteAll( mRenderers );
47 }
48 
50 {
51  if ( !metadata || mRenderers.contains( metadata->name() ) )
52  return false;
53 
54  mRenderers[metadata->name()] = metadata;
55  mRenderersOrder << metadata->name();
56  return true;
57 }
58 
59 bool QgsPointCloudRendererRegistry::removeRenderer( const QString &rendererName )
60 {
61  if ( !mRenderers.contains( rendererName ) )
62  return false;
63 
64  delete mRenderers[rendererName];
65  mRenderers.remove( rendererName );
66  mRenderersOrder.removeAll( rendererName );
67  return true;
68 }
69 
71 {
72  return mRenderers.value( rendererName );
73 }
74 
76 {
77  QStringList renderers;
78  for ( const QString &renderer : mRenderersOrder )
79  {
80  QgsPointCloudRendererAbstractMetadata *r = mRenderers.value( renderer );
81  if ( r )
82  renderers << renderer;
83  }
84  return renderers;
85 }
86 
88 {
89  const QgsPointCloudDataProvider *provider = layer->dataProvider();
90  if ( !provider )
92 
93  const QgsPointCloudStatistics stats = layer->statistics();
94 
95  if ( ( provider->name() == QLatin1String( "pdal" ) ) && ( !provider->hasValidIndex() ) )
96  {
97  // for now, default to extent renderer only for las/laz files
98  return new QgsPointCloudExtentRenderer();
99  }
100 
101  // If we are calculating statistics, we default to the extent renderer until the statistics calculation finishes
103  {
104  return new QgsPointCloudExtentRenderer();
105  }
106 
107  const QgsPointCloudAttributeCollection attributes = provider->attributes();
108 
109  //if red/green/blue attributes are present, then default to a RGB renderer
110  if ( attributes.indexOf( QLatin1String( "Red" ) ) >= 0 && attributes.indexOf( QLatin1String( "Green" ) ) >= 0 && attributes.indexOf( QLatin1String( "Blue" ) ) >= 0 )
111  {
112  std::unique_ptr< QgsPointCloudRgbRenderer > renderer = std::make_unique< QgsPointCloudRgbRenderer >();
113 
114  // set initial guess for rgb ranges
115  const double redMax = stats.maximum( QStringLiteral( "Red" ) );
116  const double greenMax = stats.maximum( QStringLiteral( "Red" ) );
117  const double blueMax = stats.maximum( QStringLiteral( "Red" ) );
118  if ( !std::isnan( redMax ) && !std::isnan( greenMax ) && !std::isnan( blueMax ) )
119  {
120  const int maxValue = std::max( blueMax, std::max( redMax, greenMax ) );
121 
122  if ( maxValue == 0 )
123  {
124  // r/g/b max value is 0 -- likely these attributes have been created by some process, but are empty.
125  // in any case they won't result in a useful render, so don't use RGB renderer for this dataset.
126  renderer.reset();
127  }
128  else
129  {
130  // try and guess suitable range from input max values -- we don't just take the provider max value directly here, but rather see if it's
131  // likely to be 8 bit or 16 bit color values
132  const int rangeGuess = maxValue > 255 ? 65535 : 255;
133 
134  if ( rangeGuess > 255 )
135  {
136  // looks like 16 bit colors, so default to a stretch contrast enhancement
138  contrast.setMinimumValue( 0 );
139  contrast.setMaximumValue( rangeGuess );
141  renderer->setRedContrastEnhancement( new QgsContrastEnhancement( contrast ) );
142  renderer->setGreenContrastEnhancement( new QgsContrastEnhancement( contrast ) );
143  renderer->setBlueContrastEnhancement( new QgsContrastEnhancement( contrast ) );
144  }
145  }
146  }
147  else
148  {
150  contrast.setMinimumValue( std::numeric_limits<uint16_t>::lowest() );
151  contrast.setMaximumValue( std::numeric_limits<uint16_t>::max() );
153  renderer->setRedContrastEnhancement( new QgsContrastEnhancement( contrast ) );
154  renderer->setGreenContrastEnhancement( new QgsContrastEnhancement( contrast ) );
155  renderer->setBlueContrastEnhancement( new QgsContrastEnhancement( contrast ) );
156  }
157 
158  if ( renderer )
159  return renderer.release();
160  }
161 
162  // otherwise try a classified renderer...
163  if ( attributes.indexOf( QLatin1String( "Classification" ) ) >= 0 )
164  {
165  // are any classifications present?
166  QList<int> classes = stats.classesOf( QStringLiteral( "Classification" ) );
167  // ignore "not classified" classes, and see if any are left...
168  classes.removeAll( 0 );
169  classes.removeAll( 1 );
170  if ( !classes.empty() )
171  {
173  std::unique_ptr< QgsPointCloudClassifiedRenderer > renderer = std::make_unique< QgsPointCloudClassifiedRenderer >( QLatin1String( "Classification" ), categories );
174  return renderer.release();
175  }
176  }
177 
178  // fallback to shading by Z
179  std::unique_ptr< QgsPointCloudAttributeByRampRenderer > renderer = std::make_unique< QgsPointCloudAttributeByRampRenderer >();
180  renderer->setAttribute( QStringLiteral( "Z" ) );
181 
182  // set initial range for z values if possible
183  const double zMin = stats.minimum( QStringLiteral( "Z" ) );
184  const double zMax = stats.maximum( QStringLiteral( "Z" ) );
185  if ( !std::isnan( zMin ) && !std::isnan( zMax ) )
186  {
187  renderer->setMinimum( zMin );
188  renderer->setMaximum( zMax );
189 
190  QgsColorRampShader shader = renderer->colorRampShader();
191  shader.setMinimumValue( zMin );
192  shader.setMaximumValue( zMax );
193  shader.classifyColorRamp( 5, -1, QgsRectangle(), nullptr );
194  renderer->setColorRampShader( shader );
195  }
196  return renderer.release();
197 }
198 
200 {
201  if ( !layer )
202  return QgsPointCloudCategoryList();
203 
204  const QgsPointCloudStatistics stats = layer->statistics();
205  const QList<int> layerClasses = stats.classesOf( QStringLiteral( "Classification" ) );
207 
208  QgsPointCloudCategoryList categories;
209  for ( const int &layerClass : layerClasses )
210  {
211  const QColor color = layerClass < defaultCategories.size() ? defaultCategories.at( layerClass ).color() : QgsApplication::colorSchemeRegistry()->fetchRandomStyleColor();
212  const QString label = layerClass < defaultCategories.size() ? QgsPointCloudDataProvider::translatedLasClassificationCodes().value( layerClass, QString::number( layerClass ) ) : QString::number( layerClass );
213  categories.append( QgsPointCloudCategory( layerClass, color, label ) );
214  }
215  return categories;
216 }
QgsPointCloudRgbRenderer::create
static QgsPointCloudRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
Creates an RGB renderer from an XML element.
Definition: qgspointcloudrgbrenderer.cpp:168
QgsPointCloudClassifiedRenderer::defaultCategories
static QgsPointCloudCategoryList defaultCategories()
Returns the default list of categories.
Definition: qgspointcloudclassifiedrenderer.cpp:192
QgsColorSchemeRegistry::fetchRandomStyleColor
QColor fetchRandomStyleColor() const
Returns a random color for use with a new symbol style (e.g.
Definition: qgscolorschemeregistry.cpp:141
QgsContrastEnhancement::setContrastEnhancementAlgorithm
void setContrastEnhancementAlgorithm(ContrastEnhancementAlgorithm algorithm, bool generateTable=true)
Sets the contrast enhancement algorithm.
Definition: qgscontrastenhancement.cpp:132
QgsPointCloudLayer::PointCloudStatisticsCalculationState::Calculating
@ Calculating
The statistics calculation task is running.
QgsPointCloudLayer::statistics
const QgsPointCloudStatistics statistics() const
Returns the object containing statistics.
Definition: qgspointcloudlayer.h:239
QgsPointCloudLayer
Represents a map layer supporting display of point clouds.
Definition: qgspointcloudlayer.h:45
QgsContrastEnhancement::setMinimumValue
void setMinimumValue(double value, bool generateTable=true)
Sets the minimum value for the contrast enhancement range.
Definition: qgscontrastenhancement.cpp:200
QgsPointCloudRendererMetadata
Convenience metadata class that uses static functions to create point cloud renderer and its widget.
Definition: qgspointcloudrendererregistry.h:126
QgsPointCloudClassifiedRenderer::create
static QgsPointCloudRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
Creates an RGB renderer from an XML element.
Definition: qgspointcloudclassifiedrenderer.cpp:161
QgsPointCloudCategoryList
QList< QgsPointCloudCategory > QgsPointCloudCategoryList
Definition: qgspointcloudclassifiedrenderer.h:116
QgsPointCloudExtentRenderer
A renderer for 2d visualisation of point clouds which shows the dataset's extents using a fill symbol...
Definition: qgspointcloudextentrenderer.h:33
QgsColorRampShader::classifyColorRamp
void classifyColorRamp(int classes=0, int band=-1, const QgsRectangle &extent=QgsRectangle(), QgsRasterInterface *input=nullptr)
Classify color ramp shader.
Definition: qgscolorrampshader.cpp:187
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
QgsPointCloudRendererRegistry::rendererMetadata
QgsPointCloudRendererAbstractMetadata * rendererMetadata(const QString &rendererName)
Returns the metadata for a specified renderer.
Definition: qgspointcloudrendererregistry.cpp:70
QgsColorRampShader
A ramp shader will color a raster pixel based on a list of values ranges in a ramp.
Definition: qgscolorrampshader.h:42
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsPointCloudStatistics::maximum
double maximum(const QString &attribute) const
Returns the maximum value for the attribute attribute If no matching statistic is available then NaN ...
Definition: qgspointcloudstatistics.cpp:110
QgsPointCloudDataProvider::attributes
virtual QgsPointCloudAttributeCollection attributes() const =0
Returns the attributes available from this data provider.
QgsPointCloudRendererRegistry::removeRenderer
bool removeRenderer(const QString &rendererName)
Removes a renderer from registry.
Definition: qgspointcloudrendererregistry.cpp:59
qgsapplication.h
QgsPointCloudRendererRegistry::defaultRenderer
static QgsPointCloudRenderer * defaultRenderer(const QgsPointCloudLayer *layer)
Returns a new default point cloud renderer for a specified layer.
Definition: qgspointcloudrendererregistry.cpp:87
QgsPointCloudRendererRegistry::QgsPointCloudRendererRegistry
QgsPointCloudRendererRegistry()
Definition: qgspointcloudrendererregistry.cpp:27
QgsPointCloudLayer::dataProvider
QgsPointCloudDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
Definition: qgspointcloudlayer.cpp:114
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
qgspointcloudlayer.h
qgspointcloudrgbrenderer.h
QgsContrastEnhancement::StretchToMinimumMaximum
@ StretchToMinimumMaximum
Linear histogram.
Definition: qgscontrastenhancement.h:51
qgspointcloudclassifiedrenderer.h
QgsPointCloudDataProvider::hasValidIndex
bool hasValidIndex() const
Returns whether provider has index which is valid.
Definition: qgspointclouddataprovider.cpp:47
QgsPointCloudAttributeCollection
Collection of point cloud attributes.
Definition: qgspointcloudattribute.h:141
QgsRasterShaderFunction::setMaximumValue
virtual void setMaximumValue(double value)
Sets the maximum value for the raster shader.
Definition: qgsrastershaderfunction.cpp:30
Qgis::DataType::UnknownDataType
@ UnknownDataType
Unknown or unspecified type.
qgspointcloudrendererregistry.h
QgsPointCloudAttributeByRampRenderer::create
static QgsPointCloudRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
Creates an RGB renderer from an XML element.
Definition: qgspointcloudattributebyramprenderer.cpp:133
QgsPointCloudAttributeByRampRenderer
An RGB renderer for 2d visualisation of point clouds using embedded red, green and blue attributes.
Definition: qgspointcloudattributebyramprenderer.h:61
qgspointcloudattributebyramprenderer.h
QgsPointCloudRendererAbstractMetadata
Stores metadata about one point cloud renderer class.
Definition: qgspointcloudrendererregistry.h:46
QgsPointCloudRendererRegistry::renderersList
QStringList renderersList() const
Returns a list of available renderers.
Definition: qgspointcloudrendererregistry.cpp:75
qgspointcloudextentrenderer.h
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
Qgis::DataType::UInt16
@ UInt16
Sixteen bit unsigned integer (quint16)
QgsPointCloudDataProvider
Base class for providing data for QgsPointCloudLayer.
Definition: qgspointclouddataprovider.h:46
QgsContrastEnhancement
Manipulates raster or point cloud pixel values so that they enhanceContrast or clip into a specified ...
Definition: qgscontrastenhancement.h:42
QgsPointCloudAttributeCollection::indexOf
int indexOf(const QString &name) const
Returns the index of the attribute with the specified name.
Definition: qgspointcloudattribute.cpp:181
QgsPointCloudExtentRenderer::create
static QgsPointCloudRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
Creates an extent renderer from an XML element.
Definition: qgspointcloudextentrenderer.cpp:54
QgsPointCloudStatistics::minimum
double minimum(const QString &attribute) const
Returns the minimum value for the attribute attribute If no matching statistic is available then NaN ...
Definition: qgspointcloudstatistics.cpp:103
QgsPointCloudRendererAbstractMetadata::name
QString name() const
Returns the unique name of the renderer.
Definition: qgspointcloudrendererregistry.h:68
QgsPointCloudRenderer
Abstract base class for 2d point cloud renderers.
Definition: qgspointcloudrenderer.h:296
qgscolorschemeregistry.h
QgsDataProvider::name
virtual QString name() const =0
Returns a provider name.
QgsPointCloudLayer::statisticsCalculationState
PointCloudStatisticsCalculationState statisticsCalculationState() const
Returns the status of point cloud statistics calculation.
Definition: qgspointcloudlayer.h:246
QgsPointCloudDataProvider::translatedLasClassificationCodes
static QMap< int, QString > translatedLasClassificationCodes()
Returns the map of LAS classification code to translated string value, corresponding to the ASPRS Sta...
Definition: qgspointclouddataprovider.cpp:105
qgspointcloudrenderer.h
QgsPointCloudRendererRegistry::addRenderer
bool addRenderer(QgsPointCloudRendererAbstractMetadata *metadata)
Adds a renderer to the registry.
Definition: qgspointcloudrendererregistry.cpp:49
QgsContrastEnhancement::setMaximumValue
void setMaximumValue(double value, bool generateTable=true)
Sets the maximum value for the contrast enhancement range.
Definition: qgscontrastenhancement.cpp:174
QgsPointCloudRendererRegistry::~QgsPointCloudRendererRegistry
~QgsPointCloudRendererRegistry()
Definition: qgspointcloudrendererregistry.cpp:44
QgsRasterShaderFunction::setMinimumValue
virtual void setMinimumValue(double value)
Sets the minimum value for the raster shader.
Definition: qgsrastershaderfunction.cpp:38