diff --git a/python/PyQt6/core/auto_additions/qgis.py b/python/PyQt6/core/auto_additions/qgis.py index c55fd59435e..bb55f022be0 100644 --- a/python/PyQt6/core/auto_additions/qgis.py +++ b/python/PyQt6/core/auto_additions/qgis.py @@ -11088,6 +11088,21 @@ Qgis.MouseHandlesAction.__doc__ = """Action to be performed by the mouse handles # -- Qgis.MouseHandlesAction.baseClass = Qgis # monkey patching scoped based enum +Qgis.PointCloudZoomOutBehavior.Extent.__doc__ = "" +Qgis.PointCloudZoomOutBehavior.Overview.__doc__ = "" +Qgis.PointCloudZoomOutBehavior.Both.__doc__ = "" +Qgis.PointCloudZoomOutBehavior.__doc__ = """Point cloud zoom out options + +.. versionadded:: 3.42 + +* ``Extent``: +* ``Overview``: +* ``Both``: + +""" +# -- +Qgis.PointCloudZoomOutBehavior.baseClass = Qgis +# monkey patching scoped based enum Qgis.MeshRangeLimit.NotSet.__doc__ = "User defined" Qgis.MeshRangeLimit.MinimumMaximum.__doc__ = "Real min-max values" Qgis.MeshRangeLimit.__doc__ = """Describes the limits used to compute mesh ranges (min/max values). diff --git a/python/PyQt6/core/auto_generated/pointcloud/qgspointcloudrenderer.sip.in b/python/PyQt6/core/auto_generated/pointcloud/qgspointcloudrenderer.sip.in index 4e67e5eae22..dae015de582 100644 --- a/python/PyQt6/core/auto_generated/pointcloud/qgspointcloudrenderer.sip.in +++ b/python/PyQt6/core/auto_generated/pointcloud/qgspointcloudrenderer.sip.in @@ -578,16 +578,16 @@ Returns the text format renderer is using for rendering labels .. versionadded:: 3.42 %End - void setShowExtends( const bool show ); + void setZoomOutBehavior( const Qgis::PointCloudZoomOutBehavior behavior ); %Docstring -Set whether the renderer should render point cloud extends instead of overview when zoomed out +Sets the renderer behavior when zoomed out .. versionadded:: 3.42 %End - bool showExtends() const; + Qgis::PointCloudZoomOutBehavior zoomOutBehavior() const; %Docstring -Returns whether the renderer renders point cloud extends instead of overview when zoomed out +Returns the renderer behavior when zoomed out .. versionadded:: 3.42 %End diff --git a/python/PyQt6/core/auto_generated/qgis.sip.in b/python/PyQt6/core/auto_generated/qgis.sip.in index 51de848c4c1..5829efa5b44 100644 --- a/python/PyQt6/core/auto_generated/qgis.sip.in +++ b/python/PyQt6/core/auto_generated/qgis.sip.in @@ -3249,6 +3249,13 @@ The development version UpdatedCanvas, }; + enum class PointCloudZoomOutBehavior /BaseType=IntEnum/ + { + Extent, + Overview, + Both + }; + enum class PointCloudAccessType /BaseType=IntEnum/ { Local, diff --git a/python/core/auto_generated/pointcloud/qgspointcloudrenderer.sip.in b/python/core/auto_generated/pointcloud/qgspointcloudrenderer.sip.in index 4e67e5eae22..dae015de582 100644 --- a/python/core/auto_generated/pointcloud/qgspointcloudrenderer.sip.in +++ b/python/core/auto_generated/pointcloud/qgspointcloudrenderer.sip.in @@ -578,16 +578,16 @@ Returns the text format renderer is using for rendering labels .. versionadded:: 3.42 %End - void setShowExtends( const bool show ); + void setZoomOutBehavior( const Qgis::PointCloudZoomOutBehavior behavior ); %Docstring -Set whether the renderer should render point cloud extends instead of overview when zoomed out +Sets the renderer behavior when zoomed out .. versionadded:: 3.42 %End - bool showExtends() const; + Qgis::PointCloudZoomOutBehavior zoomOutBehavior() const; %Docstring -Returns whether the renderer renders point cloud extends instead of overview when zoomed out +Returns the renderer behavior when zoomed out .. versionadded:: 3.42 %End diff --git a/python/core/auto_generated/qgis.sip.in b/python/core/auto_generated/qgis.sip.in index a978d6ff2b8..8ae9abd56da 100644 --- a/python/core/auto_generated/qgis.sip.in +++ b/python/core/auto_generated/qgis.sip.in @@ -3249,6 +3249,13 @@ The development version UpdatedCanvas, }; + enum class PointCloudZoomOutBehavior + { + Extent, + Overview, + Both + }; + enum class PointCloudAccessType { Local, diff --git a/src/core/pointcloud/qgspointcloudlayerrenderer.cpp b/src/core/pointcloud/qgspointcloudlayerrenderer.cpp index eaf918cdda5..8c7444f94f8 100644 --- a/src/core/pointcloud/qgspointcloudlayerrenderer.cpp +++ b/src/core/pointcloud/qgspointcloudlayerrenderer.cpp @@ -199,6 +199,7 @@ bool QgsPointCloudLayerRenderer::render() } else { + // we can be sure this won't fail as we are rendering virtual point clouds in this branch const QgsVirtualPointCloudProvider &vpcProvider = dynamic_cast( *mLayer->dataProvider() ); QVector< QgsPointCloudSubIndex > visibleIndexes; for ( const auto &si : mSubIndexes ) @@ -208,31 +209,37 @@ bool QgsPointCloudLayerRenderer::render() visibleIndexes.append( si ); } } - // if the overview of virtual point cloud exists and user hasn't requested point cloud extends we render overview, - // when we are zoomed out + const bool zoomedOut = renderExtent.width() > vpcProvider.averageSubIndexWidth() && + renderExtent.height() > vpcProvider.averageSubIndexHeight(); + // if the overview of virtual point cloud exists, and we are zoomed out, we render just overview if ( vpcProvider.overview() != nullptr && - !mRenderer->showExtends() && - renderExtent.width() > vpcProvider.averageSubIndexWidth() && - renderExtent.height() > vpcProvider.averageSubIndexHeight() ) + mRenderer->zoomOutBehavior() == Qgis::PointCloudZoomOutBehavior::Overview && + zoomedOut ) { renderIndex( vpcProvider.overview() ); } else { + // if the overview of virtual point cloud exists, and we are zoomed out, but we want both overview and extents, + // we render overview + if ( vpcProvider.overview() != nullptr && + mRenderer->zoomOutBehavior() == Qgis::PointCloudZoomOutBehavior::Both && + zoomedOut ) + { + renderIndex( vpcProvider.overview() ); + } mSubIndexExtentRenderer->startRender( context ); for ( const auto &si : visibleIndexes ) { if ( canceled ) break; - QgsPointCloudIndex pc = si.index(); - - if ( ( !pc || !pc.isValid() || mRenderer->showExtends() ) && - renderExtent.width() > vpcProvider.averageSubIndexWidth() && - renderExtent.height() > vpcProvider.averageSubIndexHeight() ) + QgsPointCloudIndex pc = si.index(); + // if the index of point cloud is invalid, or we are zoomed out and want extents, we render the point cloud extent + if ( !pc || !pc.isValid() || ( ( mRenderer->zoomOutBehavior() == Qgis::PointCloudZoomOutBehavior::Extent || mRenderer->zoomOutBehavior() == Qgis::PointCloudZoomOutBehavior::Both ) && + zoomedOut ) ) { mSubIndexExtentRenderer->renderExtent( si.polygonBounds(), context ); - // render the label of point cloud tile if ( mSubIndexExtentRenderer->showLabels() ) { mSubIndexExtentRenderer->renderLabel( @@ -241,6 +248,7 @@ bool QgsPointCloudLayerRenderer::render() context ); } } + // else we just render the visible point cloud else { canceled = !renderIndex( pc ); diff --git a/src/core/pointcloud/qgspointcloudrenderer.cpp b/src/core/pointcloud/qgspointcloudrenderer.cpp index a5cfdab88a2..2598989dcdd 100644 --- a/src/core/pointcloud/qgspointcloudrenderer.cpp +++ b/src/core/pointcloud/qgspointcloudrenderer.cpp @@ -25,6 +25,7 @@ #include "qgslogger.h" #include "qgscircle.h" #include "qgsunittypes.h" +#include "qgsvirtualpointcloudprovider.h" #include #include @@ -68,7 +69,7 @@ QgsPointCloudRenderer::QgsPointCloudRenderer() settings.setEnabled( true ); settings.setSize( 1 ); textFormat.setBuffer( settings ); - mLabelTextFormat = ( textFormat ); + mLabelTextFormat = textFormat; } QgsPointCloudRenderer *QgsPointCloudRenderer::load( QDomElement &element, const QgsReadWriteContext &context ) @@ -218,7 +219,7 @@ void QgsPointCloudRenderer::copyCommonProperties( QgsPointCloudRenderer *destina destination->setShowLabels( mShowLabels ); destination->setLabelTextFormat( mLabelTextFormat ); - destination->setShowExtends( mShowExtends ); + destination->setZoomOutBehavior( mZoomOutBehavior ); } void QgsPointCloudRenderer::restoreCommonProperties( const QDomElement &element, const QgsReadWriteContext &context ) @@ -243,7 +244,7 @@ void QgsPointCloudRenderer::restoreCommonProperties( const QDomElement &element, mLabelTextFormat = QgsTextFormat(); mLabelTextFormat.readXml( element.firstChildElement( QStringLiteral( "text-style" ) ), context ); } - mShowExtends = element.attribute( QStringLiteral( "showExtends" ), QStringLiteral( "0" ) ).toInt(); + mZoomOutBehavior = static_cast( element.attribute( QStringLiteral( "zoomOutBehavior" ), QStringLiteral( "0" ) ).toInt() ); } void QgsPointCloudRenderer::saveCommonProperties( QDomElement &element, const QgsReadWriteContext &context ) const @@ -269,7 +270,7 @@ void QgsPointCloudRenderer::saveCommonProperties( QDomElement &element, const Qg QDomDocument doc = element.ownerDocument(); element.appendChild( mLabelTextFormat.writeXml( doc, context ) ); } - element.setAttribute( QStringLiteral( "showExtends" ), QString::number( mShowExtends ) ); + element.setAttribute( QStringLiteral( "zoomOutBehavior" ), QString::number( static_cast( mZoomOutBehavior ) ) ); } Qgis::PointCloudSymbol QgsPointCloudRenderer::pointSymbol() const diff --git a/src/core/pointcloud/qgspointcloudrenderer.h b/src/core/pointcloud/qgspointcloudrenderer.h index 0a4711595cf..c3ced87cfc5 100644 --- a/src/core/pointcloud/qgspointcloudrenderer.h +++ b/src/core/pointcloud/qgspointcloudrenderer.h @@ -702,16 +702,16 @@ class CORE_EXPORT QgsPointCloudRenderer QgsTextFormat labelTextFormat() const { return mLabelTextFormat; } /** - * Set whether the renderer should render point cloud extends instead of overview when zoomed out + * Sets the renderer behavior when zoomed out * \since QGIS 3.42 */ - void setShowExtends( const bool show ) { mShowExtends = show; } + void setZoomOutBehavior( const Qgis::PointCloudZoomOutBehavior behavior ) { mZoomOutBehavior = behavior; } /** - * Returns whether the renderer renders point cloud extends instead of overview when zoomed out + * Returns the renderer behavior when zoomed out * \since QGIS 3.42 */ - bool showExtends() const { return mShowExtends; } + Qgis::PointCloudZoomOutBehavior zoomOutBehavior() const { return mZoomOutBehavior; } protected: @@ -855,7 +855,7 @@ class CORE_EXPORT QgsPointCloudRenderer bool mShowLabels = false; QgsTextFormat mLabelTextFormat; - bool mShowExtends = false; + Qgis::PointCloudZoomOutBehavior mZoomOutBehavior = Qgis::PointCloudZoomOutBehavior::Extent; }; #endif // QGSPOINTCLOUDRENDERER_H diff --git a/src/core/providers/vpc/qgsvirtualpointcloudprovider.cpp b/src/core/providers/vpc/qgsvirtualpointcloudprovider.cpp index d0d572f981d..3f5ad485fd0 100644 --- a/src/core/providers/vpc/qgsvirtualpointcloudprovider.cpp +++ b/src/core/providers/vpc/qgsvirtualpointcloudprovider.cpp @@ -538,7 +538,12 @@ QgsPointCloudRenderer *QgsVirtualPointCloudProvider::createRenderer( const QVari if ( mAttributes.indexOf( QLatin1String( "Classification" ) ) >= 0 ) { - return new QgsPointCloudClassifiedRenderer( QStringLiteral( "Classification" ), QgsPointCloudClassifiedRenderer::defaultCategories() ); + QgsPointCloudClassifiedRenderer *newRenderer = new QgsPointCloudClassifiedRenderer( QStringLiteral( "Classification" ), QgsPointCloudClassifiedRenderer::defaultCategories() ); + if ( mOverview != nullptr ) + { + newRenderer->setZoomOutBehavior( Qgis::PointCloudZoomOutBehavior::Overview ); + } + return newRenderer; } return new QgsPointCloudExtentRenderer(); diff --git a/src/core/qgis.h b/src/core/qgis.h index 1439ae053eb..d67fea0211d 100644 --- a/src/core/qgis.h +++ b/src/core/qgis.h @@ -5734,6 +5734,18 @@ class CORE_EXPORT Qgis }; Q_ENUM( PointCloudAccessType ) + /** + * Point cloud zoom out options + * \since QGIS 3.42 + */ + enum class PointCloudZoomOutBehavior : int + { + Extent, + Overview, + Both + }; + Q_ENUM( PointCloudZoomOutBehavior ) + /** * Identify search radius in mm */ diff --git a/src/gui/pointcloud/qgspointcloudrendererpropertieswidget.cpp b/src/gui/pointcloud/qgspointcloudrendererpropertieswidget.cpp index b0000b1d9b5..8e7b356dd56 100644 --- a/src/gui/pointcloud/qgspointcloudrendererpropertieswidget.cpp +++ b/src/gui/pointcloud/qgspointcloudrendererpropertieswidget.cpp @@ -33,6 +33,7 @@ #include "qgsstyle.h" #include "qgssymbolwidgetcontext.h" #include "qgstextformatwidget.h" +#include "qgsvirtualpointcloudprovider.h" static bool initPointCloudRenderer( const QString &name, QgsPointCloudRendererWidgetFunc f, const QString &iconName = QString() ) { @@ -125,12 +126,44 @@ QgsPointCloudRendererPropertiesWidget::QgsPointCloudRendererPropertiesWidget( Qg connect( mHorizontalTriangleUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged ); // show virtual point cloud options only when vpc layer is selected - bool showVpcOptions = !mLayer->dataProvider()->subIndexes().isEmpty(); - mVpcGroupBox->setVisible( showVpcOptions ); - mLabelOptions->setDialogTitle( tr( "Customize label text" ) ); - connect( mExtendsCheckBox, &QCheckBox::stateChanged, this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged ); - connect( mLabels, &QCheckBox::stateChanged, this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged ); - connect( mLabelOptions, &QgsFontButton::changed, this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged ); + if ( !mLayer->dataProvider()->subIndexes().isEmpty() ) + { + mLabelOptions->setDialogTitle( tr( "Customize label text" ) ); + connect( mLabels, &QCheckBox::stateChanged, this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged ); + connect( mLabelOptions, &QgsFontButton::changed, this, &QgsPointCloudRendererPropertiesWidget::emitWidgetChanged ); + mZoomOutOptions->addItem( tr( "Show extents only" ), static_cast( Qgis::PointCloudZoomOutBehavior::Extent ) ); + try + { + const QgsVirtualPointCloudProvider &vpcProvider = dynamic_cast( *mLayer->dataProvider() ); + if ( vpcProvider.overview() != nullptr ) + { + mZoomOutOptions->addItem( tr( "Show overview only" ), static_cast( Qgis::PointCloudZoomOutBehavior::Overview ) ); + mZoomOutOptions->addItem( tr( "Show extents over overview" ), static_cast( Qgis::PointCloudZoomOutBehavior::Both ) ); + } + } + catch ( const std::bad_cast & ) + { + mZoomOutOptions->setDisabled( true ); + } + connect( mZoomOutOptions, static_cast( &QComboBox::currentIndexChanged ), this, [this]() { + Qgis::PointCloudZoomOutBehavior zoomOutBehavior = static_cast( mZoomOutOptions->currentData().toInt() ); + if ( zoomOutBehavior == Qgis::PointCloudZoomOutBehavior::Overview ) + { + mLabels->setDisabled( true ); + mLabelOptions->setDisabled( true ); + } + else + { + mLabels->setDisabled( false ); + mLabelOptions->setDisabled( false ); + } + emitWidgetChanged(); + } ); + } + else + { + mVpcGroupBox->setVisible( false ); + } syncToLayer( layer ); } @@ -191,7 +224,17 @@ void QgsPointCloudRendererPropertiesWidget::syncToLayer( QgsMapLayer *layer ) { mLabels->setChecked( mLayer->renderer()->showLabels() ); mLabelOptions->setTextFormat( mLayer->renderer()->labelTextFormat() ); - mExtendsCheckBox->setChecked( mLayer->renderer()->showExtends() ); + mZoomOutOptions->setCurrentIndex( static_cast( mLayer->renderer()->zoomOutBehavior() ) ); + if ( mLayer->renderer()->zoomOutBehavior() == Qgis::PointCloudZoomOutBehavior::Overview ) + { + mLabels->setDisabled( true ); + mLabelOptions->setDisabled( true ); + } + else + { + mLabels->setDisabled( false ); + mLabelOptions->setDisabled( false ); + } } } @@ -235,7 +278,7 @@ void QgsPointCloudRendererPropertiesWidget::apply() mLayer->renderer()->setShowLabels( mLabels->isChecked() ); mLayer->renderer()->setLabelTextFormat( mLabelOptions->textFormat() ); - mLayer->renderer()->setShowExtends( mExtendsCheckBox->isChecked() ); + mLayer->renderer()->setZoomOutBehavior( static_cast( mZoomOutOptions->currentData().toInt() ) ); } void QgsPointCloudRendererPropertiesWidget::rendererChanged() diff --git a/src/ui/pointcloud/qgspointcloudrendererpropsdialogbase.ui b/src/ui/pointcloud/qgspointcloudrendererpropsdialogbase.ui index bd318a6fd24..6fd5eca3f68 100644 --- a/src/ui/pointcloud/qgspointcloudrendererpropsdialogbase.ui +++ b/src/ui/pointcloud/qgspointcloudrendererpropsdialogbase.ui @@ -181,13 +181,6 @@ false - - - - Show tile labels - - - @@ -201,6 +194,9 @@ + + + @@ -209,9 +205,16 @@ - + - Show point cloud extends + When zoomed out + + + + + + + Show tile labels