36#include "qgsvirtualpointcloudprovider.h"
40#include "moc_qgspointcloudrendererpropertieswidget.cpp"
42using namespace Qt::StringLiterals;
47 if ( !rendererAbstractMetadata )
50 if ( !rendererMetadata )
55 if ( !iconName.isEmpty() )
64void QgsPointCloudRendererPropertiesWidget::initRendererWidgetFunctions()
66 static bool sInitialized =
false;
70 initPointCloudRenderer( u
"extent"_s, QgsPointCloudExtentRendererWidget::create, u
"styleicons/pointcloudextent.svg"_s );
71 initPointCloudRenderer( u
"rgb"_s, QgsPointCloudRgbRendererWidget::create, u
"styleicons/multibandcolor.svg"_s );
72 initPointCloudRenderer( u
"ramp"_s, QgsPointCloudAttributeByRampRendererWidget::create, u
"styleicons/singlebandpseudocolor.svg"_s );
73 initPointCloudRenderer( u
"classified"_s, QgsPointCloudClassifiedRendererWidget::create, u
"styleicons/paletted.svg"_s );
85 layout()->setContentsMargins( 0, 0, 0, 0 );
88 initRendererWidgetFunctions();
92 for (
const QString &name : renderers )
95 cboRenderers->addItem( m->icon(), m->visibleName(), name );
98 cboRenderers->setCurrentIndex( -1 );
103 connect( cboRenderers,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsPointCloudRendererPropertiesWidget::rendererChanged );
105 connect( mBlendModeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
108 mPointSizeUnitWidget->setUnits(
112 connect( mPointSizeSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
121 mEdlDistanceSpinBox->setClearValue( 0.5 );
122 mEdlStrengthSpinBox->setClearValue( 1000 );
123 connect( mEdlStrengthSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
124 connect( mEdlDistanceSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
127 mHillshadingZFactorSpinBox->setClearValue( 1.0 );
128 connect( mHillshadingZFactorSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
129 connect( mHillshadingMultidirCheckBox, &QCheckBox::toggled,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
131 mMaxErrorUnitWidget->setUnits(
134 mMaxErrorSpinBox->setClearValue( 0.3 );
136 mHorizontalTriangleThresholdSpinBox->setClearValue( 5.0 );
137 mHorizontalTriangleUnitWidget->setUnits(
141 connect( mMaxErrorSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
144 connect( mPointStyleComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
145 connect( mDrawOrderComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
147 connect( mEyeDomeLightingGroupBox, &QGroupBox::toggled,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
148 connect( mHillshadeGroupBox, &QGroupBox::toggled,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
150 connect( mTriangulateGroupBox, &QGroupBox::toggled,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
151 connect( mHorizontalTriangleCheckBox, &QCheckBox::clicked,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
152 connect( mHorizontalTriangleThresholdSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
156 if ( !mLayer->dataProvider()->subIndexes().isEmpty() )
158 mLabelOptions->setDialogTitle( tr(
"Customize label text" ) );
159 mLabelOptions->setText( tr(
"Label format" ) );
160 connect( mLabels, &QCheckBox::stateChanged,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
161 connect( mLabelOptions, &
QgsFontButton::changed,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
164 if (
const QgsVirtualPointCloudProvider *vpcProvider =
dynamic_cast<QgsVirtualPointCloudProvider *
>( mLayer->dataProvider() ) )
166 if ( !vpcProvider->overviews().isEmpty() )
172 for (
auto it = mOverviewSwitchingScaleMap.constBegin(); it != mOverviewSwitchingScaleMap.constEnd(); ++it )
174 mOverviewSwitchingScale->addItem( it.value(), it.key() );
176 setOverviewSwitchingScale( 1.0 );
180 mZoomOutOptions->setEnabled(
false );
181 mOverviewSwitchingScale->setEnabled(
false );
184 connect( mOverviewSwitchingScale,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
186 connect( mZoomOutOptions, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [
this](
int ) {
190 mLabels->setEnabled(
false );
191 mLabelOptions->setEnabled(
false );
195 mLabels->setEnabled(
true );
196 mLabelOptions->setEnabled(
true );
203 mVpcGroupBox->setVisible(
false );
215 mActiveWidget->setContext( context );
221 mLayer = qobject_cast<QgsPointCloudLayer *>( layer );
223 mBlockChangedSignal =
true;
224 mOpacityWidget->setOpacity( mLayer->opacity() );
226 mBlendModeComboBox->setBlendMode( mLayer->blendMode() );
228 if ( mLayer->renderer() )
231 const QString rendererName = mLayer->renderer()->type();
233 const int rendererIdx = cboRenderers->findData( rendererName );
234 if ( cboRenderers->currentIndex() != rendererIdx )
236 cboRenderers->setCurrentIndex( rendererIdx );
244 Q_ASSERT( rendererIdx != -1 &&
"there must be a renderer!" );
246 mPointSizeSpinBox->setValue( mLayer->renderer()->pointSize() );
247 mPointSizeUnitWidget->setUnit( mLayer->renderer()->pointSizeUnit() );
248 mPointSizeUnitWidget->setMapUnitScale( mLayer->renderer()->pointSizeMapUnitScale() );
250 mPointStyleComboBox->setCurrentIndex( mPointStyleComboBox->findData( QVariant::fromValue( mLayer->renderer()->pointSymbol() ) ) );
251 mDrawOrderComboBox->setCurrentIndex( mDrawOrderComboBox->findData( QVariant::fromValue( mLayer->renderer()->drawOrder2d() ) ) );
253 mMaxErrorSpinBox->setValue( mLayer->renderer()->maximumScreenError() );
254 mMaxErrorUnitWidget->setUnit( mLayer->renderer()->maximumScreenErrorUnit() );
255 setOverviewSwitchingScale( mLayer->renderer()->overviewSwitchingScale() );
257 mTriangulateGroupBox->setChecked( mLayer->renderer()->renderAsTriangles() );
258 mHorizontalTriangleCheckBox->setChecked( mLayer->renderer()->horizontalTriangleFilter() );
259 mHorizontalTriangleThresholdSpinBox->setValue( mLayer->renderer()->horizontalTriangleFilterThreshold() );
260 mHorizontalTriangleUnitWidget->setUnit( mLayer->renderer()->horizontalTriangleFilterUnit() );
262 if ( !mLayer->dataProvider()->subIndexes().isEmpty() )
264 mLabels->setChecked( mLayer->renderer()->showLabels() );
265 mLabelOptions->setTextFormat( mLayer->renderer()->labelTextFormat() );
266 mZoomOutOptions->setCurrentIndex( mZoomOutOptions->findData( QVariant::fromValue( mLayer->renderer()->zoomOutBehavior() ) ) );
267 switch ( mLayer->renderer()->zoomOutBehavior() )
270 mLabels->setEnabled(
false );
271 mLabelOptions->setEnabled(
false );
274 mLabels->setEnabled(
true );
275 mLabelOptions->setEnabled(
true );
286 mEdlDistanceUnit->setUnits(
293 mDirectionalLightWidget->setAltitude( shadingRenderer.
lightAltitude() );
294 mDirectionalLightWidget->setAzimuth( shadingRenderer.
lightAzimuth() );
295 mDirectionalLightWidget->setEnableAzimuth( !mHillshadingMultidirCheckBox->isChecked() );
298 mBlockChangedSignal =
false;
304 mActiveWidget->setDockMode(
dockMode );
310 mLayer->setOpacity( mOpacityWidget->opacity() );
311 mLayer->setBlendMode( mBlendModeComboBox->blendMode() );
314 mLayer->setRenderer( mActiveWidget->renderer() );
315 else if ( !cboRenderers->currentData().toString().isEmpty() )
324 mLayer->renderer()->setPointSize( mPointSizeSpinBox->value() );
325 mLayer->renderer()->setPointSizeUnit( mPointSizeUnitWidget->unit() );
326 mLayer->renderer()->setPointSizeMapUnitScale( mPointSizeUnitWidget->getMapUnitScale() );
330 mLayer->renderer()->setMaximumScreenError( mMaxErrorSpinBox->value() );
331 mLayer->renderer()->setMaximumScreenErrorUnit( mMaxErrorUnitWidget->unit() );
334 mLayer->renderer()->setRenderAsTriangles( mTriangulateGroupBox->isChecked() );
335 mLayer->renderer()->setHorizontalTriangleFilter( mHorizontalTriangleCheckBox->isChecked() );
336 mLayer->renderer()->setHorizontalTriangleFilterThreshold( mHorizontalTriangleThresholdSpinBox->value() );
337 mLayer->renderer()->setHorizontalTriangleFilterUnit( mHorizontalTriangleUnitWidget->unit() );
339 mLayer->renderer()->setShowLabels( mLabels->isChecked() );
340 mLayer->renderer()->setLabelTextFormat( mLabelOptions->textFormat() );
343 mLayer->renderer()->setOverviewSwitchingScale( overviewSwitchingScale() );
349 shadingRenderer.
setActive( mEyeDomeLightingGroupBox->isChecked() || mHillshadeGroupBox->isChecked() );
359 mLayer->renderer()->setElevationShadingRenderer( shadingRenderer );
362void QgsPointCloudRendererPropertiesWidget::rendererChanged()
364 if ( cboRenderers->currentIndex() == -1 )
366 QgsDebugError( u
"No current item -- this should never happen!"_s );
370 const QString rendererName = cboRenderers->currentData().toString();
373 std::unique_ptr<QgsPointCloudRenderer> oldRenderer;
374 std::unique_ptr<QgsPointCloudRenderer> newRenderer;
376 newRenderer.reset( mActiveWidget->renderer() );
380 oldRenderer = std::move( newRenderer );
384 oldRenderer.reset( mLayer->renderer()->clone() );
390 stackedWidget->removeWidget( mActiveWidget );
392 delete mActiveWidget;
393 mActiveWidget =
nullptr;
396 QgsPointCloudRendererWidget *widget =
nullptr;
398 if ( rendererMetadata )
405 mActiveWidget = widget;
406 stackedWidget->addWidget( mActiveWidget );
407 stackedWidget->setCurrentWidget( mActiveWidget );
409 if ( mMapCanvas || mMessageBar )
411 QgsSymbolWidgetContext context;
414 mActiveWidget->setContext( context );
424 stackedWidget->setCurrentWidget( pageNoWidget );
429void QgsPointCloudRendererPropertiesWidget::emitWidgetChanged()
431 if ( !mBlockChangedSignal )
435void QgsPointCloudRendererPropertiesWidget::setOverviewSwitchingScale(
double scale )
437 mOverviewSwitchingScale->setCurrentIndex( mOverviewSwitchingScale->findData( scale ) );
440double QgsPointCloudRendererPropertiesWidget::overviewSwitchingScale()
const
442 return mOverviewSwitchingScaleMap.key( mOverviewSwitchingScale->currentText() );
PointCloudSymbol
Rendering symbols for point cloud points.
@ Circle
Renders points as circles.
@ Square
Renders points as squares.
PointCloudDrawOrder
Pointcloud rendering order for 2d views.
@ 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.
PointCloudZoomOutRenderBehavior
Point cloud zoom out options.
@ RenderOverviewAndExtents
Render point cloud extents over overview point cloud.
@ RenderExtents
Render only point cloud extents when zoomed out.
@ RenderOverview
Render overview point cloud when zoomed out.
@ Millimeters
Millimeters.
@ Points
Points (e.g., for font sizes).
@ 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.
Renders elevation shading on an image with different methods (eye dome lighting, hillshading,...
bool isActiveHillshading() const
Returns whether the hillshading is active.
void setActive(bool active)
Sets whether this shading renderer is active.
double hillshadingZFactor() const
Returns the z factor used by the hill shading method.
double eyeDomeLightingStrength() const
Returns the strength of the eye dome lighting method.
void setLightAzimuth(double lightAzimuth)
Sets the azimuth of the light (degree) that can be used by some methods (e.g.
double lightAltitude() const
Returns the altitude of the light (degree) that can be used by some methods (e.g.
void setHillshadingMultidirectional(bool multiDirectional)
Sets whether the hill shading method is multidirectional.
double eyeDomeLightingDistance() const
Returns the distance of the eye dome lighting method, that is the distance where the effect is apply ...
void setLightAltitude(double lightAltitude)
Sets the altitude of the light (degree) that can be used by some methods (e.g.
void setEyeDomeLightingStrength(double strength)
Sets the strength of the eye dome lighting method.
void setEyeDomeLightingDistanceUnit(Qgis::RenderUnit unit)
Sets the unit of the distance of the eye dome lighting method set by setEyeDomeLightingDistance().
void setActiveHillshading(bool active)
Sets active the hillshading.
bool isHillshadingMultidirectional() const
Returns whether the hill shading method is multidirectional.
void setHillshadingZFactor(double zFactor)
Sets the z factor used by the hill shading method.
bool isActiveEyeDomeLighting() const
Returns whether eye-dome lighting shading method is active.
void setEyeDomeLightingDistance(double distance)
Sets the distance of the eye dome lighting method, that is the distance where the effect is apply fro...
void setActiveEyeDomeLighting(bool active)
Sets active the eye-dome lighting shading method.
double lightAzimuth() const
Returns the azimuth of the light (degree) that can be used by some methods (e.g.
Qgis::RenderUnit eyeDomeLightingDistanceUnit() const
Returns the unit of the distance of the eye dome lighting method returned by eyeDomeLightingDistance(...
Base class for all map layer types.
Represents a map layer supporting display of point clouds.
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.
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.
A container for the context for various read/write operations on objects.
A database of saved style entities, including symbols, color ramps, text formats and others.
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)
#define QgsDebugError(str)
QgsPointCloudRendererWidget *(* QgsPointCloudRendererWidgetFunc)(QgsPointCloudLayer *, QgsStyle *, QgsPointCloudRenderer *)