QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgspointcloudrendererpropertieswidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspointcloudrendererpropertieswidget.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
17#include "qgis.h"
19#include "qgsapplication.h"
22#include "qgspointcloudlayer.h"
28
30#include "qgslogger.h"
31#include "qgsproject.h"
32#include "qgsprojectutils.h"
33
34static bool _initRenderer( const QString &name, QgsPointCloudRendererWidgetFunc f, const QString &iconName = QString() )
35{
37 if ( !rendererAbstractMetadata )
38 return false;
39 QgsPointCloudRendererMetadata *rendererMetadata = dynamic_cast<QgsPointCloudRendererMetadata *>( rendererAbstractMetadata );
40 if ( !rendererMetadata )
41 return false;
42
43 rendererMetadata->setWidgetFunction( f );
44
45 if ( !iconName.isEmpty() )
46 {
47 rendererMetadata->setIcon( QgsApplication::getThemeIcon( iconName ) );
48 }
49
50 QgsDebugMsgLevel( "Set for " + name, 2 );
51 return true;
52}
53
54static void _initRendererWidgetFunctions()
55{
56 static bool sInitialized = false;
57 if ( sInitialized )
58 return;
59
60 _initRenderer( QStringLiteral( "extent" ), QgsPointCloudExtentRendererWidget::create, QStringLiteral( "styleicons/pointcloudextent.svg" ) );
61 _initRenderer( QStringLiteral( "rgb" ), QgsPointCloudRgbRendererWidget::create, QStringLiteral( "styleicons/multibandcolor.svg" ) );
62 _initRenderer( QStringLiteral( "ramp" ), QgsPointCloudAttributeByRampRendererWidget::create, QStringLiteral( "styleicons/singlebandpseudocolor.svg" ) );
63 _initRenderer( QStringLiteral( "classified" ), QgsPointCloudClassifiedRendererWidget::create, QStringLiteral( "styleicons/paletted.svg" ) );
64
65 sInitialized = true;
66}
67
69 : QgsMapLayerConfigWidget( layer, nullptr, parent )
70 , mLayer( layer )
71 , mStyle( style )
72{
73 setupUi( this );
74
75 layout()->setContentsMargins( 0, 0, 0, 0 );
76
77 // initialize registry's widget functions
78 _initRendererWidgetFunctions();
79
81 const QStringList renderers = reg->renderersList();
82 for ( const QString &name : renderers )
83 {
85 cboRenderers->addItem( m->icon(), m->visibleName(), name );
86 }
87
88 cboRenderers->setCurrentIndex( -1 ); // set no current renderer
89
90 mPointStyleComboBox->addItem( tr( "Square" ), static_cast< int >( Qgis::PointCloudSymbol::Square ) );
91 mPointStyleComboBox->addItem( tr( "Circle" ), static_cast< int >( Qgis::PointCloudSymbol::Circle ) );
92
93 connect( cboRenderers, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPointCloudRendererPropertiesWidget::rendererChanged );
94
95 connect( mBlendModeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
96 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
97
100
101 connect( mPointSizeSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
102 connect( mPointSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
103
104 mDrawOrderComboBox->addItem( tr( "Default" ), static_cast< int >( Qgis::PointCloudDrawOrder::Default ) );
105 mDrawOrderComboBox->addItem( tr( "Bottom to Top" ), static_cast< int >( Qgis::PointCloudDrawOrder::BottomToTop ) );
106 mDrawOrderComboBox->addItem( tr( "Top to Bottom" ), static_cast< int >( Qgis::PointCloudDrawOrder::TopToBottom ) );
107
110 mMaxErrorSpinBox->setClearValue( 0.3 );
111
112 mEdlStrength->setClearValue( 1000 );
113 mEdlDistance->setClearValue( 0.5 );
114
117
118 connect( mMaxErrorSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
119 connect( mMaxErrorUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
120
121 connect( mPointStyleComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
122 connect( mDrawOrderComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
123 connect( mDrawOrderComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [ = ]
124 {
125 mEdlWarningLabel->setVisible( mDrawOrderComboBox->currentIndex() == 0 ); // visible on default draw order
126 } );
127 connect( mEyeDomeLightingGroupBox, &QGroupBox::toggled, this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
128 connect( mEdlStrength, qOverload<int>( &QSpinBox::valueChanged ), this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
129 connect( mEdlDistance, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
130 connect( mEdlDistanceUnit, &QgsUnitSelectionWidget::changed, this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
131 syncToLayer( layer );
132}
133
135{
136 mMapCanvas = context.mapCanvas();
137 mMessageBar = context.messageBar();
138 if ( mActiveWidget )
139 {
140 mActiveWidget->setContext( context );
141 }
142}
143
145{
146 mLayer = qobject_cast< QgsPointCloudLayer * >( layer );
147
148 mBlockChangedSignal = true;
149 mOpacityWidget->setOpacity( mLayer->opacity() );
150 mBlendModeComboBox->setShowClippingModes( QgsProjectUtils::layerIsContainedInGroupLayer( QgsProject::instance(), mLayer ) );
151 mBlendModeComboBox->setBlendMode( mLayer->blendMode() );
152
153 if ( mLayer->renderer() )
154 {
155 // set current renderer from layer
156 const QString rendererName = mLayer->renderer()->type();
157
158 const int rendererIdx = cboRenderers->findData( rendererName );
159 cboRenderers->setCurrentIndex( rendererIdx );
160
161 // no renderer found... this mustn't happen
162 Q_ASSERT( rendererIdx != -1 && "there must be a renderer!" );
163
164 mPointSizeSpinBox->setValue( mLayer->renderer()->pointSize() );
165 mPointSizeUnitWidget->setUnit( mLayer->renderer()->pointSizeUnit() );
166 mPointSizeUnitWidget->setMapUnitScale( mLayer->renderer()->pointSizeMapUnitScale() );
167
168 mPointStyleComboBox->setCurrentIndex( mPointStyleComboBox->findData( static_cast< int >( mLayer->renderer()->pointSymbol() ) ) );
169 mDrawOrderComboBox->setCurrentIndex( mDrawOrderComboBox->findData( static_cast< int >( mLayer->renderer()->drawOrder2d() ) ) );
170
171 mMaxErrorSpinBox->setValue( mLayer->renderer()->maximumScreenError() );
172 mMaxErrorUnitWidget->setUnit( mLayer->renderer()->maximumScreenErrorUnit() );
173
174 mEyeDomeLightingGroupBox->setChecked( mLayer->renderer()->eyeDomeLightingEnabled() );
175 mEdlStrength->setValue( mLayer->renderer()->eyeDomeLightingStrength() );
176 mEdlDistance->setValue( mLayer->renderer()->eyeDomeLightingDistance() );
177 mEdlDistanceUnit->setUnit( mLayer->renderer()->eyeDomeLightingDistanceUnit() );
178 mEdlWarningLabel->setVisible( mLayer->renderer()->drawOrder2d() == Qgis::PointCloudDrawOrder::Default );
179 }
180
181 mBlockChangedSignal = false;
182}
183
185{
186 if ( mActiveWidget )
187 mActiveWidget->setDockMode( dockMode );
189}
190
192{
193 mLayer->setOpacity( mOpacityWidget->opacity() );
194 mLayer->setBlendMode( mBlendModeComboBox->blendMode() );
195
196 if ( mActiveWidget )
197 mLayer->setRenderer( mActiveWidget->renderer() );
198 else if ( !cboRenderers->currentData().toString().isEmpty() )
199 {
200 QDomElement elem;
201 mLayer->setRenderer( QgsApplication::pointCloudRendererRegistry()->rendererMetadata( cboRenderers->currentData().toString() )->createRenderer( elem, QgsReadWriteContext() ) );
202 }
203
204 mLayer->renderer()->setPointSize( mPointSizeSpinBox->value() );
205 mLayer->renderer()->setPointSizeUnit( mPointSizeUnitWidget->unit() );
206 mLayer->renderer()->setPointSizeMapUnitScale( mPointSizeUnitWidget->getMapUnitScale() );
207
208 mLayer->renderer()->setPointSymbol( static_cast< Qgis::PointCloudSymbol >( mPointStyleComboBox->currentData().toInt() ) );
209
210 mLayer->renderer()->setMaximumScreenError( mMaxErrorSpinBox->value() );
211 mLayer->renderer()->setMaximumScreenErrorUnit( mMaxErrorUnitWidget->unit() );
212 mLayer->renderer()->setDrawOrder2d( static_cast< Qgis::PointCloudDrawOrder >( mDrawOrderComboBox->currentData().toInt() ) );
213 mLayer->renderer()->setEyeDomeLightingEnabled( mEyeDomeLightingGroupBox->isChecked() );
214 mLayer->renderer()->setEyeDomeLightingStrength( mEdlStrength->value() );
215 mLayer->renderer()->setEyeDomeLightingDistance( mEdlDistance->value() );
216 mLayer->renderer()->setEyeDomeLightingDistanceUnit( mEdlDistanceUnit->unit() );
217}
218
219void QgsPointCloudRendererPropertiesWidget::rendererChanged()
220{
221 if ( cboRenderers->currentIndex() == -1 )
222 {
223 QgsDebugMsg( QStringLiteral( "No current item -- this should never happen!" ) );
224 return;
225 }
226
227 const QString rendererName = cboRenderers->currentData().toString();
228
229 //Retrieve the previous renderer: from the old active widget if possible, otherwise from the layer
230 std::unique_ptr< QgsPointCloudRenderer > oldRenderer;
231 std::unique_ptr< QgsPointCloudRenderer > newRenderer;
232 if ( mActiveWidget )
233 newRenderer.reset( mActiveWidget->renderer() );
234
235 if ( newRenderer )
236 {
237 oldRenderer = std::move( newRenderer );
238 }
239 else
240 {
241 oldRenderer.reset( mLayer->renderer()->clone() );
242 }
243
244 // get rid of old active widget (if any)
245 if ( mActiveWidget )
246 {
247 stackedWidget->removeWidget( mActiveWidget );
248
249 delete mActiveWidget;
250 mActiveWidget = nullptr;
251 }
252
253 QgsPointCloudRendererWidget *widget = nullptr;
255 if ( rendererMetadata )
256 widget = rendererMetadata->createRendererWidget( mLayer, mStyle, oldRenderer.get() );
257 oldRenderer.reset();
258
259 if ( widget )
260 {
261 // instantiate the widget and set as active
262 mActiveWidget = widget;
263 stackedWidget->addWidget( mActiveWidget );
264 stackedWidget->setCurrentWidget( mActiveWidget );
265
266 if ( mMapCanvas || mMessageBar )
267 {
269 context.setMapCanvas( mMapCanvas );
270 context.setMessageBar( mMessageBar );
271 mActiveWidget->setContext( context );
272 }
273
276 widget->setDockMode( dockMode() );
277 }
278 else
279 {
280 // set default "no edit widget available" page
281 stackedWidget->setCurrentWidget( pageNoWidget );
282 }
283 emitWidgetChanged();
284}
285
286void QgsPointCloudRendererPropertiesWidget::emitWidgetChanged()
287{
288 if ( !mBlockChangedSignal )
289 emit widgetChanged();
290}
291
PointCloudSymbol
Rendering symbols for point cloud points.
Definition: qgis.h:2058
@ Circle
Renders points as circles.
@ Square
Renders points as squares.
PointCloudDrawOrder
Pointcloud rendering order for 2d views.
Definition: qgis.h:2070
@ BottomToTop
Draw points with larger Z values last.
@ Default
Draw points in the order they are stored.
@ TopToBottom
Draw points with larger Z values first.
static QgsPointCloudRendererRegistry * pointCloudRendererRegistry()
Returns the application's point cloud renderer registry, used for managing point cloud layer 2D rende...
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
A panel widget that can be shown in the map style dock.
Base class for all map layer types.
Definition: qgsmaplayer.h:73
void setBlendMode(QPainter::CompositionMode blendMode)
Set the blending mode used for rendering a layer.
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer.
virtual void setOpacity(double opacity)
Sets the opacity for the layer, where opacity is a value between 0 (totally transparent) and 1....
double opacity
Definition: qgsmaplayer.h:82
void opacityChanged(double opacity)
Emitted when the opacity is changed in the widget, where opacity ranges from 0.0 (transparent) to 1....
void showPanel(QgsPanelWidget *panel)
Emit when you require a panel to be show in the interface.
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
void widgetChanged()
Emitted when the widget state changes.
virtual void setDockMode(bool dockMode)
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
bool dockMode()
Returns the dock mode state.
Represents a map layer supporting display of point clouds.
QgsPointCloudRenderer * renderer()
Returns the 2D renderer for the point cloud.
void setRenderer(QgsPointCloudRenderer *renderer)
Sets the 2D renderer for the point cloud.
Stores metadata about one point cloud renderer class.
void setIcon(const QIcon &icon)
Sets an icon representing the renderer.
virtual QgsPointCloudRendererWidget * createRendererWidget(QgsPointCloudLayer *layer, QgsStyle *style, QgsPointCloudRenderer *oldRenderer)
Returns new instance of settings widget for the renderer.
Convenience metadata class that uses static functions to create point cloud renderer and its widget.
void setWidgetFunction(QgsPointCloudRendererWidgetFunc f)
QgsPointCloudRenderer * createRenderer(QDomElement &elem, const QgsReadWriteContext &context) override
Returns new instance of the renderer given the DOM element.
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the widget is shown, e.g., the associated map canvas and expression context...
QgsPointCloudRendererPropertiesWidget(QgsPointCloudLayer *layer, QgsStyle *style, QWidget *parent=nullptr)
Constructor for QgsPointCloudRendererPropertiesWidget, associated with the specified layer and style ...
void setDockMode(bool dockMode) override
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
void syncToLayer(QgsMapLayer *layer) override
Reset to original (vector layer) values.
Registry of 2D renderers for point clouds.
QgsPointCloudRendererAbstractMetadata * rendererMetadata(const QString &rendererName)
Returns the metadata for a specified renderer.
QStringList renderersList() const
Returns a list of available renderers.
Base class for point cloud 2D renderer settings widgets.
virtual void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the renderer widget is shown, e.g., the associated map canvas and expressio...
virtual QgsPointCloudRenderer * renderer()=0
Returns a new instance of a renderer as defined by the settings in the widget.
void setMaximumScreenError(double error)
Sets the maximum screen error allowed when rendering the point cloud.
void setPointSizeUnit(const QgsUnitTypes::RenderUnit units)
Sets the units used for the point size.
void setEyeDomeLightingEnabled(bool enabled)
Sets whether eye dome lighting effect will be used.
const QgsMapUnitScale & pointSizeMapUnitScale() const
Returns the map unit scale used for the point size.
void setPointSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale used for the point size.
QgsUnitTypes::RenderUnit eyeDomeLightingDistanceUnit() const
Returns unit for the eye dome lighting distance.
void setPointSize(double size)
Sets the point size.
virtual QString type() const =0
Returns the identifier of the renderer type.
QgsUnitTypes::RenderUnit maximumScreenErrorUnit() const
Returns the unit for the maximum screen error allowed when rendering the point cloud.
virtual QgsPointCloudRenderer * clone() const =0
Create a deep copy of this renderer.
void setDrawOrder2d(Qgis::PointCloudDrawOrder order)
Sets the drawing order used by the renderer for drawing points.
QgsUnitTypes::RenderUnit pointSizeUnit() const
Returns the units used for the point size.
void setEyeDomeLightingDistanceUnit(QgsUnitTypes::RenderUnit unit)
Sets unit for the eye dome lighting distance.
void setPointSymbol(Qgis::PointCloudSymbol symbol)
Sets the symbol used by the renderer for drawing points.
void setEyeDomeLightingDistance(double distance)
Sets the eye dome lighting distance.
double maximumScreenError() const
Returns the maximum screen error allowed when rendering the point cloud.
void setEyeDomeLightingStrength(double strength)
Sets the eye dome lighting strength value.
void setMaximumScreenErrorUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the maximum screen error allowed when rendering the point cloud.
bool eyeDomeLightingEnabled() const
Returns whether eye dome lighting effect will be used.
Qgis::PointCloudSymbol pointSymbol() const
Returns the symbol used by the renderer for drawing points.
Qgis::PointCloudDrawOrder drawOrder2d() const
Returns the drawing order used by the renderer for drawing points.
double eyeDomeLightingStrength() const
Returns the eye dome lighting strength value.
double pointSize() const
Returns the point size.
double eyeDomeLightingDistance() const
Returns the eye dome lighting distance.
static bool layerIsContainedInGroupLayer(QgsProject *project, QgsMapLayer *layer)
Returns true if the specified layer is a child layer from any QgsGroupLayer in the given project.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:477
The class is used as a container of context for various read/write operations on other objects.
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
void setMessageBar(QgsMessageBar *bar)
Sets the message bar associated with the widget.
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
QgsMessageBar * messageBar() const
Returns the message bar associated with the widget.
QList< QgsUnitTypes::RenderUnit > RenderUnitList
List of render units.
Definition: qgsunittypes.h:240
@ RenderMetersInMapUnits
Meters value as Map units.
Definition: qgsunittypes.h:176
@ RenderPoints
Points (e.g., for font sizes)
Definition: qgsunittypes.h:173
@ RenderPixels
Pixels.
Definition: qgsunittypes.h:171
@ RenderInches
Inches.
Definition: qgsunittypes.h:174
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:169
@ RenderMapUnits
Map units.
Definition: qgsunittypes.h:170
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsPointCloudRendererWidget *(* QgsPointCloudRendererWidgetFunc)(QgsPointCloudLayer *, QgsStyle *, QgsPointCloudRenderer *)