Skip to content

Commit

Permalink
Create new class QgsMapClippingRegion, for encapsulation of an area
Browse files Browse the repository at this point in the history
and method to use to clip a map render
  • Loading branch information
nyalldawson committed Jul 2, 2020
1 parent a9eb718 commit 04f5137
Show file tree
Hide file tree
Showing 8 changed files with 296 additions and 0 deletions.
7 changes: 7 additions & 0 deletions python/core/auto_additions/qgsmapclippingregion.py
@@ -0,0 +1,7 @@
# The following has been generated automatically from src/core/qgsmapclippingregion.h
# monkey patching scoped based enum
QgsMapClippingRegion.FeatureClippingType.Intersect.__doc__ = "Clip the geometry of these features to the region prior to rendering (i.e. feature boundaries will follow the clip region)"
QgsMapClippingRegion.FeatureClippingType.PainterClip.__doc__ = "Applying clipping on the painter only (i.e. feature boundaries will be unchanged, but may be invisible where the feature falls outside the clipping region)"
QgsMapClippingRegion.FeatureClippingType.Intersects.__doc__ = "Only render features which intersect the clipping region, but do not clip these features to the region"
QgsMapClippingRegion.FeatureClippingType.__doc__ = 'Feature clipping behavior.\n\n' + '* ``Intersect``: ' + QgsMapClippingRegion.FeatureClippingType.Intersect.__doc__ + '\n' + '* ``PainterClip``: ' + QgsMapClippingRegion.FeatureClippingType.PainterClip.__doc__ + '\n' + '* ``Intersects``: ' + QgsMapClippingRegion.FeatureClippingType.Intersects.__doc__
# --
92 changes: 92 additions & 0 deletions python/core/auto_generated/qgsmapclippingregion.sip.in
@@ -0,0 +1,92 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsmapclippingregion.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/



class QgsMapClippingRegion
{
%Docstring

A map clipping region (in map coordinates and CRS).

.. versionadded:: 3.16
%End

%TypeHeaderCode
#include "qgsmapclippingregion.h"
%End
public:

enum class FeatureClippingType
{
Intersect,
PainterClip,
Intersects,
};

explicit QgsMapClippingRegion( const QgsGeometry &geometry );
%Docstring
Constructor for a map clipping region, with the specified ``geometry`` in the destination map CRS.
%End

QgsGeometry geometry() const;
%Docstring
Returns the geometry of the clipping region (in the destination map CRS).

.. seealso:: :py:func:`setGeometry`
%End

void setGeometry( const QgsGeometry &geometry );
%Docstring
Sets the clipping region ``geometry`` (in the destination map CRS).

.. seealso:: :py:func:`geometry`
%End

FeatureClippingType featureClip() const;
%Docstring
Returns the feature clipping type.

.. seealso:: :py:func:`setFeatureClip`
%End

void setFeatureClip( FeatureClippingType type );
%Docstring
Sets the feature clipping ``type``.

.. seealso:: :py:func:`featureClip`
%End

void setRestrictedLayers( const QList< QgsMapLayer * > &layers );
%Docstring
Sets a list of ``layers`` to restrict the clipping region effects to.

By default the clipping region applies to all layers.

.. seealso:: :py:func:`restrictedLayers`
%End


QList< QgsMapLayer * > restrictedLayers() const;
%Docstring
Returns the list of layers to restrict the clipping region effects to.

If the list is empty then the clipping will be applied to all layers.

.. seealso:: :py:func:`setRestrictedLayers`
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsmapclippingregion.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Expand Up @@ -101,6 +101,7 @@
%Include auto_generated/qgslocaldefaultsettings.sip
%Include auto_generated/qgslocalizeddatapathregistry.sip
%Include auto_generated/qgslogger.sip
%Include auto_generated/qgsmapclippingregion.sip
%Include auto_generated/qgsmapdecoration.sip
%Include auto_generated/qgsmaphittest.sip
%Include auto_generated/qgsmaplayer.sip
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -311,6 +311,7 @@ SET(QGIS_CORE_SRCS
qgslocalec.cpp
qgslocalizeddatapathregistry.cpp
qgslogger.cpp
qgsmapclippingregion.cpp
qgsmapdecoration.cpp
qgsmaphittest.cpp
qgsmaplayer.cpp
Expand Down Expand Up @@ -859,6 +860,7 @@ SET(QGIS_CORE_HDRS
qgslocalec.h
qgslocalizeddatapathregistry.h
qgslogger.h
qgsmapclippingregion.h
qgsmapdecoration.h
qgsmaphittest.h
qgsmaplayer.h
Expand Down
39 changes: 39 additions & 0 deletions src/core/qgsmapclippingregion.cpp
@@ -0,0 +1,39 @@
/***************************************************************************
qgsmapclippingregion.cpp
--------------------------------------
Date : June 2020
Copyright : (C) 2020 by Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsmapclippingregion.h"
#include "qgsmaplayerlistutils.h"

QgsGeometry QgsMapClippingRegion::geometry() const
{
return mGeometry;
}

void QgsMapClippingRegion::setGeometry( const QgsGeometry &geometry )
{
mGeometry = geometry;
}

void QgsMapClippingRegion::setRestrictedLayers( const QList<QgsMapLayer *> &layers )
{
mRestrictToLayersList = _qgis_listRawToQPointer( layers );
}

QList<QgsMapLayer *> QgsMapClippingRegion::restrictedLayers() const
{
return _qgis_listQPointerToRaw( mRestrictToLayersList );
}


116 changes: 116 additions & 0 deletions src/core/qgsmapclippingregion.h
@@ -0,0 +1,116 @@
/***************************************************************************
qgsmapclippingregion.h
--------------------------------------
Date : June 2020
Copyright : (C) 2020 by Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSMAPCLIPPINGREGION_H
#define QGSMAPCLIPPINGREGION_H

#include "qgis_core.h"
#include "qgsgeometry.h"
#include "qgsmaplayer.h"

/**
* \class QgsMapClippingRegion
* \ingroup core
*
* A map clipping region (in map coordinates and CRS).
*
* \since QGIS 3.16
*/
class CORE_EXPORT QgsMapClippingRegion
{
public:

/**
* Feature clipping behavior.
*/
enum class FeatureClippingType : int
{
Intersect, //!< Clip the geometry of these features to the region prior to rendering (i.e. feature boundaries will follow the clip region)
PainterClip, //!< Applying clipping on the painter only (i.e. feature boundaries will be unchanged, but may be invisible where the feature falls outside the clipping region)
Intersects, //!< Only render features which intersect the clipping region, but do not clip these features to the region
};

/**
* Constructor for a map clipping region, with the specified \a geometry in the destination map CRS.
*/
explicit QgsMapClippingRegion( const QgsGeometry &geometry )
: mGeometry( geometry )
{}

/**
* Returns the geometry of the clipping region (in the destination map CRS).
*
* \see setGeometry().
*/
QgsGeometry geometry() const;

/**
* Sets the clipping region \a geometry (in the destination map CRS).
*
* \see geometry()
*/
void setGeometry( const QgsGeometry &geometry );

/**
* Returns the feature clipping type.
*
* \see setFeatureClip()
*/
FeatureClippingType featureClip() const
{
return mFeatureClip;
}

/**
* Sets the feature clipping \a type.
*
* \see featureClip()
*/
void setFeatureClip( FeatureClippingType type )
{
mFeatureClip = type;
}

/**
* Sets a list of \a layers to restrict the clipping region effects to.
*
* By default the clipping region applies to all layers.
*
* \see restrictedLayers()
*/
void setRestrictedLayers( const QList< QgsMapLayer * > &layers );


/**
* Returns the list of layers to restrict the clipping region effects to.
*
* If the list is empty then the clipping will be applied to all layers.
*
* \see setRestrictedLayers()
*/
QList< QgsMapLayer * > restrictedLayers() const;

private:

//! Geometry of clipping region (in destination map coordinates and CRS)
QgsGeometry mGeometry;

QgsWeakMapLayerPointerList mRestrictToLayersList;

FeatureClippingType mFeatureClip = FeatureClippingType::Intersect;

};

#endif // QGSMAPCLIPPINGREGION_H
1 change: 1 addition & 0 deletions tests/src/python/CMakeLists.txt
Expand Up @@ -148,6 +148,7 @@ ADD_PYTHON_TEST(PyQgsLocalizedDataPathRegistry test_qgslocalizeddatapathregistry
ADD_PYTHON_TEST(PyQgsLocator test_qgslocator.py)
ADD_PYTHON_TEST(PyQgsMapCanvas test_qgsmapcanvas.py)
ADD_PYTHON_TEST(PyQgsMapCanvasAnnotationItem test_qgsmapcanvasannotationitem.py)
ADD_PYTHON_TEST(PyQgsMapClippingRegion test_qgsmapclippingregion.py)
ADD_PYTHON_TEST(PyQgsMapLayer test_qgsmaplayer.py)
ADD_PYTHON_TEST(PyQgsMapLayerAction test_qgsmaplayeraction.py)
ADD_PYTHON_TEST(PyQgsMapLayerComboBox test_qgsmaplayercombobox.py)
Expand Down
38 changes: 38 additions & 0 deletions tests/src/python/test_qgsmapclippingregion.py
@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsMapClippingRegion.
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
__author__ = 'Nyall Dawson'
__date__ = '2020-06'
__copyright__ = 'Copyright 2020, The QGIS Project'


import qgis # NOQA

from qgis.testing import unittest
from qgis.core import (
QgsMapClippingRegion,
QgsGeometry
)


class TestQgsMapClippingRegion(unittest.TestCase):

def testGetSet(self):
region = QgsMapClippingRegion(QgsGeometry.fromWkt('Polygon((0 0, 1 0, 1 1, 0 1, 0 0))'))
self.assertEqual(region.geometry().asWkt(), 'Polygon ((0 0, 1 0, 1 1, 0 1, 0 0))')

region.setGeometry(QgsGeometry.fromWkt('Polygon((10 0, 11 0, 11 1, 10 1, 10 0))'))
self.assertEqual(region.geometry().asWkt(), 'Polygon ((10 0, 11 0, 11 1, 10 1, 10 0))')

self.assertEqual(region.featureClip(), QgsMapClippingRegion.FeatureClippingType.Intersect)
region.setFeatureClip(QgsMapClippingRegion.FeatureClippingType.PainterClip)
self.assertEqual(region.featureClip(), QgsMapClippingRegion.FeatureClippingType.PainterClip)


if __name__ == '__main__':
unittest.main()

0 comments on commit 04f5137

Please sign in to comment.