QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
qgslegendpatchshape.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgslegendpatchshape.cpp
3 -------------------
4begin : April 2020
5copyright : (C) 2020 by Nyall Dawson
6email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include "qgslegendpatchshape.h"
19
20#include "qgsstyle.h"
21
23 : mSymbolType( type )
24 , mGeometry( geometry )
25 , mPreserveAspectRatio( preserveAspectRatio )
26{
27
28}
29
31{
32 return mGeometry.isNull() || mGeometry.isEmpty();
33}
34
36{
37 return mGeometry;
38}
39
41{
42 mGeometry = geometry;
43}
44
46{
47 return mPreserveAspectRatio;
48}
49
54
56{
57 return mScaleToTargetSize;
58}
59
61{
62 mScaleToTargetSize = scale;
63}
64
66{
67 QgsGeometry geom = mGeometry;
68 if ( mScaleToTargetSize )
69 {
70 // scale and translate to desired size
71
72 const QRectF bounds = mGeometry.boundingBox().toRectF();
73
74 double dx = 0;
75 double dy = 0;
76 if ( mPreserveAspectRatio && bounds.height() > 0 && bounds.width() > 0 )
77 {
78 const double scaling = std::min( size.width() / bounds.width(), size.height() / bounds.height() );
79 const QSizeF scaledSize = bounds.size() * scaling;
80 dx = ( size.width() - scaledSize.width() ) / 2.0;
81 dy = ( size.height() - scaledSize.height() ) / 2.0;
82 size = scaledSize;
83 }
84
85 // important -- the transform needs to flip from north-up to painter style "increasing y down" coordinates
86 const QPolygonF targetRectPoly = QPolygonF() << QPointF( dx, dy + size.height() )
87 << QPointF( dx + size.width(), dy + size.height() )
88 << QPointF( dx + size.width(), dy )
89 << QPointF( dx, dy );
90 QTransform t;
91
92 if ( bounds.width() > 0 && bounds.height() > 0 )
93 {
94 QPolygonF patchRectPoly = QPolygonF( bounds );
95 //workaround QT Bug #21329
96 patchRectPoly.pop_back();
97
98 QTransform::quadToQuad( patchRectPoly, targetRectPoly, t );
99 }
100 else if ( bounds.width() > 0 )
101 {
102 t = QTransform::fromScale( size.width() / bounds.width(), 1 ).translate( -bounds.left(), size.height() / 2 - bounds.y() );
103 }
104 else if ( bounds.height() > 0 )
105 {
106 t = QTransform::fromScale( 1, size.height() / bounds.height() ).translate( size.width() / 2 - bounds.x(), -bounds.top() );
107 }
108
109 geom.transform( t );
110 }
111 return geom;
112}
113
114QList<QList<QPolygonF> > QgsLegendPatchShape::toQPolygonF( Qgis::SymbolType type, QSizeF size ) const
115{
116 if ( isNull() || type != mSymbolType )
117 return QgsStyle::defaultStyle()->defaultPatchAsQPolygonF( type, size );
118
119 const QgsGeometry geom = scaledGeometry( size );
121 {
122 QPolygonF points;
123 points << QPointF( size.width() / 2, size.height() / 2 );
124 return QList< QList<QPolygonF> >() << ( QList< QPolygonF >() << points );
125 }
126
127 return QgsSymbolLayerUtils::toQPolygonF( geom, type );
128}
129
130void QgsLegendPatchShape::readXml( const QDomElement &element, const QgsReadWriteContext & )
131{
132 mGeometry = QgsGeometry::fromWkt( element.attribute( QStringLiteral( "wkt" ) ) );
133 mPreserveAspectRatio = element.attribute( QStringLiteral( "preserveAspect" ) ).toInt();
134 mSymbolType = static_cast< Qgis::SymbolType >( element.attribute( QStringLiteral( "type" ) ).toInt() );
135}
136
137void QgsLegendPatchShape::writeXml( QDomElement &element, QDomDocument &, const QgsReadWriteContext & ) const
138{
139 element.setAttribute( QStringLiteral( "wkt" ), mGeometry.isNull() ? QString() : mGeometry.asWkt( ) );
140 element.setAttribute( QStringLiteral( "preserveAspect" ), mPreserveAspectRatio ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
141 element.setAttribute( QStringLiteral( "type" ), QString::number( static_cast< int >( mSymbolType ) ) );
142}
143
145{
146 return mSymbolType;
147}
148
150{
151 mSymbolType = type;
152}
SymbolType
Symbol types.
Definition qgis.h:610
@ Marker
Marker symbol.
Definition qgis.h:611
@ MultiPoint
MultiPoint.
Definition qgis.h:283
A geometry is the spatial representation of a feature.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
static Q_INVOKABLE QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
Qgis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.).
bool scaleToOutputSize() const
Returns true if the patch shape should by resized to the desired target size when rendering.
void setSymbolType(Qgis::SymbolType type)
Sets the symbol type associated with this patch.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Read settings from a DOM element.
QList< QList< QPolygonF > > toQPolygonF(Qgis::SymbolType type, QSizeF size) const
Converts the patch shape to a set of QPolygonF objects representing how the patch should be drawn for...
QgsGeometry scaledGeometry(QSizeF size) const
Returns the patch shape's geometry, scaled to the given size.
void setGeometry(const QgsGeometry &geometry)
Sets the geometry for the patch shape.
bool preserveAspectRatio() const
Returns true if the patch shape should preserve its aspect ratio when it is resized to fit a desired ...
bool isNull() const
Returns true if the patch shape is a null QgsLegendPatchShape, which indicates that the default legen...
QgsLegendPatchShape()=default
Constructor for a null QgsLegendPatchShape.
void setPreserveAspectRatio(bool preserve)
Sets whether the patch shape should preserve its aspect ratio when it is resized to fit a desired leg...
void writeXml(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
QgsGeometry geometry() const
Returns the geometry for the patch shape.
void setScaleToOutputSize(bool scale)
Sets whether the patch shape should by resized to the desired target size when rendering.
Qgis::SymbolType symbolType() const
Returns the symbol type associated with this patch.
A container for the context for various read/write operations on objects.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
Definition qgsstyle.cpp:147
QList< QList< QPolygonF > > defaultPatchAsQPolygonF(Qgis::SymbolType type, QSizeF size) const
Returns the default patch geometry for the given symbol type and size as a set of QPolygonF objects (...
static QList< QList< QPolygonF > > toQPolygonF(const QgsGeometry &geometry, Qgis::SymbolType type)
Converts a geometry to a set of QPolygonF objects representing how the geometry should be drawn for a...
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.