Add clipping regions to QgsMapSettings/QgsRenderContext API

This commit is contained in:
Nyall Dawson 2020-06-30 13:21:46 +10:00
parent 04f51371fc
commit e38bb541a6
8 changed files with 124 additions and 3 deletions

View File

@ -667,6 +667,24 @@ Returns the list of regions to avoid placing labels within.
.. seealso:: :py:func:`labelBoundaryGeometry`
.. versionadded:: 3.6
%End
void addClippingRegion( const QgsMapClippingRegion &region );
%Docstring
Adds a new clipping ``region`` to the map settings.
.. seealso:: :py:func:`clippingRegions`
.. versionadded:: 3.16
%End
QList< QgsMapClippingRegion > clippingRegions() const;
%Docstring
Returns the list of clipping regions to apply to the map.
.. seealso:: :py:func:`addClippingRegion`
.. versionadded:: 3.16
%End
void setSimplifyMethod( const QgsVectorSimplifyMethod &method );

View File

@ -12,7 +12,6 @@
class QgsRenderContext : QgsTemporalRangeObject
{
%Docstring
@ -27,6 +26,7 @@ to be rendered etc.
%End
public:
QgsRenderContext();
~QgsRenderContext();
QgsRenderContext( const QgsRenderContext &rh );
@ -787,6 +787,15 @@ Clears the specified custom rendering flag.
.. seealso:: :py:func:`setCustomRenderingFlag`
.. versionadded:: 3.12
%End
QList< QgsMapClippingRegion > clippingRegions() const;
%Docstring
Returns the list of clipping regions to apply during the render.
These regions are always in the final destination CRS for the map.
.. versionadded:: 3.16
%End
};

View File

@ -682,6 +682,16 @@ void QgsMapSettings::setLabelBoundaryGeometry( const QgsGeometry &boundary )
mLabelBoundaryGeometry = boundary;
}
void QgsMapSettings::addClippingRegion( const QgsMapClippingRegion &region )
{
mClippingRegions.append( region );
}
QList<QgsMapClippingRegion> QgsMapSettings::clippingRegions() const
{
return mClippingRegions;
}
void QgsMapSettings::addRenderedFeatureHandler( QgsRenderedFeatureHandlerInterface *handler )
{
mRenderedFeatureHandlers.append( handler );

View File

@ -33,6 +33,7 @@
#include "qgsmaplayer.h"
#include "qgsgeometry.h"
#include "qgstemporalrangeobject.h"
#include "qgsmapclippingregion.h"
class QPainter;
@ -578,6 +579,24 @@ class CORE_EXPORT QgsMapSettings : public QgsTemporalRangeObject
*/
QList< QgsLabelBlockingRegion > labelBlockingRegions() const { return mLabelBlockingRegions; }
/**
* Adds a new clipping \a region to the map settings.
*
* \see clippingRegions()
*
* \since QGIS 3.16
*/
void addClippingRegion( const QgsMapClippingRegion &region );
/**
* Returns the list of clipping regions to apply to the map.
*
* \see addClippingRegion()
*
* \since QGIS 3.16
*/
QList< QgsMapClippingRegion > clippingRegions() const;
/**
* Sets the simplification setting to use when rendering vector layers.
*
@ -692,6 +711,7 @@ class CORE_EXPORT QgsMapSettings : public QgsTemporalRangeObject
private:
QList< QgsLabelBlockingRegion > mLabelBlockingRegions;
QList< QgsMapClippingRegion > mClippingRegions;
QList< QgsRenderedFeatureHandlerInterface * > mRenderedFeatureHandlers;
};

View File

@ -37,6 +37,8 @@ QgsRenderContext::QgsRenderContext()
mDistanceArea.setEllipsoid( mDistanceArea.sourceCrs().ellipsoidAcronym() );
}
QgsRenderContext::~QgsRenderContext() = default;
QgsRenderContext::QgsRenderContext( const QgsRenderContext &rh )
: QgsTemporalRangeObject( rh )
, mFlags( rh.mFlags )
@ -65,6 +67,7 @@ QgsRenderContext::QgsRenderContext( const QgsRenderContext &rh )
, mHasRenderedFeatureHandlers( rh.mHasRenderedFeatureHandlers )
, mCustomRenderingFlags( rh.mCustomRenderingFlags )
, mDisabledSymbolLayers()
, mClippingRegions( rh.mClippingRegions )
#ifdef QGISDEBUG
, mHasTransformContext( rh.mHasTransformContext )
#endif
@ -98,6 +101,7 @@ QgsRenderContext &QgsRenderContext::operator=( const QgsRenderContext &rh )
mRenderedFeatureHandlers = rh.mRenderedFeatureHandlers;
mHasRenderedFeatureHandlers = rh.mHasRenderedFeatureHandlers;
mCustomRenderingFlags = rh.mCustomRenderingFlags;
mClippingRegions = rh.mClippingRegions;
setIsTemporal( rh.isTemporal() );
if ( isTemporal() )
setTemporalRange( rh.temporalRange() );
@ -209,6 +213,8 @@ QgsRenderContext QgsRenderContext::fromMapSettings( const QgsMapSettings &mapSet
if ( ctx.isTemporal() )
ctx.setTemporalRange( mapSettings.temporalRange() );
ctx.mClippingRegions = mapSettings.clippingRegions();
return ctx;
}
@ -491,4 +497,9 @@ QList<QgsRenderedFeatureHandlerInterface *> QgsRenderContext::renderedFeatureHan
return mRenderedFeatureHandlers;
}
QList<QgsMapClippingRegion> QgsRenderContext::clippingRegions() const
{
return mClippingRegions;
}

View File

@ -43,8 +43,8 @@ class QgsLabelingEngine;
class QgsMapSettings;
class QgsRenderedFeatureHandlerInterface;
class QgsSymbolLayer;
class QgsMaskIdProvider;
class QgsMapClippingRegion;
/**
@ -58,6 +58,7 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
{
public:
QgsRenderContext();
~QgsRenderContext() override;
QgsRenderContext( const QgsRenderContext &rh );
QgsRenderContext &operator=( const QgsRenderContext &rh );
@ -786,6 +787,15 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
*/
void clearCustomRenderingFlag( const QString &flag ) { mCustomRenderingFlags.remove( flag ); }
/**
* Returns the list of clipping regions to apply during the render.
*
* These regions are always in the final destination CRS for the map.
*
* \since QGIS 3.16
*/
QList< QgsMapClippingRegion > clippingRegions() const;
private:
Flags mFlags;
@ -877,6 +887,8 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
QSet<const QgsSymbolLayer *> mDisabledSymbolLayers;
QList< QgsMapClippingRegion > mClippingRegions;
#ifdef QGISDEBUG
bool mHasTransformContext = false;
#endif

View File

@ -61,6 +61,7 @@ class TestQgsMapSettings: public QObject
void testExpressionContext();
void testRenderedFeatureHandlers();
void testCustomRenderingFlags();
void testClippingRegions();
private:
QString toString( const QPolygonF &p, int decimalPlaces = 2 ) const;
@ -588,5 +589,32 @@ void TestQgsMapSettings::testCustomRenderingFlags()
Q_NOWARN_DEPRECATED_POP
}
void TestQgsMapSettings::testClippingRegions()
{
QgsMapSettings settings;
QVERIFY( settings.clippingRegions().isEmpty() );
QgsMapClippingRegion region( QgsGeometry::fromWkt( QStringLiteral( "Polygon(( 0 0, 1 0 , 1 1 , 0 1, 0 0 ))" ) ) );
settings.addClippingRegion( region );
QCOMPARE( settings.clippingRegions().size(), 1 );
QCOMPARE( settings.clippingRegions().at( 0 ).geometry().asWkt(), QStringLiteral( "Polygon ((0 0, 1 0, 1 1, 0 1, 0 0))" ) );
QgsMapClippingRegion region2( QgsGeometry::fromWkt( QStringLiteral( "Polygon(( 10 0, 11 0 , 11 1 , 10 1, 10 0 ))" ) ) );
settings.addClippingRegion( region2 );
QCOMPARE( settings.clippingRegions().size(), 2 );
QCOMPARE( settings.clippingRegions().at( 0 ).geometry().asWkt(), QStringLiteral( "Polygon ((0 0, 1 0, 1 1, 0 1, 0 0))" ) );
QCOMPARE( settings.clippingRegions().at( 1 ).geometry().asWkt(), QStringLiteral( "Polygon ((10 0, 11 0, 11 1, 10 1, 10 0))" ) );
QgsMapSettings settings2( settings );
QCOMPARE( settings2.clippingRegions().size(), 2 );
QCOMPARE( settings2.clippingRegions().at( 0 ).geometry().asWkt(), QStringLiteral( "Polygon ((0 0, 1 0, 1 1, 0 1, 0 0))" ) );
QCOMPARE( settings2.clippingRegions().at( 1 ).geometry().asWkt(), QStringLiteral( "Polygon ((10 0, 11 0, 11 1, 10 1, 10 0))" ) );
QgsMapSettings settings3;
settings3 = settings;
QCOMPARE( settings3.clippingRegions().size(), 2 );
QCOMPARE( settings3.clippingRegions().at( 0 ).geometry().asWkt(), QStringLiteral( "Polygon ((0 0, 1 0, 1 1, 0 1, 0 0))" ) );
QCOMPARE( settings3.clippingRegions().at( 1 ).geometry().asWkt(), QStringLiteral( "Polygon ((10 0, 11 0, 11 1, 10 1, 10 0))" ) ) ;
}
QGSTEST_MAIN( TestQgsMapSettings )
#include "testqgsmapsettings.moc"

View File

@ -23,7 +23,9 @@ from qgis.core import (QgsRenderContext,
QgsRectangle,
QgsVectorSimplifyMethod,
QgsRenderedFeatureHandlerInterface,
QgsDateTimeRange)
QgsDateTimeRange,
QgsMapClippingRegion,
QgsGeometry)
from qgis.PyQt.QtCore import QSize, QDateTime
from qgis.PyQt.QtGui import QPainter, QImage
from qgis.testing import start_app, unittest
@ -507,6 +509,17 @@ class TestQgsRenderContext(unittest.TestCase):
self.assertEqual(rc.isTemporal(), False)
self.assertIsNotNone(rc.temporalRange())
def testClippingRegion(self):
ms = QgsMapSettings()
rc = QgsRenderContext.fromMapSettings(ms)
self.assertFalse(rc.clippingRegions())
ms.addClippingRegion(QgsMapClippingRegion(QgsGeometry.fromWkt('Polygon(( 0 0, 1 0 , 1 1 , 0 1, 0 0 ))')))
ms.addClippingRegion(QgsMapClippingRegion(QgsGeometry.fromWkt('Polygon(( 10 0, 11 0 , 11 1 , 10 1, 10 0 ))')))
rc = QgsRenderContext.fromMapSettings(ms)
self.assertEqual(len(rc.clippingRegions()), 2)
self.assertEqual(rc.clippingRegions()[0].geometry().asWkt(), 'Polygon ((0 0, 1 0, 1 1, 0 1, 0 0))')
self.assertEqual(rc.clippingRegions()[1].geometry().asWkt(), 'Polygon ((10 0, 11 0, 11 1, 10 1, 10 0))')
if __name__ == '__main__':
unittest.main()