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() );
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 )
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;
62 mTextColor = other.mTextColor;
63 mTextAlignment = other.mTextAlignment;
80 mLineSymbol.reset(
symbol );
85 return mLineSymbol.get();
90 mSizeScaleTransformer.reset( transformer );
95 return mSizeScaleTransformer.get();
105 mSizeScaleTransformer.reset( sizeTransformer ? sizeTransformer->
clone() : nullptr );
107 if ( mTitleLabel.isEmpty() )
111 if ( sizeTransformer && mSizeClasses.isEmpty() )
113 mSizeClasses.clear();
115 for (
double v : prettyBreaks )
117 mSizeClasses <<
SizeClass( v, QString::number( v ) );
125 if ( !mTitleLabel.isEmpty() )
143 lst.reserve( mSizeClasses.size() );
144 for (
const SizeClass &cl : mSizeClasses )
148 double size = cl.
size;
149 if ( mSizeScaleTransformer )
151 size = mSizeScaleTransformer->size( size );
171 *outputSize = QSizeF();
178 double hLengthLineMM = 2;
179 double hSpaceLineTextMM = 1;
181 std::unique_ptr<QgsMarkerSymbol> s( mSymbol->clone() );
183 QList<SizeClass>
classes = mSizeClasses;
186 if ( mSizeScaleTransformer )
189 cls.size = mSizeScaleTransformer->size( cls.size );
197 int dpm = std::round( context.
scaleFactor() * 1000 );
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;
213 double maxTextWidth = 0;
216 maxTextWidth = std::max( maxTextWidth, fm.boundingRect(
c.label ).width() );
222 double largestSize =
classes.at( 0 ).size;
223 double outputLargestSize = context.
convertToPainterUnits( largestSize, s->sizeUnit(), s->sizeMapUnitScale() );
226 QList<double> symbolTopY;
233 symbolTopY << outputLargestSize / 2 - outputSymbolSize / 2;
236 symbolTopY << outputLargestSize - outputSymbolSize;
243 double middleIndex = 0;
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 )
249 double symbolY = symbolTopY[i];
250 if ( symbolY - lastY < minTextDistY )
251 symbolY = lastY + minTextDistY;
252 textCenterY << symbolY;
256 double textTopY = textCenterY.first() - textHeight / 2;
257 double textBottomY = textCenterY.last() + textHeight / 2;
258 double totalTextHeight = textBottomY - textTopY;
260 double fullWidth = outputLargestSize + hLengthLine + hSpaceLineText + maxTextWidth;
261 double fullHeight = std::max( outputLargestSize - textTopY, totalTextHeight );
264 *outputSize = QSizeF( fullWidth, fullHeight );
266 *labelXOffset = outputLargestSize + hLengthLine + hSpaceLineText;
275 QPainter *p = context.
painter();
277 p->translate( 0, -textTopY );
282 s->setSize(
c.size );
285 double tx = ( outputLargestSize - outputSymbolSize ) / 2;
291 p->translate( tx, ( outputLargestSize - outputSymbolSize ) / 2 );
294 p->translate( tx, outputLargestSize - outputSymbolSize );
297 s->drawPreviewIcon(
nullptr, QSize( outputSymbolSize, outputSymbolSize ), &context );
305 mLineSymbol->startRender( context );
314 mLineSymbol->renderPolyline( QPolygonF() << QPointF( outputLargestSize / 2, symbolTopY[i] )
315 << QPointF( outputLargestSize + hLengthLine, textCenterY[i] ),
nullptr, context );
319 QRect rect( outputLargestSize + hLengthLine + hSpaceLineText, textCenterY[i] - textHeight / 2,
320 maxTextWidth, textHeight );
323 QStringList() <<
c.label, context, format );
328 mLineSymbol->stopRender( context );
342 int dpm = std::round( context.
scaleFactor() * 1000 );
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 );
349 QPainter painter( &img );
350 painter.setRenderHint( QPainter::Antialiasing,
true );
352 painter.translate( padding, padding );
355 QPainter *oldPainter = context.
painter();
371 ddsLegend->
setTitle( elem.attribute( QStringLiteral(
"title" ) ) );
373 QDomElement elemSymbol = elem.firstChildElement( QStringLiteral(
"symbol" ) );
374 if ( !elemSymbol.isNull() )
376 ddsLegend->
setSymbol( QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( elemSymbol, context ) );
379 const QDomElement lineSymbolElem = elem.firstChildElement( QStringLiteral(
"lineSymbol" ) );
380 if ( !lineSymbolElem.isNull() )
382 ddsLegend->
setLineSymbol( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( lineSymbolElem.firstChildElement(), context ) );
386 QDomElement elemTransformer = elem.firstChildElement( QStringLiteral(
"transformer" ) );
387 if ( !elemTransformer.isNull() )
394 QDomElement elemTextStyle = elem.firstChildElement( QStringLiteral(
"text-style" ) );
395 if ( !elemTextStyle.isNull() )
397 QDomElement elemFont = elemTextStyle.firstChildElement( QStringLiteral(
"font" ) );
398 if ( !elemFont.isNull() )
400 ddsLegend->
setFont( QFont( elemFont.attribute( QStringLiteral(
"family" ) ), elemFont.attribute( QStringLiteral(
"size" ) ).toInt(),
401 elemFont.attribute( QStringLiteral(
"weight" ) ).toInt(), elemFont.attribute( QStringLiteral(
"italic" ) ).toInt() ) );
404 ddsLegend->
setTextAlignment(
static_cast<Qt::AlignmentFlag
>( elemTextStyle.attribute( QStringLiteral(
"align" ) ).toInt() ) );
407 QDomElement elemClasses = elem.firstChildElement( QStringLiteral(
"classes" ) );
408 if ( !elemClasses.isNull() )
411 QDomElement elemClass = elemClasses.firstChildElement( QStringLiteral(
"class" ) );
412 while ( !elemClass.isNull() )
414 classes <<
SizeClass( elemClass.attribute( QStringLiteral(
"size" ) ).toDouble(), elemClass.attribute( QStringLiteral(
"label" ) ) );
415 elemClass = elemClass.nextSiblingElement();
425 QDomDocument doc = elem.ownerDocument();
427 elem.setAttribute( QStringLiteral(
"type" ), mType ==
LegendCollapsed ?
"collapsed" :
"separated" );
428 elem.setAttribute( QStringLiteral(
"valign" ), mVAlign ==
AlignCenter ?
"center" :
"bottom" );
429 elem.setAttribute( QStringLiteral(
"title" ), mTitleLabel );
434 elem.appendChild( elemSymbol );
439 QDomElement lineSymbolElem = doc.createElement( QStringLiteral(
"lineSymbol" ) );
441 elem.appendChild( lineSymbolElem );
444 if ( mSizeScaleTransformer )
447 elemTransformer.setTagName( QStringLiteral(
"transformer" ) );
448 elem.appendChild( elemTransformer );
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() );
457 QDomElement elemTextStyle = doc.createElement( QStringLiteral(
"text-style" ) );
459 elemTextStyle.setAttribute( QStringLiteral(
"align" ),
static_cast<int>( mTextAlignment ) );
460 elemTextStyle.appendChild( elemFont );
461 elem.appendChild( elemTextStyle );
463 if ( !mSizeClasses.isEmpty() )
465 QDomElement elemClasses = doc.createElement( QStringLiteral(
"classes" ) );
466 for (
const SizeClass &sc : std::as_const( mSizeClasses ) )
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 );
473 elem.appendChild( elemClasses );