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();
275 p->translate( 0, -textTopY );
280 s->setSize(
c.size );
283 double tx = ( outputLargestSize - outputSymbolSize ) / 2;
289 p->translate( tx, ( outputLargestSize - outputSymbolSize ) / 2 );
292 p->translate( tx, outputLargestSize - outputSymbolSize );
295 s->drawPreviewIcon(
nullptr, QSize( outputSymbolSize, outputSymbolSize ), &context );
303 mLineSymbol->setColor( mTextColor );
304 mLineSymbol->startRender( context );
313 mLineSymbol->renderPolyline( QPolygonF() << QPointF( outputLargestSize / 2, symbolTopY[i] )
314 << QPointF( outputLargestSize + hLengthLine, textCenterY[i] ),
nullptr, context );
318 QRect rect( outputLargestSize + hLengthLine + hSpaceLineText, textCenterY[i] - textHeight / 2,
319 maxTextWidth, textHeight );
322 QStringList() <<
c.label, context, format );
327 mLineSymbol->stopRender( context );
341 int dpm = std::round( context.
scaleFactor() * 1000 );
343 QImage img( contentSize.width() + padding * 2, contentSize.height() + padding * 2, QImage::Format_ARGB32_Premultiplied );
344 img.setDotsPerMeterX( dpm );
345 img.setDotsPerMeterY( dpm );
346 img.fill( backgroundColor );
348 QPainter painter( &img );
349 painter.setRenderHint( QPainter::Antialiasing,
true );
351 painter.translate( padding, padding );
354 QPainter *oldPainter = context.
painter();
370 ddsLegend->
setTitle( elem.attribute( QStringLiteral(
"title" ) ) );
372 QDomElement elemSymbol = elem.firstChildElement( QStringLiteral(
"symbol" ) );
373 if ( !elemSymbol.isNull() )
375 ddsLegend->
setSymbol( QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( elemSymbol, context ) );
378 QDomElement
lineSymbol = elem.firstChildElement( QStringLiteral(
"lineSymbol" ) );
385 QDomElement elemTransformer = elem.firstChildElement( QStringLiteral(
"transformer" ) );
386 if ( !elemTransformer.isNull() )
393 QDomElement elemTextStyle = elem.firstChildElement( QStringLiteral(
"text-style" ) );
394 if ( !elemTextStyle.isNull() )
396 QDomElement elemFont = elemTextStyle.firstChildElement( QStringLiteral(
"font" ) );
397 if ( !elemFont.isNull() )
399 ddsLegend->
setFont( QFont( elemFont.attribute( QStringLiteral(
"family" ) ), elemFont.attribute( QStringLiteral(
"size" ) ).toInt(),
400 elemFont.attribute( QStringLiteral(
"weight" ) ).toInt(), elemFont.attribute( QStringLiteral(
"italic" ) ).toInt() ) );
403 ddsLegend->
setTextAlignment(
static_cast<Qt::AlignmentFlag
>( elemTextStyle.attribute( QStringLiteral(
"align" ) ).toInt() ) );
406 QDomElement elemClasses = elem.firstChildElement( QStringLiteral(
"classes" ) );
407 if ( !elemClasses.isNull() )
410 QDomElement elemClass = elemClasses.firstChildElement( QStringLiteral(
"class" ) );
411 while ( !elemClass.isNull() )
413 classes <<
SizeClass( elemClass.attribute( QStringLiteral(
"size" ) ).toDouble(), elemClass.attribute( QStringLiteral(
"label" ) ) );
414 elemClass = elemClass.nextSiblingElement();
424 QDomDocument doc = elem.ownerDocument();
426 elem.setAttribute( QStringLiteral(
"type" ), mType ==
LegendCollapsed ?
"collapsed" :
"separated" );
427 elem.setAttribute( QStringLiteral(
"valign" ), mVAlign ==
AlignCenter ?
"center" :
"bottom" );
428 elem.setAttribute( QStringLiteral(
"title" ), mTitleLabel );
433 elem.appendChild( elemSymbol );
439 elem.appendChild( elemSymbol );
442 if ( mSizeScaleTransformer )
445 elemTransformer.setTagName( QStringLiteral(
"transformer" ) );
446 elem.appendChild( elemTransformer );
449 QDomElement elemFont = doc.createElement( QStringLiteral(
"font" ) );
450 elemFont.setAttribute( QStringLiteral(
"family" ), mFont.family() );
451 elemFont.setAttribute( QStringLiteral(
"size" ), mFont.pointSize() );
452 elemFont.setAttribute( QStringLiteral(
"weight" ), mFont.weight() );
453 elemFont.setAttribute( QStringLiteral(
"italic" ), mFont.italic() );
455 QDomElement elemTextStyle = doc.createElement( QStringLiteral(
"text-style" ) );
457 elemTextStyle.setAttribute( QStringLiteral(
"align" ),
static_cast<int>( mTextAlignment ) );
458 elemTextStyle.appendChild( elemFont );
459 elem.appendChild( elemTextStyle );
461 if ( !mSizeClasses.isEmpty() )
463 QDomElement elemClasses = doc.createElement( QStringLiteral(
"classes" ) );
464 for (
const SizeClass &sc : qgis::as_const( mSizeClasses ) )
466 QDomElement elemClass = doc.createElement( QStringLiteral(
"class" ) );
467 elemClass.setAttribute( QStringLiteral(
"size" ), sc.size );
468 elemClass.setAttribute( QStringLiteral(
"label" ), sc.label );
469 elemClasses.appendChild( elemClass );
471 elem.appendChild( elemClasses );