39#include "qgsvirtualpointcloudprovider.h"
43#include "moc_qgspointcloudrendererpropertieswidget.cpp"
45using namespace Qt::StringLiterals;
50 if ( !rendererAbstractMetadata )
53 if ( !rendererMetadata )
58 if ( !iconName.isEmpty() )
67void QgsPointCloudRendererPropertiesWidget::initRendererWidgetFunctions()
69 static bool sInitialized =
false;
73 initPointCloudRenderer( u
"extent"_s, QgsPointCloudExtentRendererWidget::create, u
"styleicons/pointcloudextent.svg"_s );
74 initPointCloudRenderer( u
"rgb"_s, QgsPointCloudRgbRendererWidget::create, u
"styleicons/multibandcolor.svg"_s );
75 initPointCloudRenderer( u
"ramp"_s, QgsPointCloudAttributeByRampRendererWidget::create, u
"styleicons/singlebandpseudocolor.svg"_s );
76 initPointCloudRenderer( u
"classified"_s, QgsPointCloudClassifiedRendererWidget::create, u
"styleicons/paletted.svg"_s );
88 layout()->setContentsMargins( 0, 0, 0, 0 );
91 initRendererWidgetFunctions();
95 for (
const QString &name : renderers )
98 cboRenderers->addItem( m->icon(), m->visibleName(), name );
101 cboRenderers->setCurrentIndex( -1 );
106 connect( cboRenderers,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsPointCloudRendererPropertiesWidget::rendererChanged );
108 connect( mBlendModeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
111 mPointSizeUnitWidget->setUnits(
115 connect( mPointSizeSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
116 mPointSizeSpinBox->setClearValue( 1.0 );
126 mEdlDistanceSpinBox->setClearValue( 0.5 );
127 mEdlStrengthSpinBox->setClearValue( 1000 );
128 connect( mEdlStrengthSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
129 connect( mEdlDistanceSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
132 mHillshadingZFactorSpinBox->setClearValue( 1.0 );
133 connect( mHillshadingZFactorSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
134 connect( mHillshadingMultidirCheckBox, &QCheckBox::toggled,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
136 mMaxErrorUnitWidget->setUnits(
139 mMaxErrorSpinBox->setClearValue( 0.3 );
141 mHorizontalTriangleThresholdSpinBox->setClearValue( 5.0 );
142 mHorizontalTriangleUnitWidget->setUnits(
146 connect( mMaxErrorSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
149 connect( mPointStyleComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
150 connect( mDrawOrderComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
152 connect( mEyeDomeLightingGroupBox, &QGroupBox::toggled,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
153 connect( mHillshadeGroupBox, &QGroupBox::toggled,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
155 connect( mTriangulateGroupBox, &QGroupBox::toggled,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
156 connect( mHorizontalTriangleCheckBox, &QCheckBox::clicked,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
157 connect( mHorizontalTriangleThresholdSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
162 if ( !mLayer->dataProvider()->subIndexes().isEmpty() )
164 mLabelOptions->setDialogTitle( tr(
"Customize label text" ) );
165 mLabelOptions->setText( tr(
"Label format" ) );
166 connect( mLabels, &QCheckBox::stateChanged,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
167 connect( mLabelOptions, &
QgsFontButton::changed,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
170 if (
const QgsVirtualPointCloudProvider *vpcProvider =
dynamic_cast<QgsVirtualPointCloudProvider *
>( mLayer->dataProvider() ) )
172 if ( !vpcProvider->overviews().isEmpty() )
178 for (
auto it = mOverviewSwitchingScaleMap.constBegin(); it != mOverviewSwitchingScaleMap.constEnd(); ++it )
180 mOverviewSwitchingScale->addItem( it.value(), it.key() );
182 setOverviewSwitchingScale( 1.0 );
186 mZoomOutOptions->setEnabled(
false );
187 mOverviewSwitchingScale->setEnabled(
false );
190 connect( mOverviewSwitchingScale,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
192 connect( mZoomOutOptions, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [
this](
int ) {
196 mLabels->setEnabled(
false );
197 mLabelOptions->setEnabled(
false );
201 mLabels->setEnabled(
true );
202 mLabelOptions->setEnabled(
true );
209 mVpcGroupBox->setVisible(
false );
222 mActiveWidget->setContext( context );
228 mLayer = qobject_cast<QgsPointCloudLayer *>(
layer );
230 mBlockChangedSignal =
true;
231 mOpacityWidget->setOpacity( mLayer->opacity() );
233 mBlendModeComboBox->setBlendMode( mLayer->blendMode() );
235 if ( mLayer->renderer() )
238 const QString rendererName = mLayer->renderer()->type();
240 const int rendererIdx = cboRenderers->findData( rendererName );
241 if ( cboRenderers->currentIndex() != rendererIdx )
243 cboRenderers->setCurrentIndex( rendererIdx );
251 Q_ASSERT( rendererIdx != -1 &&
"there must be a renderer!" );
253 mPointSizeSpinBox->setValue( mLayer->renderer()->pointSize() );
254 mPointSizeUnitWidget->setUnit( mLayer->renderer()->pointSizeUnit() );
255 mPointSizeUnitWidget->setMapUnitScale( mLayer->renderer()->pointSizeMapUnitScale() );
257 mPointStyleComboBox->setCurrentIndex( mPointStyleComboBox->findData( QVariant::fromValue( mLayer->renderer()->pointSymbol() ) ) );
258 mDrawOrderComboBox->setCurrentIndex( mDrawOrderComboBox->findData( QVariant::fromValue( mLayer->renderer()->drawOrder2d() ) ) );
260 mMaxErrorSpinBox->setValue( mLayer->renderer()->maximumScreenError() );
261 mMaxErrorUnitWidget->setUnit( mLayer->renderer()->maximumScreenErrorUnit() );
262 setOverviewSwitchingScale( mLayer->renderer()->overviewSwitchingScale() );
264 mTriangulateGroupBox->setChecked( mLayer->renderer()->renderAsTriangles() );
265 mHorizontalTriangleCheckBox->setChecked( mLayer->renderer()->horizontalTriangleFilter() );
266 mHorizontalTriangleThresholdSpinBox->setValue( mLayer->renderer()->horizontalTriangleFilterThreshold() );
267 mHorizontalTriangleUnitWidget->setUnit( mLayer->renderer()->horizontalTriangleFilterUnit() );
269 if ( !mLayer->dataProvider()->subIndexes().isEmpty() )
271 mLabels->setChecked( mLayer->renderer()->showLabels() );
272 mLabelOptions->setTextFormat( mLayer->renderer()->labelTextFormat() );
273 mZoomOutOptions->setCurrentIndex( mZoomOutOptions->findData( QVariant::fromValue( mLayer->renderer()->zoomOutBehavior() ) ) );
274 switch ( mLayer->renderer()->zoomOutBehavior() )
277 mLabels->setEnabled(
false );
278 mLabelOptions->setEnabled(
false );
281 mLabels->setEnabled(
true );
282 mLabelOptions->setEnabled(
true );
293 mEdlDistanceUnit->setUnits(
300 mDirectionalLightWidget->setAltitude( shadingRenderer.
lightAltitude() );
301 mDirectionalLightWidget->setAzimuth( shadingRenderer.
lightAzimuth() );
302 mDirectionalLightWidget->setEnableAzimuth( !mHillshadingMultidirCheckBox->isChecked() );
305 mColorExpressionWidget->setLayer(
layer );
306 mColorExpressionWidget->registerExpressionContextGenerator(
this );
308 mDataDefinedProperties = mLayer->renderer()->dataDefinedProperties();
312 mBlockChangedSignal =
false;
318 mActiveWidget->setDockMode(
dockMode );
324 mLayer->setOpacity( mOpacityWidget->opacity() );
325 mLayer->setBlendMode( mBlendModeComboBox->blendMode() );
328 mLayer->setRenderer( mActiveWidget->renderer() );
329 else if ( !cboRenderers->currentData().toString().isEmpty() )
338 mLayer->renderer()->setPointSize( mPointSizeSpinBox->value() );
339 mLayer->renderer()->setPointSizeUnit( mPointSizeUnitWidget->unit() );
340 mLayer->renderer()->setPointSizeMapUnitScale( mPointSizeUnitWidget->getMapUnitScale() );
344 mLayer->renderer()->setMaximumScreenError( mMaxErrorSpinBox->value() );
345 mLayer->renderer()->setMaximumScreenErrorUnit( mMaxErrorUnitWidget->unit() );
348 mLayer->renderer()->setRenderAsTriangles( mTriangulateGroupBox->isChecked() );
349 mLayer->renderer()->setHorizontalTriangleFilter( mHorizontalTriangleCheckBox->isChecked() );
350 mLayer->renderer()->setHorizontalTriangleFilterThreshold( mHorizontalTriangleThresholdSpinBox->value() );
351 mLayer->renderer()->setHorizontalTriangleFilterUnit( mHorizontalTriangleUnitWidget->unit() );
353 mLayer->renderer()->setShowLabels( mLabels->isChecked() );
354 mLayer->renderer()->setLabelTextFormat( mLabelOptions->textFormat() );
357 mLayer->renderer()->setOverviewSwitchingScale( overviewSwitchingScale() );
363 shadingRenderer.
setActive( mEyeDomeLightingGroupBox->isChecked() || mHillshadeGroupBox->isChecked() );
373 mLayer->renderer()->setElevationShadingRenderer( shadingRenderer );
374 mLayer->renderer()->setDataDefinedProperties( mDataDefinedProperties );
377void QgsPointCloudRendererPropertiesWidget::rendererChanged()
379 if ( cboRenderers->currentIndex() == -1 )
381 QgsDebugError( u
"No current item -- this should never happen!"_s );
385 const QString rendererName = cboRenderers->currentData().toString();
388 std::unique_ptr<QgsPointCloudRenderer> oldRenderer;
389 std::unique_ptr<QgsPointCloudRenderer> newRenderer;
391 newRenderer.reset( mActiveWidget->renderer() );
395 oldRenderer = std::move( newRenderer );
399 oldRenderer.reset( mLayer->renderer()->clone() );
405 stackedWidget->removeWidget( mActiveWidget );
407 delete mActiveWidget;
408 mActiveWidget =
nullptr;
411 QgsPointCloudRendererWidget *widget =
nullptr;
413 if ( rendererMetadata )
420 mActiveWidget = widget;
421 stackedWidget->addWidget( mActiveWidget );
422 stackedWidget->setCurrentWidget( mActiveWidget );
424 if ( mMapCanvas || mMessageBar )
426 QgsSymbolWidgetContext context;
429 mActiveWidget->setContext( mContext );
439 stackedWidget->setCurrentWidget( pageNoWidget );
444void QgsPointCloudRendererPropertiesWidget::emitWidgetChanged()
446 if ( !mBlockChangedSignal )
450void QgsPointCloudRendererPropertiesWidget::updateDataDefinedProperty()
452 const QString expression = mColorExpressionWidget->expression();
453 if ( !expression.isEmpty() )
461void QgsPointCloudRendererPropertiesWidget::setOverviewSwitchingScale(
double scale )
463 mOverviewSwitchingScale->setCurrentIndex( mOverviewSwitchingScale->findData( scale ) );
466double QgsPointCloudRendererPropertiesWidget::overviewSwitchingScale()
const
468 return mOverviewSwitchingScaleMap.key( mOverviewSwitchingScale->currentText() );
473 if (
auto *lExpressionContext = mContext.expressionContext() )
474 return *lExpressionContext;
478 auto pointCloudScope = std::make_unique<QgsExpressionContextScope>( tr(
"Point Cloud" ) );
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(...
Single scope for storing variables and functions for use within a QgsExpressionContext.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
static const QString EXPR_ORIGINAL_VALUE
Inbuilt variable name for value original value variable.
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 store for object properties.
QString expressionString() const
Returns the expression used for the property value.
static QgsProperty fromExpression(const QString &expression, bool isActive=true)
Returns a new ExpressionBasedProperty created from the specified expression.
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 *)