QGIS API Documentation  3.23.0-Master (dd0cd13a00)
qgsdatadefinedsizelegend.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsdatadefinedsizelegend.cpp
3  --------------------------------------
4  Date : June 2017
5  Copyright : (C) 2017 by Martin Dobias
6  Email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 
18 #include "qgsproperty.h"
19 #include "qgspropertytransformer.h"
20 #include "qgssymbollayerutils.h"
21 #include "qgsxmlutils.h"
22 #include "qgslinesymbollayer.h"
23 #include "qgstextformat.h"
24 #include "qgstextrenderer.h"
25 #include "qgsmarkersymbol.h"
26 #include "qgslinesymbol.h"
27 
29 {
30  std::unique_ptr< QgsSimpleLineSymbolLayer > lineSymbolLayer = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 0, 0, 0 ), 0.2 );
31  mLineSymbol = std::make_unique< QgsLineSymbol >( QgsSymbolLayerList() << lineSymbolLayer.release() );
32 }
33 
35 
37  : mType( other.mType )
38  , mTitleLabel( other.mTitleLabel )
39  , mSizeClasses( other.mSizeClasses )
40  , mSymbol( other.mSymbol.get() ? other.mSymbol->clone() : nullptr )
41  , mLineSymbol( other.mLineSymbol.get() ? other.mLineSymbol->clone() : nullptr )
42  , mSizeScaleTransformer( other.mSizeScaleTransformer.get() ? new QgsSizeScaleTransformer( *other.mSizeScaleTransformer ) : nullptr )
43  , mVAlign( other.mVAlign )
44  , mFont( other.mFont )
45  , mTextColor( other.mTextColor )
46  , mTextAlignment( other.mTextAlignment )
47 {
48 }
49 
51 {
52  if ( this != &other )
53  {
54  mType = other.mType;
55  mTitleLabel = other.mTitleLabel;
56  mSizeClasses = other.mSizeClasses;
57  mSymbol.reset( other.mSymbol.get() ? other.mSymbol->clone() : nullptr );
58  mLineSymbol.reset( other.mLineSymbol.get() ? other.mLineSymbol->clone() : nullptr );
59  mSizeScaleTransformer.reset( other.mSizeScaleTransformer.get() ? new QgsSizeScaleTransformer( *other.mSizeScaleTransformer ) : nullptr );
60  mVAlign = other.mVAlign;
61  mFont = other.mFont;
62  mTextColor = other.mTextColor;
63  mTextAlignment = other.mTextAlignment;
64  }
65  return *this;
66 }
67 
69 {
70  mSymbol.reset( symbol );
71 }
72 
74 {
75  return mSymbol.get();
76 }
77 
79 {
80  mLineSymbol.reset( symbol );
81 }
82 
84 {
85  return mLineSymbol.get();
86 }
87 
89 {
90  mSizeScaleTransformer.reset( transformer );
91 }
92 
94 {
95  return mSizeScaleTransformer.get();
96 }
97 
98 
100 {
101  mSymbol.reset( symbol->clone() );
102  mSymbol->setDataDefinedSize( QgsProperty() ); // original symbol may have had data-defined size associated
103 
104  const QgsSizeScaleTransformer *sizeTransformer = dynamic_cast< const QgsSizeScaleTransformer * >( ddSize.transformer() );
105  mSizeScaleTransformer.reset( sizeTransformer ? sizeTransformer->clone() : nullptr );
106 
107  if ( mTitleLabel.isEmpty() )
108  mTitleLabel = ddSize.propertyType() == QgsProperty::ExpressionBasedProperty ? ddSize.expressionString() : ddSize.field();
109 
110  // automatically generate classes if no classes are defined
111  if ( sizeTransformer && mSizeClasses.isEmpty() )
112  {
113  mSizeClasses.clear();
114  const auto prettyBreaks { QgsSymbolLayerUtils::prettyBreaks( sizeTransformer->minValue(), sizeTransformer->maxValue(), 4 ) };
115  for ( double v : prettyBreaks )
116  {
117  mSizeClasses << SizeClass( v, QString::number( v ) );
118  }
119  }
120 }
121 
123 {
125  if ( !mTitleLabel.isEmpty() )
126  {
127  QgsLegendSymbolItem title( nullptr, mTitleLabel, QString() );
128  lst << title;
129  }
130 
131  switch ( mType )
132  {
133  case LegendCollapsed:
134  {
137  lst << i;
138  break;
139  }
140 
141  case LegendSeparated:
142  {
143  lst.reserve( mSizeClasses.size() );
144  for ( const SizeClass &cl : mSizeClasses )
145  {
146  QgsLegendSymbolItem si( mSymbol.get(), cl.label, QString() );
147  QgsMarkerSymbol *s = static_cast<QgsMarkerSymbol *>( si.symbol() );
148  double size = cl.size;
149  if ( mSizeScaleTransformer )
150  {
151  size = mSizeScaleTransformer->size( size );
152  }
153 
154  s->setSize( size );
155  lst << si;
156  }
157  break;
158  }
159  }
160  return lst;
161 }
162 
163 
164 void QgsDataDefinedSizeLegend::drawCollapsedLegend( QgsRenderContext &context, QSizeF *outputSize, double *labelXOffset ) const
165 {
166  // this assumes the context's painter has been scaled to pixels in advance!
167 
168  if ( mType != LegendCollapsed || mSizeClasses.isEmpty() || !mSymbol )
169  {
170  if ( outputSize )
171  *outputSize = QSizeF();
172  if ( labelXOffset )
173  *labelXOffset = 0;
174  return;
175  }
176 
177  // parameters that could be configurable
178  double hLengthLineMM = 2; // extra horizontal space to be occupied by callout line
179  double hSpaceLineTextMM = 1; // horizontal space between end of the line and start of the text
180 
181  std::unique_ptr<QgsMarkerSymbol> s( mSymbol->clone() );
182 
183  QList<SizeClass> classes = mSizeClasses;
184 
185  // optionally scale size values if transformer is defined
186  if ( mSizeScaleTransformer )
187  {
188  for ( SizeClass &cls : classes )
189  cls.size = mSizeScaleTransformer->size( cls.size );
190  }
191 
192  // make sure we draw bigger symbols first
193  std::sort( classes.begin(), classes.end(), []( const SizeClass & a, const SizeClass & b ) { return a.size > b.size; } );
194 
195  double hLengthLine = context.convertToPainterUnits( hLengthLineMM, QgsUnitTypes::RenderMillimeters );
196  double hSpaceLineText = context.convertToPainterUnits( hSpaceLineTextMM, QgsUnitTypes::RenderMillimeters );
197  int dpm = std::round( context.scaleFactor() * 1000 ); // scale factor = dots per millimeter
198 
199  // get font metrics - we need a temporary image just to get the metrics right for the given DPI
200  QImage tmpImg( QSize( 1, 1 ), QImage::Format_ARGB32_Premultiplied );
201  tmpImg.setDotsPerMeterX( dpm );
202  tmpImg.setDotsPerMeterY( dpm );
203  QFontMetricsF fm( mFont, &tmpImg );
204  double textHeight = fm.height();
205  double leading = fm.leading();
206  double minTextDistY = textHeight + leading;
207 
208  //
209  // determine layout of the rendered elements
210  //
211 
212  // find out how wide the text will be
213  double maxTextWidth = 0;
214  for ( const SizeClass &c : std::as_const( classes ) )
215  {
216  maxTextWidth = std::max( maxTextWidth, fm.boundingRect( c.label ).width() );
217  }
218  // add extra width needed to handle varying rendering of font weight
219  maxTextWidth += 1;
220 
221  // find out size of the largest symbol
222  double largestSize = classes.at( 0 ).size;
223  double outputLargestSize = context.convertToPainterUnits( largestSize, s->sizeUnit(), s->sizeMapUnitScale() );
224 
225  // find out top Y coordinate for individual symbol sizes
226  QList<double> symbolTopY;
227  for ( const SizeClass &c : std::as_const( classes ) )
228  {
229  double outputSymbolSize = context.convertToPainterUnits( c.size, s->sizeUnit(), s->sizeMapUnitScale() );
230  switch ( mVAlign )
231  {
232  case AlignCenter:
233  symbolTopY << outputLargestSize / 2 - outputSymbolSize / 2;
234  break;
235  case AlignBottom:
236  symbolTopY << outputLargestSize - outputSymbolSize;
237  break;
238  }
239  }
240 
241  // determine Y coordinate of texts: ideally they should be at the same level as symbolTopY
242  // but we need to avoid overlapping texts, so adjust the vertical positions
243  double middleIndex = 0; // classes.count() / 2; // will get the ideal position
244  QList<double> textCenterY;
245  double lastY = middleIndex < symbolTopY.size() ? symbolTopY[middleIndex] : 0;
246  textCenterY << lastY;
247  for ( int i = middleIndex + 1; i < classes.count(); ++i )
248  {
249  double symbolY = symbolTopY[i];
250  if ( symbolY - lastY < minTextDistY )
251  symbolY = lastY + minTextDistY;
252  textCenterY << symbolY;
253  lastY = symbolY;
254  }
255 
256  double textTopY = textCenterY.first() - textHeight / 2;
257  double textBottomY = textCenterY.last() + textHeight / 2;
258  double totalTextHeight = textBottomY - textTopY;
259 
260  double fullWidth = outputLargestSize + hLengthLine + hSpaceLineText + maxTextWidth;
261  double fullHeight = std::max( outputLargestSize - textTopY, totalTextHeight );
262 
263  if ( outputSize )
264  *outputSize = QSizeF( fullWidth, fullHeight );
265  if ( labelXOffset )
266  *labelXOffset = outputLargestSize + hLengthLine + hSpaceLineText;
267 
268  if ( !context.painter() )
269  return; // only layout
270 
271  //
272  // drawing
273  //
274 
275  QPainter *p = context.painter();
276  QgsScopedQPainterState painterState( p );
277  p->translate( 0, -textTopY );
278 
279  // draw symbols first so that they do not cover
280  for ( const SizeClass &c : std::as_const( classes ) )
281  {
282  s->setSize( c.size );
283 
284  double outputSymbolSize = context.convertToPainterUnits( c.size, s->sizeUnit(), s->sizeMapUnitScale() );
285  double tx = ( outputLargestSize - outputSymbolSize ) / 2;
286 
287  QgsScopedQPainterState symbolPainterState( p );
288  switch ( mVAlign )
289  {
290  case AlignCenter:
291  p->translate( tx, ( outputLargestSize - outputSymbolSize ) / 2 );
292  break;
293  case AlignBottom:
294  p->translate( tx, outputLargestSize - outputSymbolSize );
295  break;
296  }
297  s->drawPreviewIcon( nullptr, QSize( outputSymbolSize, outputSymbolSize ), &context );
298  }
299 
300  QgsTextFormat format = QgsTextFormat::fromQFont( mFont );
301  format.setColor( mTextColor );
302 
303  if ( mLineSymbol )
304  {
305  mLineSymbol->startRender( context );
306  }
307 
308  int i = 0;
309  for ( const SizeClass &c : std::as_const( classes ) )
310  {
311  // line from symbol to the text
312  if ( mLineSymbol )
313  {
314  mLineSymbol->renderPolyline( QPolygonF() << QPointF( outputLargestSize / 2, symbolTopY[i] )
315  << QPointF( outputLargestSize + hLengthLine, textCenterY[i] ), nullptr, context );
316  }
317 
318  // draw label
319  QRect rect( outputLargestSize + hLengthLine + hSpaceLineText, textCenterY[i] - textHeight / 2,
320  maxTextWidth, textHeight );
321 
323  QStringList() << c.label, context, format );
324  i++;
325  }
326 
327  if ( mLineSymbol )
328  mLineSymbol->stopRender( context );
329 }
330 
331 
332 QImage QgsDataDefinedSizeLegend::collapsedLegendImage( QgsRenderContext &context, const QColor &backgroundColor, double paddingMM ) const
333 {
334  if ( mType != LegendCollapsed || mSizeClasses.isEmpty() || !mSymbol )
335  return QImage();
336 
337  // find out the size first
338  QSizeF contentSize;
339  drawCollapsedLegend( context, &contentSize );
340 
341  double padding = context.convertToPainterUnits( paddingMM, QgsUnitTypes::RenderMillimeters );
342  int dpm = std::round( context.scaleFactor() * 1000 ); // scale factor = dots per millimeter
343 
344  QImage img( contentSize.width() + padding * 2, contentSize.height() + padding * 2, QImage::Format_ARGB32_Premultiplied );
345  img.setDotsPerMeterX( dpm );
346  img.setDotsPerMeterY( dpm );
347  img.fill( backgroundColor );
348 
349  QPainter painter( &img );
350  painter.setRenderHint( QPainter::Antialiasing, true );
351 
352  painter.translate( padding, padding ); // so we do not need to care about padding at all
353 
354  // now do the rendering
355  QPainter *oldPainter = context.painter();
356  context.setPainter( &painter );
357  drawCollapsedLegend( context );
358  context.setPainter( oldPainter );
359 
360  painter.end();
361  return img;
362 }
363 
365 {
366  if ( elem.isNull() )
367  return nullptr;
369  ddsLegend->setLegendType( elem.attribute( QStringLiteral( "type" ) ) == QLatin1String( "collapsed" ) ? LegendCollapsed : LegendSeparated );
370  ddsLegend->setVerticalAlignment( elem.attribute( QStringLiteral( "valign" ) ) == QLatin1String( "center" ) ? AlignCenter : AlignBottom );
371  ddsLegend->setTitle( elem.attribute( QStringLiteral( "title" ) ) );
372 
373  QDomElement elemSymbol = elem.firstChildElement( QStringLiteral( "symbol" ) );
374  if ( !elemSymbol.isNull() )
375  {
376  ddsLegend->setSymbol( QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( elemSymbol, context ) );
377  }
378 
379  const QDomElement lineSymbolElem = elem.firstChildElement( QStringLiteral( "lineSymbol" ) );
380  if ( !lineSymbolElem.isNull() )
381  {
382  ddsLegend->setLineSymbol( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( lineSymbolElem.firstChildElement(), context ) );
383  }
384 
385  QgsSizeScaleTransformer *transformer = nullptr;
386  QDomElement elemTransformer = elem.firstChildElement( QStringLiteral( "transformer" ) );
387  if ( !elemTransformer.isNull() )
388  {
389  transformer = new QgsSizeScaleTransformer;
390  transformer->loadVariant( QgsXmlUtils::readVariant( elemTransformer ) );
391  }
392  ddsLegend->setSizeScaleTransformer( transformer );
393 
394  QDomElement elemTextStyle = elem.firstChildElement( QStringLiteral( "text-style" ) );
395  if ( !elemTextStyle.isNull() )
396  {
397  QDomElement elemFont = elemTextStyle.firstChildElement( QStringLiteral( "font" ) );
398  if ( !elemFont.isNull() )
399  {
400  ddsLegend->setFont( QFont( elemFont.attribute( QStringLiteral( "family" ) ), elemFont.attribute( QStringLiteral( "size" ) ).toInt(),
401  elemFont.attribute( QStringLiteral( "weight" ) ).toInt(), elemFont.attribute( QStringLiteral( "italic" ) ).toInt() ) );
402  }
403  ddsLegend->setTextColor( QgsSymbolLayerUtils::decodeColor( elemTextStyle.attribute( QStringLiteral( "color" ) ) ) );
404  ddsLegend->setTextAlignment( static_cast<Qt::AlignmentFlag>( elemTextStyle.attribute( QStringLiteral( "align" ) ).toInt() ) );
405  }
406 
407  QDomElement elemClasses = elem.firstChildElement( QStringLiteral( "classes" ) );
408  if ( !elemClasses.isNull() )
409  {
410  QList<SizeClass> classes;
411  QDomElement elemClass = elemClasses.firstChildElement( QStringLiteral( "class" ) );
412  while ( !elemClass.isNull() )
413  {
414  classes << SizeClass( elemClass.attribute( QStringLiteral( "size" ) ).toDouble(), elemClass.attribute( QStringLiteral( "label" ) ) );
415  elemClass = elemClass.nextSiblingElement();
416  }
417  ddsLegend->setClasses( classes );
418  }
419 
420  return ddsLegend;
421 }
422 
423 void QgsDataDefinedSizeLegend::writeXml( QDomElement &elem, const QgsReadWriteContext &context ) const
424 {
425  QDomDocument doc = elem.ownerDocument();
426 
427  elem.setAttribute( QStringLiteral( "type" ), mType == LegendCollapsed ? "collapsed" : "separated" );
428  elem.setAttribute( QStringLiteral( "valign" ), mVAlign == AlignCenter ? "center" : "bottom" );
429  elem.setAttribute( QStringLiteral( "title" ), mTitleLabel );
430 
431  if ( mSymbol )
432  {
433  QDomElement elemSymbol = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "source" ), mSymbol.get(), doc, context );
434  elem.appendChild( elemSymbol );
435  }
436 
437  if ( mLineSymbol )
438  {
439  QDomElement lineSymbolElem = doc.createElement( QStringLiteral( "lineSymbol" ) );
440  lineSymbolElem.appendChild( QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "lineSymbol" ), mLineSymbol.get(), doc, context ) );
441  elem.appendChild( lineSymbolElem );
442  }
443 
444  if ( mSizeScaleTransformer )
445  {
446  QDomElement elemTransformer = QgsXmlUtils::writeVariant( mSizeScaleTransformer->toVariant(), doc );
447  elemTransformer.setTagName( QStringLiteral( "transformer" ) );
448  elem.appendChild( elemTransformer );
449  }
450 
451  QDomElement elemFont = doc.createElement( QStringLiteral( "font" ) );
452  elemFont.setAttribute( QStringLiteral( "family" ), mFont.family() );
453  elemFont.setAttribute( QStringLiteral( "size" ), mFont.pointSize() );
454  elemFont.setAttribute( QStringLiteral( "weight" ), mFont.weight() );
455  elemFont.setAttribute( QStringLiteral( "italic" ), mFont.italic() );
456 
457  QDomElement elemTextStyle = doc.createElement( QStringLiteral( "text-style" ) );
458  elemTextStyle.setAttribute( QStringLiteral( "color" ), QgsSymbolLayerUtils::encodeColor( mTextColor ) );
459  elemTextStyle.setAttribute( QStringLiteral( "align" ), static_cast<int>( mTextAlignment ) );
460  elemTextStyle.appendChild( elemFont );
461  elem.appendChild( elemTextStyle );
462 
463  if ( !mSizeClasses.isEmpty() )
464  {
465  QDomElement elemClasses = doc.createElement( QStringLiteral( "classes" ) );
466  for ( const SizeClass &sc : std::as_const( mSizeClasses ) )
467  {
468  QDomElement elemClass = doc.createElement( QStringLiteral( "class" ) );
469  elemClass.setAttribute( QStringLiteral( "size" ), sc.size );
470  elemClass.setAttribute( QStringLiteral( "label" ), sc.label );
471  elemClasses.appendChild( elemClass );
472  }
473  elem.appendChild( elemClasses );
474  }
475 }
Object that keeps configuration of appearance of marker symbol's data-defined size in legend.
void setTitle(const QString &title)
Sets title label for data-defined size legend.
QList< QgsDataDefinedSizeLegend::SizeClass > classes() const
Returns list of classes: each class is a pair of symbol size (in units used by the symbol) and label.
void setSymbol(QgsMarkerSymbol *symbol SIP_TRANSFER)
Sets marker symbol that will be used to draw markers in legend.
void setVerticalAlignment(VerticalAlignment vAlign)
Sets vertical alignment of symbols - only valid for collapsed legend.
void setLineSymbol(QgsLineSymbol *symbol SIP_TRANSFER)
Sets the line symbol that will be used to draw callout lines in legend.
QgsMarkerSymbol * symbol() const
Returns marker symbol that will be used to draw markers in legend.
@ AlignCenter
Symbols are aligned to the center.
@ AlignBottom
Symbols are aligned to the bottom.
void setTextAlignment(Qt::AlignmentFlag flag)
Sets horizontal text alignment for rendering of labels - only valid for collapsed legend.
QgsDataDefinedSizeLegend & operator=(const QgsDataDefinedSizeLegend &other)
void setClasses(const QList< QgsDataDefinedSizeLegend::SizeClass > &classes)
Sets list of classes: each class is a pair of symbol size (in units used by the symbol) and label.
void setLegendType(LegendType type)
Sets how the legend should be rendered.
void setFont(const QFont &font)
Sets font used for rendering of labels - only valid for collapsed legend.
void setTextColor(const QColor &color)
Sets text color for rendering of labels - only valid for collapsed legend.
QString title() const
Returns title label for data-defined size legend.
void setSizeScaleTransformer(QgsSizeScaleTransformer *transformer SIP_TRANSFER)
Sets transformer for scaling of symbol sizes. Takes ownership of the object. Accepts nullptr to set n...
QgsDataDefinedSizeLegend()
Constructor for QgsDataDefinedSizeLegend.
static QgsDataDefinedSizeLegend * readXml(const QDomElement &elem, const QgsReadWriteContext &context) SIP_FACTORY
Creates instance from given element and returns it (caller takes ownership). Returns nullptr on error...
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const
Writes configuration to the given XML element.
@ LegendSeparated
Each class (size value) has a separate legend node.
@ LegendCollapsed
All classes are rendered within one legend node.
QgsLineSymbol * lineSymbol() const
Returns the line symbol that will be used to draw callout lines in legend.
void updateFromSymbolAndProperty(const QgsMarkerSymbol *symbol, const QgsProperty &ddSize)
Updates the list of classes, source symbol and title label from given symbol and property.
QgsSizeScaleTransformer * sizeScaleTransformer() const
Returns transformer for scaling of symbol sizes. Returns nullptr if no transformer is defined.
QImage collapsedLegendImage(QgsRenderContext &context, const QColor &backgroundColor=Qt::transparent, double paddingMM=1) const
Returns output image that would be shown in the legend. Returns invalid image if legend is not config...
QgsLegendSymbolList legendSymbolList() const
Generates legend symbol items according to the configuration.
void drawCollapsedLegend(QgsRenderContext &context, QSizeF *outputSize SIP_OUT=nullptr, double *labelXOffset SIP_OUT=nullptr) const
Draw the legend if using LegendOneNodeForAll and optionally output size of the legend and x offset of...
The class stores information about one class/rule of a vector layer renderer in a unified way that ca...
void setDataDefinedSizeLegendSettings(QgsDataDefinedSizeLegend *settings)
Sets extra information about data-defined size.
QgsSymbol * symbol() const
Returns associated symbol. May be nullptr.
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgslinesymbol.h:30
A marker symbol type, for rendering Point and MultiPoint geometries.
void setSize(double size)
Sets the size for the whole symbol.
double size() const
Returns the estimated size for the whole symbol, which is the maximum size of all marker symbol layer...
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
double maxValue() const
Returns the maximum value expected by the transformer.
double minValue() const
Returns the minimum value expected by the transformer.
A store for object properties.
Definition: qgsproperty.h:231
@ ExpressionBasedProperty
Expression based property (QgsExpressionBasedProperty)
Definition: qgsproperty.h:240
QString expressionString() const
Returns the expression used for the property value.
QString field() const
Returns the current field name the property references.
const QgsPropertyTransformer * transformer() const
Returns the existing transformer used for manipulating the calculated values for the property,...
Type propertyType() const
Returns the property type.
The class is used as a container of context for various read/write operations on other objects.
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
QPainter * painter()
Returns the destination QPainter for the render operation.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
Scoped object for saving and restoring a QPainter object's state.
QgsPropertyTransformer subclass for scaling a value into a size according to various scaling methods.
bool loadVariant(const QVariant &definition) override
Loads this transformer from a QVariantMap, wrapped in a QVariant.
QgsSizeScaleTransformer * clone() const override
Returns a clone of the transformer.
static QColor decodeColor(const QString &str)
static QList< double > prettyBreaks(double minimum, double maximum, int classes)
Computes a sequence of about 'classes' equally spaced round values which cover the range of values fr...
static QString encodeColor(const QColor &color)
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
Container for all settings relating to text rendering.
Definition: qgstextformat.h:41
void setColor(const QColor &color)
Sets the color that text will be rendered in.
static QgsTextFormat fromQFont(const QFont &font)
Returns a text format matching the settings from an input font.
static void drawText(const QRectF &rect, double rotation, HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, VAlignment vAlignment=AlignTop, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags())
Draws text within a rectangle using the specified settings.
static HAlignment convertQtHAlignment(Qt::Alignment alignment)
Converts a Qt horizontal alignment flag to a QgsTextRenderer::HAlignment value.
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:169
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QList< QgsLegendSymbolItem > QgsLegendSymbolList
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition: qgssymbol.h:27
Definition of one class for the legend.