Skip to content

Commit f6f03cd

Browse files
committedNov 25, 2020
[api] Add z range filtering option to QgsMapSettings/QgsRenderContext/QgsMapCanvas
Allows for map renders to be filtered by a z or elevation range, such that only parts of the layer which are considered within this range will be rendered. Implements qgis/QGIS-Enhancement-Proposals#201 *Requires support for respecting the QgsRenderContext zRange to be added to the relevant map layer renderers
1 parent 95fa338 commit f6f03cd

File tree

12 files changed

+158
-2
lines changed

12 files changed

+158
-2
lines changed
 

‎python/core/auto_generated/qgsmapsettings.sip.in

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,24 @@ Returns the list of rendered feature handlers to use while rendering the map set
773773
.. seealso:: :py:func:`addRenderedFeatureHandler`
774774

775775
.. versionadded:: 3.10
776+
%End
777+
778+
QgsDoubleRange zRange() const;
779+
%Docstring
780+
Returns the range of z-values which will be visible in the map.
781+
782+
.. seealso:: :py:func:`setZRange`
783+
784+
.. versionadded:: 3.18
785+
%End
786+
787+
void setZRange( const QgsDoubleRange &range );
788+
%Docstring
789+
Sets the ``range`` of z-values which will be visible in the map.
790+
791+
.. seealso:: :py:func:`zRange`
792+
793+
.. versionadded:: 3.18
776794
%End
777795

778796
protected:

‎python/core/auto_generated/qgsrendercontext.sip.in

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,24 @@ rendering using QBrush objects.
864864
.. seealso:: :py:func:`textureOrigin`
865865

866866
.. versionadded:: 3.16
867+
%End
868+
869+
QgsDoubleRange zRange() const;
870+
%Docstring
871+
Returns the range of z-values which should be rendered.
872+
873+
.. seealso:: :py:func:`setZRange`
874+
875+
.. versionadded:: 3.18
876+
%End
877+
878+
void setZRange( const QgsDoubleRange &range );
879+
%Docstring
880+
Sets the ``range`` of z-values which should be rendered.
881+
882+
.. seealso:: :py:func:`zRange`
883+
884+
.. versionadded:: 3.18
867885
%End
868886

869887
};

‎python/gui/auto_generated/qgsmapcanvas.sip.in

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,24 @@ Set a list of resolutions (map units per pixel) to which to "snap to" when zoomi
971971
.. seealso:: :py:func:`setZoomResolutions`
972972

973973
.. versionadded:: 3.12
974+
%End
975+
976+
QgsDoubleRange zRange() const;
977+
%Docstring
978+
Returns the range of z-values which will be visible in the map.
979+
980+
.. seealso:: :py:func:`setZRange`
981+
982+
.. versionadded:: 3.18
983+
%End
984+
985+
void setZRange( const QgsDoubleRange &range );
986+
%Docstring
987+
Sets the ``range`` of z-values which will be visible in the map.
988+
989+
.. seealso:: :py:func:`zRange`
990+
991+
.. versionadded:: 3.18
974992
%End
975993

976994
signals:

‎src/core/qgsmapsettings.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,3 +747,13 @@ QList<QgsRenderedFeatureHandlerInterface *> QgsMapSettings::renderedFeatureHandl
747747
{
748748
return mRenderedFeatureHandlers;
749749
}
750+
751+
QgsDoubleRange QgsMapSettings::zRange() const
752+
{
753+
return mZRange;
754+
}
755+
756+
void QgsMapSettings::setZRange( const QgsDoubleRange &zRange )
757+
{
758+
mZRange = zRange;
759+
}

‎src/core/qgsmapsettings.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,22 @@ class CORE_EXPORT QgsMapSettings : public QgsTemporalRangeObject
676676
*/
677677
QList< QgsRenderedFeatureHandlerInterface * > renderedFeatureHandlers() const;
678678

679+
/**
680+
* Returns the range of z-values which will be visible in the map.
681+
*
682+
* \see setZRange()
683+
* \since QGIS 3.18
684+
*/
685+
QgsDoubleRange zRange() const;
686+
687+
/**
688+
* Sets the \a range of z-values which will be visible in the map.
689+
*
690+
* \see zRange()
691+
* \since QGIS 3.18
692+
*/
693+
void setZRange( const QgsDoubleRange &range );
694+
679695
protected:
680696

681697
double mDpi;
@@ -743,6 +759,9 @@ class CORE_EXPORT QgsMapSettings : public QgsTemporalRangeObject
743759
QList< QgsLabelBlockingRegion > mLabelBlockingRegions;
744760
QList< QgsMapClippingRegion > mClippingRegions;
745761
QList< QgsRenderedFeatureHandlerInterface * > mRenderedFeatureHandlers;
762+
763+
QgsDoubleRange mZRange;
764+
746765
};
747766

748767
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsMapSettings::Flags )

‎src/core/qgsrendercontext.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ QgsRenderContext::QgsRenderContext( const QgsRenderContext &rh )
7070
, mClippingRegions( rh.mClippingRegions )
7171
, mFeatureClipGeometry( rh.mFeatureClipGeometry )
7272
, mTextureOrigin( rh.mTextureOrigin )
73+
, mZRange( rh.mZRange )
7374
#ifdef QGISDEBUG
7475
, mHasTransformContext( rh.mHasTransformContext )
7576
#endif
@@ -106,6 +107,7 @@ QgsRenderContext &QgsRenderContext::operator=( const QgsRenderContext &rh )
106107
mClippingRegions = rh.mClippingRegions;
107108
mFeatureClipGeometry = rh.mFeatureClipGeometry;
108109
mTextureOrigin = rh.mTextureOrigin;
110+
mZRange = rh.mZRange;
109111
setIsTemporal( rh.isTemporal() );
110112
if ( isTemporal() )
111113
setTemporalRange( rh.temporalRange() );
@@ -238,6 +240,8 @@ QgsRenderContext QgsRenderContext::fromMapSettings( const QgsMapSettings &mapSet
238240
if ( ctx.isTemporal() )
239241
ctx.setTemporalRange( mapSettings.temporalRange() );
240242

243+
ctx.setZRange( mapSettings.zRange() );
244+
241245
ctx.mClippingRegions = mapSettings.clippingRegions();
242246

243247
return ctx;
@@ -547,4 +551,14 @@ void QgsRenderContext::setTextureOrigin( const QPointF &origin )
547551
mTextureOrigin = origin;
548552
}
549553

554+
QgsDoubleRange QgsRenderContext::zRange() const
555+
{
556+
return mZRange;
557+
}
558+
559+
void QgsRenderContext::setZRange( const QgsDoubleRange &range )
560+
{
561+
mZRange = range;
562+
}
563+
550564

‎src/core/qgsrendercontext.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,22 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
856856
*/
857857
void setTextureOrigin( const QPointF &origin );
858858

859+
/**
860+
* Returns the range of z-values which should be rendered.
861+
*
862+
* \see setZRange()
863+
* \since QGIS 3.18
864+
*/
865+
QgsDoubleRange zRange() const;
866+
867+
/**
868+
* Sets the \a range of z-values which should be rendered.
869+
*
870+
* \see zRange()
871+
* \since QGIS 3.18
872+
*/
873+
void setZRange( const QgsDoubleRange &range );
874+
859875
private:
860876

861877
Flags mFlags;
@@ -952,6 +968,8 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
952968

953969
QPointF mTextureOrigin;
954970

971+
QgsDoubleRange mZRange;
972+
955973
#ifdef QGISDEBUG
956974
bool mHasTransformContext = false;
957975
#endif

‎src/gui/qgsmapcanvas.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,6 +1326,16 @@ void QgsMapCanvas::zoomToSelected( QgsVectorLayer *layer )
13261326
zoomToFeatureExtent( rect );
13271327
}
13281328

1329+
QgsDoubleRange QgsMapCanvas::zRange() const
1330+
{
1331+
return mSettings.zRange();
1332+
}
1333+
1334+
void QgsMapCanvas::setZRange( const QgsDoubleRange &range )
1335+
{
1336+
mSettings.setZRange( range );
1337+
}
1338+
13291339
void QgsMapCanvas::zoomToFeatureExtent( QgsRectangle &rect )
13301340
{
13311341
// no selected features, only one selected point feature

‎src/gui/qgsmapcanvas.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,22 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
879879
*/
880880
const QList<double> &zoomResolutions() const { return mZoomResolutions; }
881881

882+
/**
883+
* Returns the range of z-values which will be visible in the map.
884+
*
885+
* \see setZRange()
886+
* \since QGIS 3.18
887+
*/
888+
QgsDoubleRange zRange() const;
889+
890+
/**
891+
* Sets the \a range of z-values which will be visible in the map.
892+
*
893+
* \see zRange()
894+
* \since QGIS 3.18
895+
*/
896+
void setZRange( const QgsDoubleRange &range );
897+
882898
private slots:
883899
//! called when current maptool is destroyed
884900
void mapToolDestroyed();

‎tests/src/core/testqgsmapsettings.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ void TestQgsMapSettings::testGettersSetters()
117117
simplify.setSimplifyHints( QgsVectorSimplifyMethod::GeometrySimplification );
118118
ms.setSimplifyMethod( simplify );
119119
QCOMPARE( ms.simplifyMethod().simplifyHints(), QgsVectorSimplifyMethod::GeometrySimplification );
120+
121+
QVERIFY( ms.zRange().isInfinite() );
122+
ms.setZRange( QgsDoubleRange( 1, 10 ) );
123+
QCOMPARE( ms.zRange(), QgsDoubleRange( 1, 10 ) );
120124
}
121125

122126
void TestQgsMapSettings::testLabelingEngineSettings()

‎tests/src/python/test_python_repr.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ def testDoubleRange(self):
316316
self.assertEqual(QgsDoubleRange(1, 10, False).__repr__(),
317317
"<QgsDoubleRange: (1, 10]>")
318318
self.assertEqual(QgsDoubleRange(1, 10, True, False).__repr__(),
319-
"<QgsDoubleRange: [1, 10)>")
319+
"<QgsDoubleRange: [1, 10)>")
320320

321321
def testIntRange(self):
322322
self.assertEqual(QgsIntRange(1, 10).__repr__(), "<QgsIntRange: [1, 10]>")

‎tests/src/python/test_qgsrendercontext.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
QgsRenderedFeatureHandlerInterface,
2626
QgsDateTimeRange,
2727
QgsMapClippingRegion,
28-
QgsGeometry)
28+
QgsGeometry,
29+
QgsDoubleRange)
2930
from qgis.PyQt.QtCore import QSize, QDateTime
3031
from qgis.PyQt.QtGui import QPainter, QImage
3132
from qgis.testing import start_app, unittest
@@ -58,6 +59,10 @@ def testGettersSetters(self):
5859
c.setMapExtent(QgsRectangle(1, 2, 3, 4))
5960
self.assertEqual(c.mapExtent(), QgsRectangle(1, 2, 3, 4))
6061

62+
self.assertTrue(c.zRange().isInfinite())
63+
c.setZRange(QgsDoubleRange(1, 10))
64+
self.assertEqual(c.zRange(), QgsDoubleRange(1, 10))
65+
6166
def testCopyConstructor(self):
6267
"""
6368
Test the copy constructor
@@ -66,10 +71,12 @@ def testCopyConstructor(self):
6671

6772
c1.setTextRenderFormat(QgsRenderContext.TextFormatAlwaysText)
6873
c1.setMapExtent(QgsRectangle(1, 2, 3, 4))
74+
c1.setZRange(QgsDoubleRange(1, 10))
6975

7076
c2 = QgsRenderContext(c1)
7177
self.assertEqual(c2.textRenderFormat(), QgsRenderContext.TextFormatAlwaysText)
7278
self.assertEqual(c2.mapExtent(), QgsRectangle(1, 2, 3, 4))
79+
self.assertEqual(c2.zRange(), QgsDoubleRange(1, 10))
7380

7481
c1.setTextRenderFormat(QgsRenderContext.TextFormatAlwaysOutlines)
7582
c2 = QgsRenderContext(c1)
@@ -129,17 +136,21 @@ def testFromMapSettings(self):
129136
ms.setFlag(QgsMapSettings.Antialiasing, True)
130137
ms.setFlag(QgsMapSettings.LosslessImageRendering, True)
131138
ms.setFlag(QgsMapSettings.Render3DMap, True)
139+
ms.setZRange(QgsDoubleRange(1, 10))
132140

133141
ms.setTextRenderFormat(QgsRenderContext.TextFormatAlwaysText)
134142
rc = QgsRenderContext.fromMapSettings(ms)
135143
self.assertEqual(rc.textRenderFormat(), QgsRenderContext.TextFormatAlwaysText)
136144
self.assertTrue(rc.testFlag(QgsRenderContext.Antialiasing))
137145
self.assertTrue(rc.testFlag(QgsRenderContext.LosslessImageRendering))
138146
self.assertTrue(rc.testFlag(QgsRenderContext.Render3DMap))
147+
self.assertEqual(ms.zRange(), QgsDoubleRange(1, 10))
139148

140149
ms.setTextRenderFormat(QgsRenderContext.TextFormatAlwaysOutlines)
150+
ms.setZRange(QgsDoubleRange())
141151
rc = QgsRenderContext.fromMapSettings(ms)
142152
self.assertEqual(rc.textRenderFormat(), QgsRenderContext.TextFormatAlwaysOutlines)
153+
self.assertTrue(ms.zRange().isInfinite())
143154

144155
self.assertEqual(rc.mapExtent(), QgsRectangle(10000, 20000, 30000, 40000))
145156

0 commit comments

Comments
 (0)
Please sign in to comment.