diff --git a/python/core/auto_generated/qgsmaplayerelevationproperties.sip.in b/python/core/auto_generated/qgsmaplayerelevationproperties.sip.in index f16ef20704c..bdc32f23fa7 100644 --- a/python/core/auto_generated/qgsmaplayerelevationproperties.sip.in +++ b/python/core/auto_generated/qgsmaplayerelevationproperties.sip.in @@ -37,6 +37,11 @@ how an individual QgsMapLayer behaves with relation to z values or elevations. QgsMapLayerElevationProperties( QObject *parent /TransferThis/ ); %Docstring Constructor for QgsMapLayerElevationProperties, with the specified ``parent`` object. +%End + + virtual bool hasElevation() const; +%Docstring +Returns ``True`` if the layer has an elevation or z component. %End virtual QDomElement writeXml( QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context ) = 0; diff --git a/python/gui/auto_generated/qgsmapcanvas.sip.in b/python/gui/auto_generated/qgsmapcanvas.sip.in index 76e0eaae610..9a01e446d99 100644 --- a/python/gui/auto_generated/qgsmapcanvas.sip.in +++ b/python/gui/auto_generated/qgsmapcanvas.sip.in @@ -979,6 +979,8 @@ Returns the range of z-values which will be visible in the map. .. seealso:: :py:func:`setZRange` +.. seealso:: :py:func:`zRangeChanged` + .. versionadded:: 3.18 %End @@ -988,6 +990,8 @@ Sets the ``range`` of z-values which will be visible in the map. .. seealso:: :py:func:`zRange` +.. seealso:: :py:func:`zRangeChanged` + .. versionadded:: 3.18 %End @@ -1171,6 +1175,16 @@ Emitted when the map canvas temporal range changes. .. versionadded:: 3.14 %End + void zRangeChanged(); +%Docstring +Emitted when the map canvas z (elevation) range changes. + +.. seealso:: :py:func:`zRange` + +.. seealso:: :py:func:`setZRange` + +.. versionadded:: 3.18 +%End void contextMenuAboutToShow( QMenu *menu, QgsMapMouseEvent *event ); %Docstring @@ -1180,7 +1194,6 @@ Can be used to extend the context menu. .. versionadded:: 3.16 %End - protected: virtual bool event( QEvent *e ); diff --git a/src/core/qgsmaplayerelevationproperties.cpp b/src/core/qgsmaplayerelevationproperties.cpp index 3b720bea9d8..e12396ae9a2 100644 --- a/src/core/qgsmaplayerelevationproperties.cpp +++ b/src/core/qgsmaplayerelevationproperties.cpp @@ -22,6 +22,11 @@ QgsMapLayerElevationProperties::QgsMapLayerElevationProperties( QObject *parent { } +bool QgsMapLayerElevationProperties::hasElevation() const +{ + return false; +} + bool QgsMapLayerElevationProperties::isVisibleInZRange( const QgsDoubleRange & ) const { return true; diff --git a/src/core/qgsmaplayerelevationproperties.h b/src/core/qgsmaplayerelevationproperties.h index be718289010..3c00ff2c6d1 100644 --- a/src/core/qgsmaplayerelevationproperties.h +++ b/src/core/qgsmaplayerelevationproperties.h @@ -58,6 +58,11 @@ class CORE_EXPORT QgsMapLayerElevationProperties : public QObject */ QgsMapLayerElevationProperties( QObject *parent SIP_TRANSFERTHIS ); + /** + * Returns TRUE if the layer has an elevation or z component. + */ + virtual bool hasElevation() const; + /** * Writes the properties to a DOM \a element, to be used later with readXml(). * diff --git a/src/gui/qgsmapcanvas.cpp b/src/gui/qgsmapcanvas.cpp index fbb7d4e6a3d..99fd604d8a7 100644 --- a/src/gui/qgsmapcanvas.cpp +++ b/src/gui/qgsmapcanvas.cpp @@ -84,6 +84,7 @@ email : sherman at mrcc.com #include "qgsruntimeprofiler.h" #include "qgsprojectionselectiondialog.h" #include "qgsannotationlayer.h" +#include "qgsmaplayerelevationproperties.h" /** * \ingroup gui @@ -731,6 +732,7 @@ void QgsMapCanvas::rendererJobFinished() { mRefreshAfterJob = false; clearTemporalCache(); + clearElevationCache(); refresh(); } } @@ -806,6 +808,24 @@ void QgsMapCanvas::clearTemporalCache() } } +void QgsMapCanvas::clearElevationCache() +{ + if ( mCache ) + { + const QList layerList = mapSettings().layers(); + for ( QgsMapLayer *layer : layerList ) + { + if ( layer->elevationProperties() && layer->elevationProperties()->hasElevation() ) + { + if ( layer->elevationProperties()->flags() & QgsMapLayerElevationProperties::FlagDontInvalidateCachedRendersWhenRangeChanges ) + continue; + + mCache->invalidateCacheForLayer( layer ); + } + } + } +} + void QgsMapCanvas::showContextMenu( QgsMapMouseEvent *event ) { const QgsPointXY mapPoint = event->originalMapPoint(); @@ -1333,7 +1353,19 @@ QgsDoubleRange QgsMapCanvas::zRange() const void QgsMapCanvas::setZRange( const QgsDoubleRange &range ) { + if ( zRange() == range ) + return; + mSettings.setZRange( range ); + + emit zRangeChanged(); + + // we need to discard any previously cached images which are elevation aware, so that these will be updated when + // the canvas is redrawn + if ( !mJob ) + clearElevationCache(); + + autoRefreshTriggered(); } void QgsMapCanvas::zoomToFeatureExtent( QgsRectangle &rect ) diff --git a/src/gui/qgsmapcanvas.h b/src/gui/qgsmapcanvas.h index 58294d245e8..299dd4b58d0 100644 --- a/src/gui/qgsmapcanvas.h +++ b/src/gui/qgsmapcanvas.h @@ -883,6 +883,8 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView * Returns the range of z-values which will be visible in the map. * * \see setZRange() + * \see zRangeChanged() + * * \since QGIS 3.18 */ QgsDoubleRange zRange() const; @@ -891,6 +893,8 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView * Sets the \a range of z-values which will be visible in the map. * * \see zRange() + * \see zRangeChanged() + * * \since QGIS 3.18 */ void setZRange( const QgsDoubleRange &range ); @@ -1060,6 +1064,15 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView */ void temporalRangeChanged(); + /** + * Emitted when the map canvas z (elevation) range changes. + * + * \see zRange() + * \see setZRange() + * + * \since QGIS 3.18 + */ + void zRangeChanged(); /** * Emitted before the map canvas context menu will be shown. @@ -1069,7 +1082,6 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView */ void contextMenuAboutToShow( QMenu *menu, QgsMapMouseEvent *event ); - protected: bool event( QEvent *e ) override; @@ -1329,6 +1341,11 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView */ void clearTemporalCache(); + /** + * Removes any rendered images of elevation aware layers from cache + */ + void clearElevationCache(); + void showContextMenu( QgsMapMouseEvent *event ); friend class TestQgsMapCanvas;