28 std::unique_ptr< QgsSimpleLineSymbolLayer > lineSymbolLayer = qgis::make_unique< QgsSimpleLineSymbolLayer >( QColor( 0, 0, 0 ), 0.2 );
29 mLineSymbol = qgis::make_unique< QgsLineSymbol >(
QgsSymbolLayerList() << lineSymbolLayer.release() );
35 : mType( other.mType )
36 , mTitleLabel( other.mTitleLabel )
37 , mSizeClasses( other.mSizeClasses )
38 , mSymbol( other.mSymbol.get() ? other.mSymbol->clone() : nullptr )
39 , mLineSymbol( other.mLineSymbol.get() ? other.mLineSymbol->clone() : nullptr )
40 , mSizeScaleTransformer( other.mSizeScaleTransformer.get() ? new
QgsSizeScaleTransformer( *other.mSizeScaleTransformer ) : nullptr )
41 , mVAlign( other.mVAlign )
42 , mFont( other.mFont )
43 , mTextColor( other.mTextColor )
44 , mTextAlignment( other.mTextAlignment )
53 mTitleLabel = other.mTitleLabel;
54 mSizeClasses = other.mSizeClasses;
55 mSymbol.reset( other.mSymbol.get() ? other.mSymbol->clone() :
nullptr );
56 mLineSymbol.reset( other.mLineSymbol.get() ? other.mLineSymbol->clone() :
nullptr );
57 mSizeScaleTransformer.reset( other.mSizeScaleTransformer.get() ?
new QgsSizeScaleTransformer( *other.mSizeScaleTransformer ) :
nullptr );
58 mVAlign = other.mVAlign;
60 mTextColor = other.mTextColor;
61 mTextAlignment = other.mTextAlignment;
78 mLineSymbol.reset(
symbol );
83 return mLineSymbol.get();
88 mSizeScaleTransformer.reset( transformer );
93 return mSizeScaleTransformer.get();
103 mSizeScaleTransformer.reset( sizeTransformer ? sizeTransformer->
clone() : nullptr );
105 if ( mTitleLabel.isEmpty() )
109 if ( sizeTransformer && mSizeClasses.isEmpty() )
111 mSizeClasses.clear();
113 for (
double v : prettyBreaks )
115 mSizeClasses <<
SizeClass( v, QString::number( v ) );
123 if ( !mTitleLabel.isEmpty() )
141 lst.reserve( mSizeClasses.size() );
142 for (
const SizeClass &cl : mSizeClasses )
146 double size = cl.
size;
147 if ( mSizeScaleTransformer )
149 size = mSizeScaleTransformer->size( size );
169 *outputSize = QSizeF();
176 double hLengthLineMM = 2;
177 double hSpaceLineTextMM = 1;
179 std::unique_ptr<QgsMarkerSymbol> s( mSymbol->clone() );
181 QList<SizeClass>
classes = mSizeClasses;
184 if ( mSizeScaleTransformer )
187 cls.size = mSizeScaleTransformer->size( cls.size );
195 int dpm = std::round( context.
scaleFactor() * 1000 );
198 QImage tmpImg( QSize( 1, 1 ), QImage::Format_ARGB32_Premultiplied );
199 tmpImg.setDotsPerMeterX( dpm );
200 tmpImg.setDotsPerMeterY( dpm );
201 QFontMetricsF fm( mFont, &tmpImg );
202 double textHeight = fm.height();
203 double leading = fm.leading();
204 double minTextDistY = textHeight + leading;
211 double maxTextWidth = 0;
214 maxTextWidth = std::max( maxTextWidth, fm.boundingRect(
c.label ).width() );
220 double largestSize =
classes.at( 0 ).size;
221 double outputLargestSize = context.
convertToPainterUnits( largestSize, s->sizeUnit(), s->sizeMapUnitScale() );
224 QList<double> symbolTopY;
231 symbolTopY << outputLargestSize / 2 - outputSymbolSize / 2;
234 symbolTopY << outputLargestSize - outputSymbolSize;
241 double middleIndex = 0;
242 QList<double> textCenterY;
243 double lastY = symbolTopY[middleIndex];
244 textCenterY << lastY;
245 for (
int i = middleIndex + 1; i <
classes.count(); ++i )
247 double symbolY = symbolTopY[i];
248 if ( symbolY - lastY < minTextDistY )
249 symbolY = lastY + minTextDistY;
250 textCenterY << symbolY;
254 double textTopY = textCenterY.first() - textHeight / 2;
255 double textBottomY = textCenterY.last() + textHeight / 2;
256 double totalTextHeight = textBottomY - textTopY;
258 double fullWidth = outputLargestSize + hLengthLine + hSpaceLineText + maxTextWidth;
259 double fullHeight = std::max( outputLargestSize - textTopY, totalTextHeight );
262 *outputSize = QSizeF( fullWidth, fullHeight );
264 *labelXOffset = outputLargestSize + hLengthLine + hSpaceLineText;
273 QPainter *p = context.
painter();
276 p->translate( 0, -textTopY );
281 s->setSize(
c.size );
284 double tx = ( outputLargestSize - outputSymbolSize ) / 2;
290 p->translate( tx, ( outputLargestSize - outputSymbolSize ) / 2 );
293 p->translate( tx, outputLargestSize - outputSymbolSize );
296 s->drawPreviewIcon(
nullptr, QSize( outputSymbolSize, outputSymbolSize ), &context );
305 mLineSymbol->setColor( mTextColor );
306 mLineSymbol->startRender( context );
315 mLineSymbol->renderPolyline( QPolygonF() << QPointF( outputLargestSize / 2, symbolTopY[i] )
316 << QPointF( outputLargestSize + hLengthLine, textCenterY[i] ),
nullptr, context );
320 QRect rect( outputLargestSize + hLengthLine + hSpaceLineText, textCenterY[i] - textHeight / 2,
321 maxTextWidth, textHeight );
325 QStringList() <<
c.label, context, format );
330 mLineSymbol->stopRender( context );
346 int dpm = std::round( context.
scaleFactor() * 1000 );
348 QImage img( contentSize.width() + padding * 2, contentSize.height() + padding * 2, QImage::Format_ARGB32_Premultiplied );
349 img.setDotsPerMeterX( dpm );
350 img.setDotsPerMeterY( dpm );
351 img.fill( backgroundColor );
353 QPainter painter( &img );
354 painter.setRenderHint( QPainter::Antialiasing,
true );
356 painter.translate( padding, padding );
359 QPainter *oldPainter = context.
painter();
375 ddsLegend->
setTitle( elem.attribute( QStringLiteral(
"title" ) ) );
377 QDomElement elemSymbol = elem.firstChildElement( QStringLiteral(
"symbol" ) );
378 if ( !elemSymbol.isNull() )
380 ddsLegend->
setSymbol( QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( elemSymbol, context ) );
383 QDomElement
lineSymbol = elem.firstChildElement( QStringLiteral(
"lineSymbol" ) );
390 QDomElement elemTransformer = elem.firstChildElement( QStringLiteral(
"transformer" ) );
391 if ( !elemTransformer.isNull() )
398 QDomElement elemTextStyle = elem.firstChildElement( QStringLiteral(
"text-style" ) );
399 if ( !elemTextStyle.isNull() )
401 QDomElement elemFont = elemTextStyle.firstChildElement( QStringLiteral(
"font" ) );
402 if ( !elemFont.isNull() )
404 ddsLegend->
setFont( QFont( elemFont.attribute( QStringLiteral(
"family" ) ), elemFont.attribute( QStringLiteral(
"size" ) ).toInt(),
405 elemFont.attribute( QStringLiteral(
"weight" ) ).toInt(), elemFont.attribute( QStringLiteral(
"italic" ) ).toInt() ) );
408 ddsLegend->
setTextAlignment(
static_cast<Qt::AlignmentFlag
>( elemTextStyle.attribute( QStringLiteral(
"align" ) ).toInt() ) );
411 QDomElement elemClasses = elem.firstChildElement( QStringLiteral(
"classes" ) );
412 if ( !elemClasses.isNull() )
415 QDomElement elemClass = elemClasses.firstChildElement( QStringLiteral(
"class" ) );
416 while ( !elemClass.isNull() )
418 classes <<
SizeClass( elemClass.attribute( QStringLiteral(
"size" ) ).toDouble(), elemClass.attribute( QStringLiteral(
"label" ) ) );
419 elemClass = elemClass.nextSiblingElement();
429 QDomDocument doc = elem.ownerDocument();
431 elem.setAttribute( QStringLiteral(
"type" ), mType ==
LegendCollapsed ?
"collapsed" :
"separated" );
432 elem.setAttribute( QStringLiteral(
"valign" ), mVAlign ==
AlignCenter ?
"center" :
"bottom" );
433 elem.setAttribute( QStringLiteral(
"title" ), mTitleLabel );
438 elem.appendChild( elemSymbol );
444 elem.appendChild( elemSymbol );
447 if ( mSizeScaleTransformer )
450 elemTransformer.setTagName( QStringLiteral(
"transformer" ) );
451 elem.appendChild( elemTransformer );
454 QDomElement elemFont = doc.createElement( QStringLiteral(
"font" ) );
455 elemFont.setAttribute( QStringLiteral(
"family" ), mFont.family() );
456 elemFont.setAttribute( QStringLiteral(
"size" ), mFont.pointSize() );
457 elemFont.setAttribute( QStringLiteral(
"weight" ), mFont.weight() );
458 elemFont.setAttribute( QStringLiteral(
"italic" ), mFont.italic() );
460 QDomElement elemTextStyle = doc.createElement( QStringLiteral(
"text-style" ) );
462 elemTextStyle.setAttribute( QStringLiteral(
"align" ),
static_cast<int>( mTextAlignment ) );
463 elemTextStyle.appendChild( elemFont );
464 elem.appendChild( elemTextStyle );
466 if ( !mSizeClasses.isEmpty() )
468 QDomElement elemClasses = doc.createElement( QStringLiteral(
"classes" ) );
469 for (
const SizeClass &sc : qgis::as_const( mSizeClasses ) )
471 QDomElement elemClass = doc.createElement( QStringLiteral(
"class" ) );
472 elemClass.setAttribute( QStringLiteral(
"size" ), sc.size );
473 elemClass.setAttribute( QStringLiteral(
"label" ), sc.label );
474 elemClasses.appendChild( elemClass );
476 elem.appendChild( elemClasses );