Skip to content

Commit

Permalink
Add clipping regions to QgsMapSettings/QgsRenderContext API
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 2, 2020
1 parent 04f5137 commit e38bb54
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 3 deletions.
18 changes: 18 additions & 0 deletions python/core/auto_generated/qgsmapsettings.sip.in
Expand Up @@ -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 );
Expand Down
11 changes: 10 additions & 1 deletion python/core/auto_generated/qgsrendercontext.sip.in
Expand Up @@ -12,7 +12,6 @@




class QgsRenderContext : QgsTemporalRangeObject
{
%Docstring
Expand All @@ -27,6 +26,7 @@ to be rendered etc.
%End
public:
QgsRenderContext();
~QgsRenderContext();

QgsRenderContext( const QgsRenderContext &rh );

Expand Down Expand Up @@ -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

};
Expand Down
10 changes: 10 additions & 0 deletions src/core/qgsmapsettings.cpp
Expand Up @@ -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 );
Expand Down
20 changes: 20 additions & 0 deletions src/core/qgsmapsettings.h
Expand Up @@ -33,6 +33,7 @@
#include "qgsmaplayer.h"
#include "qgsgeometry.h"
#include "qgstemporalrangeobject.h"
#include "qgsmapclippingregion.h"

class QPainter;

Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -692,6 +711,7 @@ class CORE_EXPORT QgsMapSettings : public QgsTemporalRangeObject
private:

QList< QgsLabelBlockingRegion > mLabelBlockingRegions;
QList< QgsMapClippingRegion > mClippingRegions;
QList< QgsRenderedFeatureHandlerInterface * > mRenderedFeatureHandlers;
};

Expand Down
11 changes: 11 additions & 0 deletions src/core/qgsrendercontext.cpp
Expand Up @@ -37,6 +37,8 @@ QgsRenderContext::QgsRenderContext()
mDistanceArea.setEllipsoid( mDistanceArea.sourceCrs().ellipsoidAcronym() );
}

QgsRenderContext::~QgsRenderContext() = default;

QgsRenderContext::QgsRenderContext( const QgsRenderContext &rh )
: QgsTemporalRangeObject( rh )
, mFlags( rh.mFlags )
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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() );
Expand Down Expand Up @@ -209,6 +213,8 @@ QgsRenderContext QgsRenderContext::fromMapSettings( const QgsMapSettings &mapSet
if ( ctx.isTemporal() )
ctx.setTemporalRange( mapSettings.temporalRange() );

ctx.mClippingRegions = mapSettings.clippingRegions();

return ctx;
}

Expand Down Expand Up @@ -491,4 +497,9 @@ QList<QgsRenderedFeatureHandlerInterface *> QgsRenderContext::renderedFeatureHan
return mRenderedFeatureHandlers;
}

QList<QgsMapClippingRegion> QgsRenderContext::clippingRegions() const
{
return mClippingRegions;
}


14 changes: 13 additions & 1 deletion src/core/qgsrendercontext.h
Expand Up @@ -43,8 +43,8 @@ class QgsLabelingEngine;
class QgsMapSettings;
class QgsRenderedFeatureHandlerInterface;
class QgsSymbolLayer;

class QgsMaskIdProvider;
class QgsMapClippingRegion;


/**
Expand All @@ -58,6 +58,7 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
{
public:
QgsRenderContext();
~QgsRenderContext() override;

QgsRenderContext( const QgsRenderContext &rh );
QgsRenderContext &operator=( const QgsRenderContext &rh );
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -877,6 +887,8 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject

QSet<const QgsSymbolLayer *> mDisabledSymbolLayers;

QList< QgsMapClippingRegion > mClippingRegions;

#ifdef QGISDEBUG
bool mHasTransformContext = false;
#endif
Expand Down
28 changes: 28 additions & 0 deletions tests/src/core/testqgsmapsettings.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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"
15 changes: 14 additions & 1 deletion tests/src/python/test_qgsrendercontext.py
Expand Up @@ -23,7 +23,9 @@
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
Expand Down Expand Up @@ -507,6 +509,17 @@ def testTemporalState(self):
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()

0 comments on commit e38bb54

Please sign in to comment.