Skip to content

Commit

Permalink
New class QgsLegendPatchShape
Browse files Browse the repository at this point in the history
Represents a patch shape for use in map legends.
  • Loading branch information
nyalldawson committed Apr 10, 2020
1 parent bd86add commit 1b5f4dd
Show file tree
Hide file tree
Showing 7 changed files with 331 additions and 0 deletions.
108 changes: 108 additions & 0 deletions python/core/auto_generated/layertree/qgslegendpatchshape.sip.in
@@ -0,0 +1,108 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/layertree/qgslegendpatchshape.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/



class QgsLegendPatchShape
{
%Docstring
Represents a patch shape for use in map legends.

.. versionadded:: 3.14
%End

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

QgsLegendPatchShape( QgsSymbol::SymbolType type,
const QgsGeometry &geometry,
bool preserveAspectRatio = true );
%Docstring
Constructor for QgsLegendPatchShape.

The ``type`` argument specifies the symbol type associated with this patch.

The ``geometry`` argument gives the shape of the patch to render. See setGeometry()
for further details on the geometry requirements.

If ``preserveAspectRatio`` is ``True``, then the patch shape should preserve its aspect ratio when
it is resized to fit a desired legend patch size.
%End

QgsSymbol::SymbolType symbolType() const;
%Docstring
Returns the symbol type associated with this patch.

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

void setSymbolType( QgsSymbol::SymbolType type );
%Docstring
Sets the symbol ``type`` associated with this patch.

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

QgsGeometry geometry() const;
%Docstring
Returns the geometry for the patch shape.

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

void setGeometry( const QgsGeometry &geometry );
%Docstring
Sets the ``geometry`` for the patch shape.

The origin and size of the ``geometry`` is not important, as the legend
renderer will automatically scale and transform the geometry to match
the desired overall patch bounds.

Geometries for legend patches are rendered respecting the traditional
"y values increase toward the top of the map" convention, as opposed
to the standard computer graphics convention of "y values increase toward
the bottom of the display".

.. warning::

The geometry type should match the patch shape's symbolType(),
e.g. a fill symbol type should only have Polygon or MultiPolygon geometries
set, while a line symbol type must have LineString or MultiLineString geometries.

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

bool preserveAspectRatio() const;
%Docstring
Returns ``True`` if the patch shape should preserve its aspect ratio when
it is resized to fit a desired legend patch size.

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

void setPreserveAspectRatio( bool preserve );
%Docstring
Sets whether the patch shape should ``preserve`` its aspect ratio when
it is resized to fit a desired legend patch size.

The default behavior is to respect the geometry()'s aspect ratio.

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

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/layertree/qgslegendpatchshape.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 @@ -345,6 +345,7 @@
%Include auto_generated/layertree/qgslayertreenode.sip
%Include auto_generated/layertree/qgslayertreeregistrybridge.sip
%Include auto_generated/layertree/qgslayertreeutils.sip
%Include auto_generated/layertree/qgslegendpatchshape.sip
%Include auto_generated/layout/qgsabstractlayoutiterator.sip
%Include auto_generated/layout/qgsabstractreportsection.sip
%Include auto_generated/layout/qgslayout.sip
Expand Down
3 changes: 3 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -97,6 +97,7 @@ SET(QGIS_CORE_SRCS
layertree/qgslayertreeregistrybridge.cpp
layertree/qgslayertreeutils.cpp
layertree/qgslayertree.cpp
layertree/qgslegendpatchshape.cpp

metadata/qgsabstractmetadatabase.cpp
metadata/qgslayermetadata.cpp
Expand Down Expand Up @@ -1120,6 +1121,8 @@ SET(QGIS_CORE_HDRS
layertree/qgslayertreenode.h
layertree/qgslayertreeregistrybridge.h
layertree/qgslayertreeutils.h
layertree/qgslegendpatchshape.h

layout/qgsabstractlayoutiterator.h
layout/qgsabstractreportsection.h
layout/qgscompositionconverter.h
Expand Down
57 changes: 57 additions & 0 deletions src/core/layertree/qgslegendpatchshape.cpp
@@ -0,0 +1,57 @@
/***************************************************************************
qgslegendpatchshape.cpp
-------------------
begin : April 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 "qgslegendpatchshape.h"


QgsLegendPatchShape::QgsLegendPatchShape( QgsSymbol::SymbolType type, const QgsGeometry &geometry, bool preserveAspectRatio )
: mSymbolType( type )
, mGeometry( geometry )
, mPreserveAspectRatio( preserveAspectRatio )
{

}

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

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

bool QgsLegendPatchShape::preserveAspectRatio() const
{
return mPreserveAspectRatio;
}

void QgsLegendPatchShape::setPreserveAspectRatio( bool preserveAspectRatio )
{
mPreserveAspectRatio = preserveAspectRatio;
}

QgsSymbol::SymbolType QgsLegendPatchShape::symbolType() const
{
return mSymbolType;
}

void QgsLegendPatchShape::setSymbolType( QgsSymbol::SymbolType type )
{
mSymbolType = type;
}
115 changes: 115 additions & 0 deletions src/core/layertree/qgslegendpatchshape.h
@@ -0,0 +1,115 @@
/***************************************************************************
qgslegendpatchshape.h
-------------------
begin : April 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 QGSLEGENDPATCHSHAPE_H
#define QGSLEGENDPATCHSHAPE_H

#include "qgis_core.h"
#include "qgis_sip.h"
#include "qgssymbol.h"

/**
* \ingroup core
* Represents a patch shape for use in map legends.
*
* \since QGIS 3.14
*/
class CORE_EXPORT QgsLegendPatchShape
{
public:

/**
* Constructor for QgsLegendPatchShape.
*
* The \a type argument specifies the symbol type associated with this patch.
*
* The \a geometry argument gives the shape of the patch to render. See setGeometry()
* for further details on the geometry requirements.
*
* If \a preserveAspectRatio is TRUE, then the patch shape should preserve its aspect ratio when
* it is resized to fit a desired legend patch size.
*/
QgsLegendPatchShape( QgsSymbol::SymbolType type,
const QgsGeometry &geometry,
bool preserveAspectRatio = true );

/**
* Returns the symbol type associated with this patch.
*
* \see setSymbolType()
*/
QgsSymbol::SymbolType symbolType() const;

/**
* Sets the symbol \a type associated with this patch.
*
* \see symbolType()
*/
void setSymbolType( QgsSymbol::SymbolType type );

/**
* Returns the geometry for the patch shape.
*
* \see setGeometry()
*/
QgsGeometry geometry() const;

/**
* Sets the \a geometry for the patch shape.
*
* The origin and size of the \a geometry is not important, as the legend
* renderer will automatically scale and transform the geometry to match
* the desired overall patch bounds.
*
* Geometries for legend patches are rendered respecting the traditional
* "y values increase toward the top of the map" convention, as opposed
* to the standard computer graphics convention of "y values increase toward
* the bottom of the display".
*
* \warning The geometry type should match the patch shape's symbolType(),
* e.g. a fill symbol type should only have Polygon or MultiPolygon geometries
* set, while a line symbol type must have LineString or MultiLineString geometries.
*
* \see geometry()
*/
void setGeometry( const QgsGeometry &geometry );

/**
* Returns TRUE if the patch shape should preserve its aspect ratio when
* it is resized to fit a desired legend patch size.
*
* \see setPreserveAspectRatio()
*/
bool preserveAspectRatio() const;

/**
* Sets whether the patch shape should \a preserve its aspect ratio when
* it is resized to fit a desired legend patch size.
*
* The default behavior is to respect the geometry()'s aspect ratio.
*
* \see setPreserveAspectRatio()
*/
void setPreserveAspectRatio( bool preserve );

private:
QgsSymbol::SymbolType mSymbolType = QgsSymbol::Fill;
QgsGeometry mGeometry;
bool mPreserveAspectRatio = true;

};

#endif // QGSLEGENDPATCHSHAPE_H
1 change: 1 addition & 0 deletions tests/src/python/CMakeLists.txt
Expand Up @@ -135,6 +135,7 @@ ADD_PYTHON_TEST(PyQgsLayoutScaleBar test_qgslayoutscalebar.py)
ADD_PYTHON_TEST(PyQgsLayoutShape test_qgslayoutshape.py)
ADD_PYTHON_TEST(PyQgsLayoutSnapper test_qgslayoutsnapper.py)
ADD_PYTHON_TEST(PyQgsLayoutUnitsComboBox test_qgslayoutunitscombobox.py)
ADD_PYTHON_TEST(PyQgsLegendPatchShape test_qgslegendpatchshape.py)
ADD_PYTHON_TEST(PyQgsLineSegment test_qgslinesegment.py)
ADD_PYTHON_TEST(PyQgsLineSymbolLayers test_qgslinesymbollayers.py)
ADD_PYTHON_TEST(PyQgsLocalDefaultSettings test_qgslocaldefaultsettings.py)
Expand Down
46 changes: 46 additions & 0 deletions tests/src/python/test_qgslegendpatchshape.py
@@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsLegendPatchShape.
.. 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__ = '(C) 2020 by Nyall Dawson'
__date__ = '05/04/2020'
__copyright__ = 'Copyright 2020, The QGIS Project'

import qgis # NOQA

from qgis.core import (QgsLegendPatchShape,
QgsGeometry,
QgsSymbol
)
from qgis.testing import start_app, unittest
from utilities import unitTestDataPath


start_app()
TEST_DATA_DIR = unitTestDataPath()


class TestQgsLegendPatchShape(unittest.TestCase):

def testBasic(self):
shape = QgsLegendPatchShape(QgsSymbol.Line, QgsGeometry.fromWkt('LineString( 0 0, 1 1)'), False)
self.assertEqual(shape.symbolType(), QgsSymbol.Line)
self.assertEqual(shape.geometry().asWkt(), 'LineString (0 0, 1 1)')
self.assertFalse(shape.preserveAspectRatio())

shape.setSymbolType(QgsSymbol.Marker)
self.assertEqual(shape.symbolType(), QgsSymbol.Marker)

shape.setGeometry(QgsGeometry.fromWkt('Multipoint( 1 1, 2 2)'))
self.assertEqual(shape.geometry().asWkt(), 'MultiPoint ((1 1),(2 2))')

shape.setPreserveAspectRatio(True)
self.assertTrue(shape.preserveAspectRatio())


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

0 comments on commit 1b5f4dd

Please sign in to comment.