QGIS API Documentation 3.34.0-Prizren (ffbdd678812)
Loading...
Searching...
No Matches
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#include "qgslogger.h"
29#include "qgsproject.h"
30#include "qgsprojectutils.h"
31
32static bool initPointCloudRenderer( const QString &name, QgsPointCloudRendererWidgetFunc f, const QString &iconName = QString() )
33{
35 if ( !rendererAbstractMetadata )
36 return false;
37 QgsPointCloudRendererMetadata *rendererMetadata = dynamic_cast<QgsPointCloudRendererMetadata *>( rendererAbstractMetadata );
38 if ( !rendererMetadata )
39 return false;
40
41 rendererMetadata->setWidgetFunction( f );
42
43 if ( !iconName.isEmpty() )
44 {
45 rendererMetadata->setIcon( QgsApplication::getThemeIcon( iconName ) );
46 }
47
48 QgsDebugMsgLevel( "Set for " + name, 2 );
49 return true;
50}
51
52void QgsPointCloudRendererPropertiesWidget::initRendererWidgetFunctions()
53{
54 static bool sInitialized = false;
55 if ( sInitialized )
56 return;
57
58 initPointCloudRenderer( QStringLiteral( "extent" ), QgsPointCloudExtentRendererWidget::create, QStringLiteral( "styleicons/pointcloudextent.svg" ) );
59 initPointCloudRenderer( QStringLiteral( "rgb" ), QgsPointCloudRgbRendererWidget::create, QStringLiteral( "styleicons/multibandcolor.svg" ) );
60 initPointCloudRenderer( QStringLiteral( "ramp" ), QgsPointCloudAttributeByRampRendererWidget::create, QStringLiteral( "styleicons/singlebandpseudocolor.svg" ) );
61 initPointCloudRenderer( QStringLiteral( "classified" ), QgsPointCloudClassifiedRendererWidget::create, QStringLiteral( "styleicons/paletted.svg" ) );
62
63 sInitialized = true;
64}
65
67 : QgsMapLayerConfigWidget( layer, nullptr, parent )
68 , mLayer( layer )
69 , mStyle( style )
70{
71 setupUi( this );
72
73 layout()->setContentsMargins( 0, 0, 0, 0 );
74
75 // initialize registry's widget functions
76 initRendererWidgetFunctions();
77
79 const QStringList renderers = reg->renderersList();
80 for ( const QString &name : renderers )
81 {
83 cboRenderers->addItem( m->icon(), m->visibleName(), name );
84 }
85
86 cboRenderers->setCurrentIndex( -1 ); // set no current renderer
87
88 mPointStyleComboBox->addItem( tr( "Square" ), static_cast< int >( Qgis::PointCloudSymbol::Square ) );
89 mPointStyleComboBox->addItem( tr( "Circle" ), static_cast< int >( Qgis::PointCloudSymbol::Circle ) );
90
91 connect( cboRenderers, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPointCloudRendererPropertiesWidget::rendererChanged );
92
93 connect( mBlendModeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
94 connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
95
96 mPointSizeUnitWidget->setUnits( {Qgis::RenderUnit::Millimeters,
102
103 connect( mPointSizeSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
104 connect( mPointSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
105
106 mDrawOrderComboBox->addItem( tr( "Default" ), static_cast< int >( Qgis::PointCloudDrawOrder::Default ) );
107 mDrawOrderComboBox->addItem( tr( "Bottom to Top" ), static_cast< int >( Qgis::PointCloudDrawOrder::BottomToTop ) );
108 mDrawOrderComboBox->addItem( tr( "Top to Bottom" ), static_cast< int >( Qgis::PointCloudDrawOrder::TopToBottom ) );
109
110 mMaxErrorUnitWidget->setUnits( { Qgis::RenderUnit::Millimeters,
116 mMaxErrorSpinBox->setClearValue( 0.3 );
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
124 syncToLayer( layer );
125}
126
128{
129 mMapCanvas = context.mapCanvas();
130 mMessageBar = context.messageBar();
131 if ( mActiveWidget )
132 {
133 mActiveWidget->setContext( context );
134 }
135}
136
138{
139 mLayer = qobject_cast< QgsPointCloudLayer * >( layer );
140
141 mBlockChangedSignal = true;
142 mOpacityWidget->setOpacity( mLayer->opacity() );
143 mBlendModeComboBox->setShowClippingModes( QgsProjectUtils::layerIsContainedInGroupLayer( QgsProject::instance(), mLayer ) );
144 mBlendModeComboBox->setBlendMode( mLayer->blendMode() );
145
146 if ( mLayer->renderer() )
147 {
148 // set current renderer from layer
149 const QString rendererName = mLayer->renderer()->type();
150
151 const int rendererIdx = cboRenderers->findData( rendererName );
152 cboRenderers->setCurrentIndex( rendererIdx );
153
154 // no renderer found... this mustn't happen
155 Q_ASSERT( rendererIdx != -1 && "there must be a renderer!" );
156
157 mPointSizeSpinBox->setValue( mLayer->renderer()->pointSize() );
158 mPointSizeUnitWidget->setUnit( mLayer->renderer()->pointSizeUnit() );
159 mPointSizeUnitWidget->setMapUnitScale( mLayer->renderer()->pointSizeMapUnitScale() );
160
161 mPointStyleComboBox->setCurrentIndex( mPointStyleComboBox->findData( static_cast< int >( mLayer->renderer()->pointSymbol() ) ) );
162 mDrawOrderComboBox->setCurrentIndex( mDrawOrderComboBox->findData( static_cast< int >( mLayer->renderer()->drawOrder2d() ) ) );
163
164 mMaxErrorSpinBox->setValue( mLayer->renderer()->maximumScreenError() );
165 mMaxErrorUnitWidget->setUnit( mLayer->renderer()->maximumScreenErrorUnit() );
166 }
167
168 mBlockChangedSignal = false;
169}
170
172{
173 if ( mActiveWidget )
174 mActiveWidget->setDockMode( dockMode );
176}
177
179{
180 mLayer->setOpacity( mOpacityWidget->opacity() );
181 mLayer->setBlendMode( mBlendModeComboBox->blendMode() );
182
183 if ( mActiveWidget )
184 mLayer->setRenderer( mActiveWidget->renderer() );
185 else if ( !cboRenderers->currentData().toString().isEmpty() )
186 {
187 QDomElement elem;
188 mLayer->setRenderer( QgsApplication::pointCloudRendererRegistry()->rendererMetadata( cboRenderers->currentData().toString() )->createRenderer( elem, QgsReadWriteContext() ) );
189 }
190
191 mLayer->renderer()->setPointSize( mPointSizeSpinBox->value() );
192 mLayer->renderer()->setPointSizeUnit( mPointSizeUnitWidget->unit() );
193 mLayer->renderer()->setPointSizeMapUnitScale( mPointSizeUnitWidget->getMapUnitScale() );
194
195 mLayer->renderer()->setPointSymbol( static_cast< Qgis::PointCloudSymbol >( mPointStyleComboBox->currentData().toInt() ) );
196
197 mLayer->renderer()->setMaximumScreenError( mMaxErrorSpinBox->value() );
198 mLayer->renderer()->setMaximumScreenErrorUnit( mMaxErrorUnitWidget->unit() );
199 mLayer->renderer()->setDrawOrder2d( static_cast< Qgis::PointCloudDrawOrder >( mDrawOrderComboBox->currentData().toInt() ) );
200}
201
202void QgsPointCloudRendererPropertiesWidget::rendererChanged()
203{
204 if ( cboRenderers->currentIndex() == -1 )
205 {
206 QgsDebugError( QStringLiteral( "No current item -- this should never happen!" ) );
207 return;
208 }
209
210 const QString rendererName = cboRenderers->currentData().toString();
211
212 //Retrieve the previous renderer: from the old active widget if possible, otherwise from the layer
213 std::unique_ptr< QgsPointCloudRenderer > oldRenderer;
214 std::unique_ptr< QgsPointCloudRenderer > newRenderer;
215 if ( mActiveWidget )
216 newRenderer.reset( mActiveWidget->renderer() );
217
218 if ( newRenderer )
219 {
220 oldRenderer = std::move( newRenderer );
221 }
222 else
223 {
224 oldRenderer.reset( mLayer->renderer()->clone() );
225 }
226
227 // get rid of old active widget (if any)
228 if ( mActiveWidget )
229 {
230 stackedWidget->removeWidget( mActiveWidget );
231
232 delete mActiveWidget;
233 mActiveWidget = nullptr;
234 }
235
236 QgsPointCloudRendererWidget *widget = nullptr;
238 if ( rendererMetadata )
239 widget = rendererMetadata->createRendererWidget( mLayer, mStyle, oldRenderer.get() );
240 oldRenderer.reset();
241
242 if ( widget )
243 {
244 // instantiate the widget and set as active
245 mActiveWidget = widget;
246 stackedWidget->addWidget( mActiveWidget );
247 stackedWidget->setCurrentWidget( mActiveWidget );
248
249 if ( mMapCanvas || mMessageBar )
250 {
252 context.setMapCanvas( mMapCanvas );
253 context.setMessageBar( mMessageBar );
254 mActiveWidget->setContext( context );
255 }
256
259 widget->setDockMode( dockMode() );
260 }
261 else
262 {
263 // set default "no edit widget available" page
264 stackedWidget->setCurrentWidget( pageNoWidget );
265 }
266 emitWidgetChanged();
267}
268
269void QgsPointCloudRendererPropertiesWidget::emitWidgetChanged()
270{
271 if ( !mBlockChangedSignal )
272 emit widgetChanged();
273}
274
PointCloudSymbol
Rendering symbols for point cloud points.
Definition qgis.h:2876
@ Circle
Renders points as circles.
@ Square
Renders points as squares.
PointCloudDrawOrder
Pointcloud rendering order for 2d views.
Definition qgis.h:2888
@ 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.
@ Millimeters
Millimeters.
@ Points
Points (e.g., for font sizes)
@ MapUnits
Map units.
@ MetersInMapUnits
Meters value as Map units.
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:74
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:83
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 syncToLayer(QgsMapLayer *layer) final
Reset to original (vector layer) values.
void setDockMode(bool dockMode) final
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
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 setMaximumScreenErrorUnit(Qgis::RenderUnit unit)
Sets the unit for the maximum screen error allowed when rendering the point cloud.
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.
void setPointSize(double size)
Sets the point size.
virtual QString type() const =0
Returns the identifier of the renderer type.
virtual QgsPointCloudRenderer * clone() const =0
Create a deep copy of this renderer.
Qgis::RenderUnit maximumScreenErrorUnit() const
Returns the unit for the maximum screen error allowed when rendering the point cloud.
void setDrawOrder2d(Qgis::PointCloudDrawOrder order)
Sets the drawing order used by the renderer for drawing points.
void setPointSizeUnit(const Qgis::RenderUnit units)
Sets the units used for the point size.
void setPointSymbol(Qgis::PointCloudSymbol symbol)
Sets the symbol used by the renderer for drawing points.
double maximumScreenError() const
Returns the maximum screen error allowed when rendering the point cloud.
Qgis::RenderUnit pointSizeUnit() const
Returns the units used for the point size.
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 pointSize() const
Returns the point size.
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.
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.
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:39
#define QgsDebugError(str)
Definition qgslogger.h:38
QgsPointCloudRendererWidget *(* QgsPointCloudRendererWidgetFunc)(QgsPointCloudLayer *, QgsStyle *, QgsPointCloudRenderer *)