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, [
this](
bool checked ) {
135 mDirectionalLightWidget->setEnableAzimuth( !checked );
139 mMaxErrorUnitWidget->setUnits(
142 mMaxErrorSpinBox->setClearValue( 0.3 );
144 mHorizontalTriangleThresholdSpinBox->setClearValue( 5.0 );
145 mHorizontalTriangleUnitWidget->setUnits(
149 connect( mMaxErrorSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
152 connect( mPointStyleComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
153 connect( mDrawOrderComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
155 connect( mEyeDomeLightingGroupBox, &QGroupBox::toggled,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
156 connect( mHillshadeGroupBox, &QGroupBox::toggled,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
158 connect( mTriangulateGroupBox, &QGroupBox::toggled,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
159 connect( mHorizontalTriangleCheckBox, &QCheckBox::clicked,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
160 connect( mHorizontalTriangleThresholdSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
165 if ( !mLayer->dataProvider()->subIndexes().isEmpty() )
167 mLabelOptions->setDialogTitle( tr(
"Customize label text" ) );
168 mLabelOptions->setText( tr(
"Label format" ) );
169 connect( mLabels, &QCheckBox::stateChanged,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
170 connect( mLabelOptions, &
QgsFontButton::changed,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
173 if (
const QgsVirtualPointCloudProvider *vpcProvider =
dynamic_cast<QgsVirtualPointCloudProvider *
>( mLayer->dataProvider() ) )
175 if ( !vpcProvider->overviews().isEmpty() )
181 for (
auto it = mOverviewSwitchingScaleMap.constBegin(); it != mOverviewSwitchingScaleMap.constEnd(); ++it )
183 mOverviewSwitchingScale->addItem( it.value(), it.key() );
185 setOverviewSwitchingScale( 1.0 );
189 mZoomOutOptions->setEnabled(
false );
190 mOverviewSwitchingScale->setEnabled(
false );
193 connect( mOverviewSwitchingScale,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
195 connect( mZoomOutOptions, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [
this](
int ) {
199 mLabels->setEnabled(
false );
200 mLabelOptions->setEnabled(
false );
204 mLabels->setEnabled(
true );
205 mLabelOptions->setEnabled(
true );
212 mVpcGroupBox->setVisible(
false );
225 mActiveWidget->setContext( context );
231 mLayer = qobject_cast<QgsPointCloudLayer *>(
layer );
233 mBlockChangedSignal =
true;
234 mOpacityWidget->setOpacity( mLayer->opacity() );
236 mBlendModeComboBox->setBlendMode( mLayer->blendMode() );
238 if ( mLayer->renderer() )
241 const QString rendererName = mLayer->renderer()->type();
243 const int rendererIdx = cboRenderers->findData( rendererName );
244 if ( cboRenderers->currentIndex() != rendererIdx )
246 cboRenderers->setCurrentIndex( rendererIdx );
254 Q_ASSERT( rendererIdx != -1 &&
"there must be a renderer!" );
256 mPointSizeSpinBox->setValue( mLayer->renderer()->pointSize() );
257 mPointSizeUnitWidget->setUnit( mLayer->renderer()->pointSizeUnit() );
258 mPointSizeUnitWidget->setMapUnitScale( mLayer->renderer()->pointSizeMapUnitScale() );
260 mPointStyleComboBox->setCurrentIndex( mPointStyleComboBox->findData( QVariant::fromValue( mLayer->renderer()->pointSymbol() ) ) );
261 mDrawOrderComboBox->setCurrentIndex( mDrawOrderComboBox->findData( QVariant::fromValue( mLayer->renderer()->drawOrder2d() ) ) );
263 mMaxErrorSpinBox->setValue( mLayer->renderer()->maximumScreenError() );
264 mMaxErrorUnitWidget->setUnit( mLayer->renderer()->maximumScreenErrorUnit() );
265 setOverviewSwitchingScale( mLayer->renderer()->overviewSwitchingScale() );
267 mTriangulateGroupBox->setChecked( mLayer->renderer()->renderAsTriangles() );
268 mHorizontalTriangleCheckBox->setChecked( mLayer->renderer()->horizontalTriangleFilter() );
269 mHorizontalTriangleThresholdSpinBox->setValue( mLayer->renderer()->horizontalTriangleFilterThreshold() );
270 mHorizontalTriangleUnitWidget->setUnit( mLayer->renderer()->horizontalTriangleFilterUnit() );
272 if ( !mLayer->dataProvider()->subIndexes().isEmpty() )
274 mLabels->setChecked( mLayer->renderer()->showLabels() );
275 mLabelOptions->setTextFormat( mLayer->renderer()->labelTextFormat() );
276 mZoomOutOptions->setCurrentIndex( mZoomOutOptions->findData( QVariant::fromValue( mLayer->renderer()->zoomOutBehavior() ) ) );
277 switch ( mLayer->renderer()->zoomOutBehavior() )
280 mLabels->setEnabled(
false );
281 mLabelOptions->setEnabled(
false );
284 mLabels->setEnabled(
true );
285 mLabelOptions->setEnabled(
true );
296 mEdlDistanceUnit->setUnits(
303 mDirectionalLightWidget->setAltitude( shadingRenderer.
lightAltitude() );
304 mDirectionalLightWidget->setAzimuth( shadingRenderer.
lightAzimuth() );
305 mDirectionalLightWidget->setEnableAzimuth( !mHillshadingMultidirCheckBox->isChecked() );
308 mColorExpressionWidget->setLayer(
layer );
309 mColorExpressionWidget->registerExpressionContextGenerator(
this );
311 mDataDefinedProperties = mLayer->renderer()->dataDefinedProperties();
315 mBlockChangedSignal =
false;
321 mActiveWidget->setDockMode(
dockMode );
327 mLayer->setOpacity( mOpacityWidget->opacity() );
328 mLayer->setBlendMode( mBlendModeComboBox->blendMode() );
331 mLayer->setRenderer( mActiveWidget->renderer() );
332 else if ( !cboRenderers->currentData().toString().isEmpty() )
341 mLayer->renderer()->setPointSize( mPointSizeSpinBox->value() );
342 mLayer->renderer()->setPointSizeUnit( mPointSizeUnitWidget->unit() );
343 mLayer->renderer()->setPointSizeMapUnitScale( mPointSizeUnitWidget->getMapUnitScale() );
347 mLayer->renderer()->setMaximumScreenError( mMaxErrorSpinBox->value() );
348 mLayer->renderer()->setMaximumScreenErrorUnit( mMaxErrorUnitWidget->unit() );
351 mLayer->renderer()->setRenderAsTriangles( mTriangulateGroupBox->isChecked() );
352 mLayer->renderer()->setHorizontalTriangleFilter( mHorizontalTriangleCheckBox->isChecked() );
353 mLayer->renderer()->setHorizontalTriangleFilterThreshold( mHorizontalTriangleThresholdSpinBox->value() );
354 mLayer->renderer()->setHorizontalTriangleFilterUnit( mHorizontalTriangleUnitWidget->unit() );
356 mLayer->renderer()->setShowLabels( mLabels->isChecked() );
357 mLayer->renderer()->setLabelTextFormat( mLabelOptions->textFormat() );
360 mLayer->renderer()->setOverviewSwitchingScale( overviewSwitchingScale() );
366 shadingRenderer.
setActive( mEyeDomeLightingGroupBox->isChecked() || mHillshadeGroupBox->isChecked() );
376 mLayer->renderer()->setElevationShadingRenderer( shadingRenderer );
377 mLayer->renderer()->setDataDefinedProperties( mDataDefinedProperties );
380void QgsPointCloudRendererPropertiesWidget::rendererChanged()
382 if ( cboRenderers->currentIndex() == -1 )
384 QgsDebugError( u
"No current item -- this should never happen!"_s );
388 const QString rendererName = cboRenderers->currentData().toString();
391 std::unique_ptr<QgsPointCloudRenderer> oldRenderer;
392 std::unique_ptr<QgsPointCloudRenderer> newRenderer;
394 newRenderer.reset( mActiveWidget->renderer() );
398 oldRenderer = std::move( newRenderer );
402 oldRenderer.reset( mLayer->renderer()->clone() );
408 stackedWidget->removeWidget( mActiveWidget );
410 delete mActiveWidget;
411 mActiveWidget =
nullptr;
414 QgsPointCloudRendererWidget *widget =
nullptr;
416 if ( rendererMetadata )
423 mActiveWidget = widget;
424 stackedWidget->addWidget( mActiveWidget );
425 stackedWidget->setCurrentWidget( mActiveWidget );
427 if ( mMapCanvas || mMessageBar )
429 QgsSymbolWidgetContext context;
432 mActiveWidget->setContext( mContext );
442 stackedWidget->setCurrentWidget( pageNoWidget );
447void QgsPointCloudRendererPropertiesWidget::emitWidgetChanged()
449 if ( !mBlockChangedSignal )
453void QgsPointCloudRendererPropertiesWidget::updateDataDefinedProperty()
455 const QString expression = mColorExpressionWidget->expression();
456 if ( !expression.isEmpty() )
464void QgsPointCloudRendererPropertiesWidget::setOverviewSwitchingScale(
double scale )
466 mOverviewSwitchingScale->setCurrentIndex( mOverviewSwitchingScale->findData( scale ) );
469double QgsPointCloudRendererPropertiesWidget::overviewSwitchingScale()
const
471 return mOverviewSwitchingScaleMap.key( mOverviewSwitchingScale->currentText() );
476 if (
auto *lExpressionContext = mContext.expressionContext() )
477 return *lExpressionContext;
481 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 *)