25 : mType( other.mType )
26 , mTitleLabel( other.mTitleLabel )
27 , mSizeClasses( other.mSizeClasses )
28 , mSymbol( other.mSymbol.get() ? other.mSymbol->clone() : nullptr )
29 , mSizeScaleTransformer( other.mSizeScaleTransformer.get() ? new
QgsSizeScaleTransformer( *other.mSizeScaleTransformer ) : nullptr )
30 , mVAlign( other.mVAlign )
31 , mFont( other.mFont )
32 , mTextColor( other.mTextColor )
33 , mTextAlignment( other.mTextAlignment )
42 mTitleLabel = other.mTitleLabel;
43 mSizeClasses = other.mSizeClasses;
44 mSymbol.reset( other.mSymbol.get() ? other.mSymbol->clone() : nullptr );
45 mSizeScaleTransformer.reset( other.mSizeScaleTransformer.get() ?
new QgsSizeScaleTransformer( *other.mSizeScaleTransformer ) : nullptr );
46 mVAlign = other.mVAlign;
48 mTextColor = other.mTextColor;
49 mTextAlignment = other.mTextAlignment;
56 mSymbol.reset( symbol );
66 mSizeScaleTransformer.reset( transformer );
71 return mSizeScaleTransformer.get();
77 mSymbol.reset( symbol->
clone() );
81 mSizeScaleTransformer.reset( sizeTransformer ? sizeTransformer->
clone() : nullptr );
83 if ( mTitleLabel.isEmpty() )
87 if ( sizeTransformer && mSizeClasses.isEmpty() )
92 mSizeClasses <<
SizeClass( v, QString::number( v ) );
100 if ( !mTitleLabel.isEmpty() )
115 Q_FOREACH (
const SizeClass &cl, mSizeClasses )
132 *outputSize = QSize();
139 double hLengthLineMM = 2;
140 double hSpaceLineTextMM = 1;
142 std::unique_ptr<QgsMarkerSymbol> s( mSymbol->clone() );
144 QList<SizeClass>
classes = mSizeClasses;
147 if ( mSizeScaleTransformer )
149 for (
auto it = classes.begin(); it != classes.end(); ++it )
150 it->size = mSizeScaleTransformer->size( it->size );
154 std::sort( classes.begin(), classes.end(), [](
const SizeClass & a,
const SizeClass & b ) {
return a.
size > b.size; } );
158 int dpm = std::round( context.
scaleFactor() * 1000 );
161 QImage tmpImg( QSize( 1, 1 ), QImage::Format_ARGB32_Premultiplied );
162 tmpImg.setDotsPerMeterX( dpm );
163 tmpImg.setDotsPerMeterY( dpm );
164 QFontMetrics fm( mFont, &tmpImg );
165 int textHeight = fm.height();
166 int leading = fm.leading();
167 int minTextDistY = textHeight + leading;
174 int maxTextWidth = 0;
177 int w = fm.width( c.
label );
178 if ( w > maxTextWidth )
185 double largestSize = classes.at( 0 ).size;
186 int outputLargestSize = std::round( context.
convertToPainterUnits( largestSize, s->sizeUnit(), s->sizeMapUnitScale() ) );
189 QList<int> symbolTopY;
190 Q_FOREACH (
const SizeClass &c, classes )
196 symbolTopY << std::round( outputLargestSize / 2 - outputSymbolSize / 2 );
199 symbolTopY << std::round( outputLargestSize - outputSymbolSize );
207 QList<int> textCenterY;
208 int lastY = symbolTopY[middleIndex];
209 textCenterY << lastY;
210 for (
int i = middleIndex + 1; i < classes.count(); ++i )
212 int symbolY = symbolTopY[i];
213 if ( symbolY - lastY < minTextDistY )
214 symbolY = lastY + minTextDistY;
215 textCenterY << symbolY;
219 int textTopY = textCenterY.first() - textHeight / 2;
220 int textBottomY = textCenterY.last() + textHeight / 2;
221 int totalTextHeight = textBottomY - textTopY;
223 int fullWidth = outputLargestSize + hLengthLine + hSpaceLineText + maxTextWidth;
224 int fullHeight = std::max( static_cast< int >( std::round( outputLargestSize ) ) - textTopY, totalTextHeight );
227 *outputSize = QSize( fullWidth, fullHeight );
229 *labelXOffset = outputLargestSize + hLengthLine + hSpaceLineText;
238 QPainter *p = context.
painter();
241 p->translate( 0, -textTopY );
244 Q_FOREACH (
const SizeClass &c, classes )
246 s->setSize( c.
size );
249 double tx = ( outputLargestSize - outputSymbolSize ) / 2;
255 p->translate( tx, ( outputLargestSize - outputSymbolSize ) / 2 );
258 p->translate( tx, outputLargestSize - outputSymbolSize );
261 s->drawPreviewIcon( p, QSize( outputSymbolSize, outputSymbolSize ) );
265 p->setPen( mTextColor );
269 Q_FOREACH (
const SizeClass &c, classes )
272 p->drawLine( outputLargestSize / 2, symbolTopY[i], outputLargestSize + hLengthLine, textCenterY[i] );
275 QRect rect( outputLargestSize + hLengthLine + hSpaceLineText, textCenterY[i] - textHeight / 2,
276 maxTextWidth, textHeight );
277 p->drawText( rect, mTextAlignment, c.
label );
295 int dpm = std::round( context.
scaleFactor() * 1000 );
297 QImage img( contentSize.width() + padding * 2, contentSize.height() + padding * 2, QImage::Format_ARGB32_Premultiplied );
298 img.setDotsPerMeterX( dpm );
299 img.setDotsPerMeterY( dpm );
300 img.fill( backgroundColor );
302 QPainter painter( &img );
303 painter.setRenderHint( QPainter::Antialiasing,
true );
305 painter.translate( padding, padding );
308 QPainter *oldPainter = context.
painter();
324 ddsLegend->
setTitle( elem.attribute( QStringLiteral(
"title" ) ) );
326 QDomElement elemSymbol = elem.firstChildElement( QStringLiteral(
"symbol" ) );
327 if ( !elemSymbol.isNull() )
329 ddsLegend->
setSymbol( QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( elemSymbol, context ) );
333 QDomElement elemTransformer = elem.firstChildElement( QStringLiteral(
"transformer" ) );
334 if ( !elemTransformer.isNull() )
341 QDomElement elemTextStyle = elem.firstChildElement( QStringLiteral(
"text-style" ) );
342 if ( !elemTextStyle.isNull() )
344 QDomElement elemFont = elemTextStyle.firstChildElement( QStringLiteral(
"font" ) );
345 if ( !elemFont.isNull() )
347 ddsLegend->
setFont( QFont( elemFont.attribute( QStringLiteral(
"family" ) ), elemFont.attribute( QStringLiteral(
"size" ) ).toInt(),
348 elemFont.attribute( QStringLiteral(
"weight" ) ).toInt(), elemFont.attribute( QStringLiteral(
"italic" ) ).toInt() ) );
351 ddsLegend->
setTextAlignment( static_cast<Qt::AlignmentFlag>( elemTextStyle.attribute( QStringLiteral(
"align" ) ).toInt() ) );
354 QDomElement elemClasses = elem.firstChildElement( QStringLiteral(
"classes" ) );
355 if ( !elemClasses.isNull() )
358 QDomElement elemClass = elemClasses.firstChildElement( QStringLiteral(
"class" ) );
359 while ( !elemClass.isNull() )
361 classes <<
SizeClass( elemClass.attribute( QStringLiteral(
"size" ) ).toDouble(), elemClass.attribute( QStringLiteral(
"label" ) ) );
362 elemClass = elemClass.nextSiblingElement();
372 QDomDocument doc = elem.ownerDocument();
374 elem.setAttribute( QStringLiteral(
"type" ), mType ==
LegendCollapsed ?
"collapsed" :
"separated" );
375 elem.setAttribute( QStringLiteral(
"valign" ), mVAlign ==
AlignCenter ?
"center" :
"bottom" );
376 elem.setAttribute( QStringLiteral(
"title" ), mTitleLabel );
381 elem.appendChild( elemSymbol );
384 if ( mSizeScaleTransformer )
387 elemTransformer.setTagName( QStringLiteral(
"transformer" ) );
388 elem.appendChild( elemTransformer );
391 QDomElement elemFont = doc.createElement( QStringLiteral(
"font" ) );
392 elemFont.setAttribute( QStringLiteral(
"family" ), mFont.family() );
393 elemFont.setAttribute( QStringLiteral(
"size" ), mFont.pointSize() );
394 elemFont.setAttribute( QStringLiteral(
"weight" ), mFont.weight() );
395 elemFont.setAttribute( QStringLiteral(
"italic" ), mFont.italic() );
397 QDomElement elemTextStyle = doc.createElement( QStringLiteral(
"text-style" ) );
399 elemTextStyle.setAttribute( QStringLiteral(
"align" ), static_cast<int>( mTextAlignment ) );
400 elemTextStyle.appendChild( elemFont );
401 elem.appendChild( elemTextStyle );
403 if ( !mSizeClasses.isEmpty() )
405 QDomElement elemClasses = doc.createElement( QStringLiteral(
"classes" ) );
406 Q_FOREACH (
const SizeClass &sc, mSizeClasses )
408 QDomElement elemClass = doc.createElement( QStringLiteral(
"class" ) );
409 elemClass.setAttribute( QStringLiteral(
"size" ), sc.
size );
410 elemClass.setAttribute( QStringLiteral(
"label" ), sc.
label );
411 elemClasses.appendChild( elemClass );
413 elem.appendChild( elemClasses );
The class is used as a container of context for various read/write operations on other objects...
Symbols are aligned to the center.
Each class (size value) has a separate legend node.
void drawCollapsedLegend(QgsRenderContext &context, QSize *outputSize SIP_OUT=nullptr, int *labelXOffset SIP_OUT=nullptr) const
Draw the legend if using LegendOneNodeForAll and optionally output size of the legend and x offset of...
QString label
Label to be shown with the particular symbol size.
QList< QgsLegendSymbolItem > QgsLegendSymbolList
void setTextAlignment(Qt::AlignmentFlag flag)
Sets horizontal text alignment for rendering of labels - only valid for collapsed legend...
void setFont(const QFont &font)
Sets font used for rendering of labels - only valid for collapsed legend.
Definition of one class for the legend.
Expression based property (QgsExpressionBasedProperty)
QgsDataDefinedSizeLegend & operator=(const QgsDataDefinedSizeLegend &other)
const QgsPropertyTransformer * transformer() const
Returns the existing transformer used for manipulating the calculated values for the property...
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
void setSize(double size)
Sets the size for the whole symbol.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
void setTitle(const QString &title)
Sets title label for data-defined size legend.
void setLegendType(LegendType type)
Sets how the legend should be rendered.
A marker symbol type, for rendering Point and MultiPoint geometries.
static QString encodeColor(const QColor &color)
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
static QVariant readVariant(const QDomElement &element)
Read a QVariant from a QDomElement.
QgsSizeScaleTransformer * sizeScaleTransformer() const
Returns transformer for scaling of symbol sizes. Returns null if no transformer is defined...
QgsLegendSymbolList legendSymbolList() const
Generates legend symbol items according to the configuration.
Type propertyType() const
Returns the property type.
QgsDataDefinedSizeLegend()=default
Constructor for QgsDataDefinedSizeLegend.
double size
Marker size in units used by the symbol (usually millimeters). May be further scaled before rendering...
QString title() const
Returns title label for data-defined size legend.
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
void updateFromSymbolAndProperty(const QgsMarkerSymbol *symbol, const QgsProperty &ddSize)
Updates the list of classes, source symbol and title label from given symbol and property.
void setSizeScaleTransformer(QgsSizeScaleTransformer *transformer SIP_TRANSFER)
Sets transformer for scaling of symbol sizes. Takes ownership of the object. Accepts null pointer to ...
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const
Writes configuration to the given XML element.
A store for object properties.
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 setVerticalAlignment(VerticalAlignment vAlign)
Sets vertical alignment of symbols - only valid for collapsed legend.
Symbols are aligned to the bottom.
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...
QString field() const
Returns the current field name the property references.
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...
QgsMarkerSymbol * symbol() const
Returns marker symbol that will be used to draw markers in legend.
The class stores information about one class/rule of a vector layer renderer in a unified way that ca...
Contains information about the context of a rendering operation.
QPainter * painter()
Returns the destination QPainter for the render operation.
void setSymbol(QgsMarkerSymbol *symbol SIP_TRANSFER)
Sets marker symbol that will be used to draw markers in legend.
static QDomElement saveSymbol(const QString &symbolName, QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
void setTextColor(const QColor &color)
Sets text color for rendering of labels - only valid for collapsed legend.
Object that keeps configuration of appearance of marker symbol's data-defined size in legend...
All classes are rendered within one legend node.
QString expressionString() const
Returns the expression used for the property value.
static QgsDataDefinedSizeLegend * readXml(const QDomElement &elem, const QgsReadWriteContext &context) SIP_FACTORY
Creates instance from given element and returns it (caller takes ownership). Returns null on error...
void setDataDefinedSizeLegendSettings(QgsDataDefinedSizeLegend *settings)
Sets extra information about data-defined size.
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
static QColor decodeColor(const QString &str)
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...