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 );
124 mEdlDistanceSpinBox->setClearValue( 0.5 );
125 mEdlStrengthSpinBox->setClearValue( 1000 );
126 connect( mEdlStrengthSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
127 connect( mEdlDistanceSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
130 mHillshadingZFactorSpinBox->setClearValue( 1.0 );
131 connect( mHillshadingZFactorSpinBox, qOverload<double>( &QDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
132 connect( mHillshadingMultidirCheckBox, &QCheckBox::toggled,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
134 mMaxErrorUnitWidget->setUnits(
137 mMaxErrorSpinBox->setClearValue( 0.3 );
139 mHorizontalTriangleThresholdSpinBox->setClearValue( 5.0 );
140 mHorizontalTriangleUnitWidget->setUnits(
144 connect( mMaxErrorSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
147 connect( mPointStyleComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
148 connect( mDrawOrderComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
150 connect( mEyeDomeLightingGroupBox, &QGroupBox::toggled,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
151 connect( mHillshadeGroupBox, &QGroupBox::toggled,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
153 connect( mTriangulateGroupBox, &QGroupBox::toggled,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
154 connect( mHorizontalTriangleCheckBox, &QCheckBox::clicked,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
155 connect( mHorizontalTriangleThresholdSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
160 if ( !mLayer->dataProvider()->subIndexes().isEmpty() )
162 mLabelOptions->setDialogTitle( tr(
"Customize label text" ) );
163 mLabelOptions->setText( tr(
"Label format" ) );
164 connect( mLabels, &QCheckBox::stateChanged,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
165 connect( mLabelOptions, &
QgsFontButton::changed,
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
168 if (
const QgsVirtualPointCloudProvider *vpcProvider =
dynamic_cast<QgsVirtualPointCloudProvider *
>( mLayer->dataProvider() ) )
170 if ( !vpcProvider->overviews().isEmpty() )
176 for (
auto it = mOverviewSwitchingScaleMap.constBegin(); it != mOverviewSwitchingScaleMap.constEnd(); ++it )
178 mOverviewSwitchingScale->addItem( it.value(), it.key() );
180 setOverviewSwitchingScale( 1.0 );
184 mZoomOutOptions->setEnabled(
false );
185 mOverviewSwitchingScale->setEnabled(
false );
188 connect( mOverviewSwitchingScale,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged );
190 connect( mZoomOutOptions, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [
this](
int ) {
194 mLabels->setEnabled(
false );
195 mLabelOptions->setEnabled(
false );
199 mLabels->setEnabled(
true );
200 mLabelOptions->setEnabled(
true );
207 mVpcGroupBox->setVisible(
false );
220 mActiveWidget->setContext( context );
226 mLayer = qobject_cast<QgsPointCloudLayer *>( layer );
228 mBlockChangedSignal =
true;
229 mOpacityWidget->setOpacity( mLayer->opacity() );
231 mBlendModeComboBox->setBlendMode( mLayer->blendMode() );
233 if ( mLayer->renderer() )
236 const QString rendererName = mLayer->renderer()->type();
238 const int rendererIdx = cboRenderers->findData( rendererName );
239 if ( cboRenderers->currentIndex() != rendererIdx )
241 cboRenderers->setCurrentIndex( rendererIdx );
249 Q_ASSERT( rendererIdx != -1 &&
"there must be a renderer!" );
251 mPointSizeSpinBox->setValue( mLayer->renderer()->pointSize() );
252 mPointSizeUnitWidget->setUnit( mLayer->renderer()->pointSizeUnit() );
253 mPointSizeUnitWidget->setMapUnitScale( mLayer->renderer()->pointSizeMapUnitScale() );
255 mPointStyleComboBox->setCurrentIndex( mPointStyleComboBox->findData( QVariant::fromValue( mLayer->renderer()->pointSymbol() ) ) );
256 mDrawOrderComboBox->setCurrentIndex( mDrawOrderComboBox->findData( QVariant::fromValue( mLayer->renderer()->drawOrder2d() ) ) );
258 mMaxErrorSpinBox->setValue( mLayer->renderer()->maximumScreenError() );
259 mMaxErrorUnitWidget->setUnit( mLayer->renderer()->maximumScreenErrorUnit() );
260 setOverviewSwitchingScale( mLayer->renderer()->overviewSwitchingScale() );
262 mTriangulateGroupBox->setChecked( mLayer->renderer()->renderAsTriangles() );
263 mHorizontalTriangleCheckBox->setChecked( mLayer->renderer()->horizontalTriangleFilter() );
264 mHorizontalTriangleThresholdSpinBox->setValue( mLayer->renderer()->horizontalTriangleFilterThreshold() );
265 mHorizontalTriangleUnitWidget->setUnit( mLayer->renderer()->horizontalTriangleFilterUnit() );
267 if ( !mLayer->dataProvider()->subIndexes().isEmpty() )
269 mLabels->setChecked( mLayer->renderer()->showLabels() );
270 mLabelOptions->setTextFormat( mLayer->renderer()->labelTextFormat() );
271 mZoomOutOptions->setCurrentIndex( mZoomOutOptions->findData( QVariant::fromValue( mLayer->renderer()->zoomOutBehavior() ) ) );
272 switch ( mLayer->renderer()->zoomOutBehavior() )
275 mLabels->setEnabled(
false );
276 mLabelOptions->setEnabled(
false );
279 mLabels->setEnabled(
true );
280 mLabelOptions->setEnabled(
true );
291 mEdlDistanceUnit->setUnits(
298 mDirectionalLightWidget->setAltitude( shadingRenderer.
lightAltitude() );
299 mDirectionalLightWidget->setAzimuth( shadingRenderer.
lightAzimuth() );
300 mDirectionalLightWidget->setEnableAzimuth( !mHillshadingMultidirCheckBox->isChecked() );
303 mColorExpressionWidget->setLayer( layer );
304 mColorExpressionWidget->registerExpressionContextGenerator(
this );
306 mDataDefinedProperties = mLayer->renderer()->dataDefinedProperties();
310 mBlockChangedSignal =
false;
316 mActiveWidget->setDockMode(
dockMode );
322 mLayer->setOpacity( mOpacityWidget->opacity() );
323 mLayer->setBlendMode( mBlendModeComboBox->blendMode() );
326 mLayer->setRenderer( mActiveWidget->renderer() );
327 else if ( !cboRenderers->currentData().toString().isEmpty() )
336 mLayer->renderer()->setPointSize( mPointSizeSpinBox->value() );
337 mLayer->renderer()->setPointSizeUnit( mPointSizeUnitWidget->unit() );
338 mLayer->renderer()->setPointSizeMapUnitScale( mPointSizeUnitWidget->getMapUnitScale() );
342 mLayer->renderer()->setMaximumScreenError( mMaxErrorSpinBox->value() );
343 mLayer->renderer()->setMaximumScreenErrorUnit( mMaxErrorUnitWidget->unit() );
346 mLayer->renderer()->setRenderAsTriangles( mTriangulateGroupBox->isChecked() );
347 mLayer->renderer()->setHorizontalTriangleFilter( mHorizontalTriangleCheckBox->isChecked() );
348 mLayer->renderer()->setHorizontalTriangleFilterThreshold( mHorizontalTriangleThresholdSpinBox->value() );
349 mLayer->renderer()->setHorizontalTriangleFilterUnit( mHorizontalTriangleUnitWidget->unit() );
351 mLayer->renderer()->setShowLabels( mLabels->isChecked() );
352 mLayer->renderer()->setLabelTextFormat( mLabelOptions->textFormat() );
355 mLayer->renderer()->setOverviewSwitchingScale( overviewSwitchingScale() );
361 shadingRenderer.
setActive( mEyeDomeLightingGroupBox->isChecked() || mHillshadeGroupBox->isChecked() );
371 mLayer->renderer()->setElevationShadingRenderer( shadingRenderer );
372 mLayer->renderer()->setDataDefinedProperties( mDataDefinedProperties );
375void QgsPointCloudRendererPropertiesWidget::rendererChanged()
377 if ( cboRenderers->currentIndex() == -1 )
379 QgsDebugError( u
"No current item -- this should never happen!"_s );
383 const QString rendererName = cboRenderers->currentData().toString();
386 std::unique_ptr<QgsPointCloudRenderer> oldRenderer;
387 std::unique_ptr<QgsPointCloudRenderer> newRenderer;
389 newRenderer.reset( mActiveWidget->renderer() );
393 oldRenderer = std::move( newRenderer );
397 oldRenderer.reset( mLayer->renderer()->clone() );
403 stackedWidget->removeWidget( mActiveWidget );
405 delete mActiveWidget;
406 mActiveWidget =
nullptr;
409 QgsPointCloudRendererWidget *widget =
nullptr;
411 if ( rendererMetadata )
418 mActiveWidget = widget;
419 stackedWidget->addWidget( mActiveWidget );
420 stackedWidget->setCurrentWidget( mActiveWidget );
422 if ( mMapCanvas || mMessageBar )
424 QgsSymbolWidgetContext context;
427 mActiveWidget->setContext( mContext );
437 stackedWidget->setCurrentWidget( pageNoWidget );
442void QgsPointCloudRendererPropertiesWidget::emitWidgetChanged()
444 if ( !mBlockChangedSignal )
448void QgsPointCloudRendererPropertiesWidget::updateDataDefinedProperty()
450 const QString expression = mColorExpressionWidget->expression();
451 if ( !expression.isEmpty() )
459void QgsPointCloudRendererPropertiesWidget::setOverviewSwitchingScale(
double scale )
461 mOverviewSwitchingScale->setCurrentIndex( mOverviewSwitchingScale->findData( scale ) );
464double QgsPointCloudRendererPropertiesWidget::overviewSwitchingScale()
const
466 return mOverviewSwitchingScaleMap.key( mOverviewSwitchingScale->currentText() );
471 if (
auto *lExpressionContext = mContext.expressionContext() )
472 return *lExpressionContext;
476 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 *)