QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
qgsmaplayerlegend.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmaplayerlegend.cpp
3 --------------------------------------
4 Date : July 2014
5 Copyright : (C) 2014 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
16#include "qgsmaplayerlegend.h"
17
19#include "qgsdiagramrenderer.h"
20#include "qgsiconutils.h"
21#include "qgsimagecache.h"
22#include "qgslayertree.h"
24#include "qgsmeshlayer.h"
25#include "qgspluginlayer.h"
26#include "qgspointcloudlayer.h"
28#include "qgsrasterlayer.h"
29#include "qgsrasterrenderer.h"
30#include "qgsrenderer.h"
32#include "qgssettings.h"
33#include "qgssymbollayerutils.h"
34#include "qgsvectorlayer.h"
36
37#include "moc_qgsmaplayerlegend.cpp"
38
40 : QObject( parent )
41{
42}
43
44void QgsMapLayerLegend::readXml( const QDomElement &elem, const QgsReadWriteContext & )
45{
47 mFlags.setFlag( Qgis::MapLayerLegendFlag::ExcludeByDefault, elem.attribute( QStringLiteral( "excludeByDefault" ), QStringLiteral( "0" ) ).toInt() == 1 );
48}
49
50QDomElement QgsMapLayerLegend::writeXml( QDomDocument &doc, const QgsReadWriteContext & ) const
51{
52 QDomElement elem = doc.createElement( QStringLiteral( "legend" ) );
53 if ( mFlags.testFlag( Qgis::MapLayerLegendFlag::ExcludeByDefault ) )
54 {
55 elem.setAttribute( QStringLiteral( "excludeByDefault" ), QStringLiteral( "1" ) );
56 }
57 return elem;
58}
59
64
69
74
79
80// -------------------------------------------------------------------------
81
82
83void QgsMapLayerLegendUtils::setLegendNodeOrder( QgsLayerTreeLayer *nodeLayer, const QList<int> &order )
84{
85 QStringList orderStr;
86 const auto constOrder = order;
87 for ( const int id : constOrder )
88 orderStr << QString::number( id );
89 const QString str = orderStr.isEmpty() ? QStringLiteral( "empty" ) : orderStr.join( QLatin1Char( ',' ) );
90
91 nodeLayer->setCustomProperty( QStringLiteral( "legend/node-order" ), str );
92}
93
94static int _originalLegendNodeCount( QgsLayerTreeLayer *nodeLayer )
95{
96 // this is not particularly efficient way of finding out number of legend nodes
97 const QList<QgsLayerTreeModelLegendNode *> lst = nodeLayer->layer()->legend()->createLayerTreeModelLegendNodes( nodeLayer );
98 const int numNodes = lst.count();
99 qDeleteAll( lst );
100 return numNodes;
101}
102
103static QList<int> _makeNodeOrder( QgsLayerTreeLayer *nodeLayer )
104{
105 if ( !nodeLayer->layer() || !nodeLayer->layer()->legend() )
106 {
107 QgsDebugError( QStringLiteral( "Legend node order manipulation is invalid without existing legend" ) );
108 return QList<int>();
109 }
110
111 const int numNodes = _originalLegendNodeCount( nodeLayer );
112
113 QList<int> order;
114 order.reserve( numNodes );
115 for ( int i = 0; i < numNodes; ++i )
116 order << i;
117 return order;
118}
119
121{
122 const QString orderStr = nodeLayer->customProperty( QStringLiteral( "legend/node-order" ) ).toString();
123
124 if ( orderStr.isEmpty() )
125 return _makeNodeOrder( nodeLayer );
126
127 if ( orderStr == QLatin1String( "empty" ) )
128 return QList<int>();
129
130 const int numNodes = _originalLegendNodeCount( nodeLayer );
131
132 QList<int> lst;
133 const auto constSplit = orderStr.split( ',' );
134 for ( const QString &item : constSplit )
135 {
136 bool ok;
137 const int id = item.toInt( &ok );
138 if ( !ok || id < 0 || id >= numNodes )
139 return _makeNodeOrder( nodeLayer );
140
141 lst << id;
142 }
143
144 return lst;
145}
146
148{
149 return nodeLayer->customProperties().contains( QStringLiteral( "legend/node-order" ) );
150}
151
152void QgsMapLayerLegendUtils::setLegendNodeUserLabel( QgsLayerTreeLayer *nodeLayer, int originalIndex, const QString &newLabel )
153{
154 nodeLayer->setCustomProperty( "legend/label-" + QString::number( originalIndex ), newLabel );
155}
156
158{
159 return nodeLayer->customProperty( "legend/label-" + QString::number( originalIndex ) ).toString();
160}
161
163{
164 return nodeLayer->customProperties().contains( "legend/label-" + QString::number( originalIndex ) );
165}
166
168{
169 QDomDocument patchDoc;
170 QDomElement patchElem = patchDoc.createElement( QStringLiteral( "patch" ) );
171 shape.writeXml( patchElem, patchDoc, QgsReadWriteContext() );
172 patchDoc.appendChild( patchElem );
173 nodeLayer->setCustomProperty( "legend/patch-shape-" + QString::number( originalIndex ), patchDoc.toString() );
174}
175
177{
178 const QString patchDef = nodeLayer->customProperty( "legend/patch-shape-" + QString::number( originalIndex ) ).toString();
179 if ( patchDef.isEmpty() )
180 return QgsLegendPatchShape();
181
182 QDomDocument doc( QStringLiteral( "patch" ) );
183 doc.setContent( patchDef );
185 shape.readXml( doc.documentElement(), QgsReadWriteContext() );
186 return shape;
187}
188
189void QgsMapLayerLegendUtils::setLegendNodeSymbolSize( QgsLayerTreeLayer *nodeLayer, int originalIndex, QSizeF size )
190{
191 if ( size.isValid() )
192 nodeLayer->setCustomProperty( "legend/symbol-size-" + QString::number( originalIndex ), QgsSymbolLayerUtils::encodeSize( size ) );
193 else
194 nodeLayer->removeCustomProperty( "legend/symbol-size-" + QString::number( originalIndex ) );
195}
196
198{
199 const QString size = nodeLayer->customProperty( "legend/symbol-size-" + QString::number( originalIndex ) ).toString();
200 if ( size.isEmpty() )
201 return QSizeF();
202 else
203 return QgsSymbolLayerUtils::decodeSize( size );
204}
205
206void QgsMapLayerLegendUtils::setLegendNodeCustomSymbol( QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsSymbol *symbol )
207{
208 if ( symbol )
209 {
210 QDomDocument doc;
211 QgsReadWriteContext rwContext;
212 rwContext.setPathResolver( QgsProject::instance()->pathResolver() ); // skip-keyword-check
213 const QDomElement elem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "custom symbol" ), symbol, doc, rwContext );
214 doc.appendChild( elem );
215 nodeLayer->setCustomProperty( "legend/custom-symbol-" + QString::number( originalIndex ), doc.toString() );
216 }
217 else
218 nodeLayer->removeCustomProperty( "legend/custom-symbol-" + QString::number( originalIndex ) );
219}
220
221std::unique_ptr< QgsSymbol > QgsMapLayerLegendUtils::legendNodeCustomSymbol( QgsLayerTreeLayer *nodeLayer, int originalIndex )
222{
223 const QString symbolDef = nodeLayer->customProperty( "legend/custom-symbol-" + QString::number( originalIndex ) ).toString();
224 if ( symbolDef.isEmpty() )
225 return nullptr;
226
227 QDomDocument doc;
228 doc.setContent( symbolDef );
229 const QDomElement elem = doc.documentElement();
230
231 QgsReadWriteContext rwContext;
232 rwContext.setPathResolver( QgsProject::instance()->pathResolver() ); // skip-keyword-check
233
234 return QgsSymbolLayerUtils::loadSymbol( elem, rwContext );
235}
236
238{
239 if ( settings )
240 {
241 QDomDocument doc;
242 QgsReadWriteContext rwContext;
243 rwContext.setPathResolver( QgsProject::instance()->pathResolver() ); // skip-keyword-check
244 QDomElement elem = doc.createElement( QStringLiteral( "rampSettings" ) );
245 settings->writeXml( doc, elem, rwContext );
246 doc.appendChild( elem );
247 nodeLayer->setCustomProperty( "legend/custom-ramp-settings-" + QString::number( originalIndex ), doc.toString() );
248 }
249 else
250 nodeLayer->removeCustomProperty( "legend/custom-ramp-settings-" + QString::number( originalIndex ) );
251}
252
254{
255 const QString settingsDef = nodeLayer->customProperty( "legend/custom-ramp-settings-" + QString::number( originalIndex ) ).toString();
256 if ( settingsDef.isEmpty() )
257 return nullptr;
258
259 QDomDocument doc;
260 doc.setContent( settingsDef );
261 const QDomElement elem = doc.documentElement();
262
263 QgsReadWriteContext rwContext;
264 rwContext.setPathResolver( QgsProject::instance()->pathResolver() ); // skip-keyword-check
265
267 settings.readXml( elem, rwContext );
268 return new QgsColorRampLegendNodeSettings( std::move( settings ) );
269}
270
271void QgsMapLayerLegendUtils::setLegendNodeColumnBreak( QgsLayerTreeLayer *nodeLayer, int originalIndex, bool columnBreakBeforeNode )
272{
273 if ( columnBreakBeforeNode )
274 nodeLayer->setCustomProperty( "legend/column-break-" + QString::number( originalIndex ), QStringLiteral( "1" ) );
275 else
276 nodeLayer->removeCustomProperty( "legend/column-break-" + QString::number( originalIndex ) );
277}
278
280{
281 return nodeLayer->customProperty( "legend/column-break-" + QString::number( originalIndex ) ).toInt();
282}
283
284void QgsMapLayerLegendUtils::applyLayerNodeProperties( QgsLayerTreeLayer *nodeLayer, QList<QgsLayerTreeModelLegendNode *> &nodes )
285{
286 // handle user labels
287 int i = 0;
288 const auto constNodes = nodes;
289 for ( QgsLayerTreeModelLegendNode *legendNode : constNodes )
290 {
291 const QString userLabel = QgsMapLayerLegendUtils::legendNodeUserLabel( nodeLayer, i );
292 if ( !userLabel.isNull() )
293 legendNode->setUserLabel( userLabel );
294
295 if ( QgsSymbolLegendNode *symbolNode = dynamic_cast< QgsSymbolLegendNode * >( legendNode ) )
296 {
298 symbolNode->setPatchShape( shape );
299
300 symbolNode->setCustomSymbol( QgsMapLayerLegendUtils::legendNodeCustomSymbol( nodeLayer, i ).release() );
301 }
302 else if ( QgsColorRampLegendNode *colorRampNode = dynamic_cast< QgsColorRampLegendNode * >( legendNode ) )
303 {
304 const std::unique_ptr< QgsColorRampLegendNodeSettings > settings( QgsMapLayerLegendUtils::legendNodeColorRampSettings( nodeLayer, i ) );
305 if ( settings )
306 {
307 colorRampNode->setSettings( *settings );
308 }
309 }
310
311 const QSizeF userSize = QgsMapLayerLegendUtils::legendNodeSymbolSize( nodeLayer, i );
312 if ( userSize.isValid() )
313 {
314 legendNode->setUserPatchSize( userSize );
315 }
316
317 if ( legendNodeColumnBreak( nodeLayer, i ) )
318 legendNode->setColumnBreak( true );
319
320 i++;
321 }
322
323 // handle user order of nodes
325 {
326 const QList<int> order = QgsMapLayerLegendUtils::legendNodeOrder( nodeLayer );
327
328 QList<QgsLayerTreeModelLegendNode *> newOrder;
329 QSet<int> usedIndices;
330 const auto constOrder = order;
331 for ( const int idx : constOrder )
332 {
333 if ( usedIndices.contains( idx ) )
334 {
335 QgsDebugError( QStringLiteral( "invalid node order. ignoring." ) );
336 return;
337 }
338
339 newOrder << nodes[idx];
340 usedIndices << idx;
341 }
342
343 // delete unused nodes
344 for ( int i = 0; i < nodes.count(); ++i )
345 {
346 if ( !usedIndices.contains( i ) )
347 delete nodes[i];
348 }
349
350 nodes = newOrder;
351 }
352
353}
354
355// -------------------------------------------------------------------------
356
357
364
366{
367 QList<QgsLayerTreeModelLegendNode *> nodes;
368 if ( !mLayer )
369 return nodes;
370
371 const QString placeholderImage = mLayer->legendPlaceholderImage();
372 if ( !placeholderImage.isEmpty() )
373 {
374 bool fitsInCache;
375 const QImage img = QgsApplication::imageCache()->pathAsImage( placeholderImage, QSize(), false, 1.0, fitsInCache );
376 nodes << new QgsImageLegendNode( nodeLayer, img );
377 return nodes;
378 }
379
380 QgsFeatureRenderer *r = mLayer->renderer();
381 if ( !r )
382 return nodes;
383
384 if ( nodeLayer->customProperty( QStringLiteral( "showFeatureCount" ), 0 ).toBool() )
385 mLayer->countSymbolFeatures();
386
387 const QgsSettings settings;
388 if ( settings.value( QStringLiteral( "qgis/showLegendClassifiers" ), false ).toBool() && !r->legendClassificationAttribute().isEmpty() )
389 {
390 nodes.append( new QgsSimpleLegendNode( nodeLayer, r->legendClassificationAttribute() ) );
391 }
392
393 const QList<QgsLayerTreeModelLegendNode *> rendererNodes = r->createLegendNodes( nodeLayer );
394 for ( QgsLayerTreeModelLegendNode *node : rendererNodes )
395 {
396 if ( QgsSymbolLegendNode *legendNode = qobject_cast< QgsSymbolLegendNode *>( node ) )
397 {
398 const QString ruleKey = legendNode->data( static_cast< int >( QgsLayerTreeModelLegendNode::CustomRole::RuleKey ) ).toString();
399 if ( mTextOnSymbolEnabled && mTextOnSymbolContent.contains( ruleKey ) )
400 {
401 legendNode->setTextOnSymbolLabel( mTextOnSymbolContent.value( ruleKey ) );
402 legendNode->setTextOnSymbolTextFormat( mTextOnSymbolTextFormat );
403 }
404 }
405 nodes << node;
406 }
407
408 if ( nodes.count() == 1 && nodes[0]->data( Qt::EditRole ).toString().isEmpty() && qobject_cast< QgsSymbolLegendNode * >( nodes[0] ) )
409 nodes[0]->setEmbeddedInParent( true );
410
411 if ( mLayer->diagramsEnabled() )
412 {
413 const auto constLegendItems = mLayer->diagramRenderer()->legendItems( nodeLayer );
414 for ( QgsLayerTreeModelLegendNode *i : constLegendItems )
415 {
416 nodes.append( i );
417 }
418 }
419
420 if ( mLayer->labelsEnabled() && mShowLabelLegend )
421 {
422 const QgsAbstractVectorLayerLabeling *labeling = mLayer->labeling();
423 if ( labeling )
424 {
425 const QStringList pList = labeling->subProviders();
426 for ( int i = 0; i < pList.size(); ++i )
427 {
428 const QgsPalLayerSettings s = labeling->settings( pList.at( i ) );
429 QString description;
430 const QgsRuleBasedLabeling *ruleBasedLabeling = dynamic_cast<const QgsRuleBasedLabeling *>( labeling );
431 if ( ruleBasedLabeling && ruleBasedLabeling->rootRule() )
432 {
433 const QgsRuleBasedLabeling::Rule *rule = ruleBasedLabeling->rootRule()->findRuleByKey( pList.at( i ) );
434 if ( rule )
435 {
436 description = rule->description();
437 }
438 }
439 QgsVectorLabelLegendNode *node = new QgsVectorLabelLegendNode( nodeLayer, s );
440 node->setUserLabel( description );
441 nodes.append( node );
442 }
443 }
444 }
445
446 return nodes;
447}
448
449void QgsDefaultVectorLayerLegend::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
450{
451 QgsMapLayerLegend::readXml( elem, context );
452
453 mTextOnSymbolEnabled = false;
454 mTextOnSymbolTextFormat = QgsTextFormat();
455 mTextOnSymbolContent.clear();
456
457 mShowLabelLegend = elem.attribute( QStringLiteral( "showLabelLegend" ), QStringLiteral( "0" ) ).compare( QStringLiteral( "1" ), Qt::CaseInsensitive ) == 0;
458
459 const QDomElement tosElem = elem.firstChildElement( QStringLiteral( "text-on-symbol" ) );
460 if ( !tosElem.isNull() )
461 {
462 mTextOnSymbolEnabled = true;
463 const QDomElement tosFormatElem = tosElem.firstChildElement( QStringLiteral( "text-style" ) );
464 mTextOnSymbolTextFormat.readXml( tosFormatElem, context );
465 const QDomElement tosContentElem = tosElem.firstChildElement( QStringLiteral( "content" ) );
466 QDomElement tosContentItemElem = tosContentElem.firstChildElement( QStringLiteral( "item" ) );
467 while ( !tosContentItemElem.isNull() )
468 {
469 mTextOnSymbolContent.insert( tosContentItemElem.attribute( QStringLiteral( "key" ) ), tosContentItemElem.attribute( QStringLiteral( "value" ) ) );
470 tosContentItemElem = tosContentItemElem.nextSiblingElement( QStringLiteral( "item" ) );
471 }
472 }
473}
474
475QDomElement QgsDefaultVectorLayerLegend::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
476{
477 QDomElement elem = QgsMapLayerLegend::writeXml( doc, context );
478 elem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "default-vector" ) );
479 elem.setAttribute( QStringLiteral( "showLabelLegend" ), mShowLabelLegend );
480
481 if ( mTextOnSymbolEnabled )
482 {
483 QDomElement tosElem = doc.createElement( QStringLiteral( "text-on-symbol" ) );
484 const QDomElement tosFormatElem = mTextOnSymbolTextFormat.writeXml( doc, context );
485 tosElem.appendChild( tosFormatElem );
486 QDomElement tosContentElem = doc.createElement( QStringLiteral( "content" ) );
487 for ( auto it = mTextOnSymbolContent.constBegin(); it != mTextOnSymbolContent.constEnd(); ++it )
488 {
489 QDomElement tosContentItemElem = doc.createElement( QStringLiteral( "item" ) );
490 tosContentItemElem.setAttribute( QStringLiteral( "key" ), it.key() );
491 tosContentItemElem.setAttribute( QStringLiteral( "value" ), it.value() );
492 tosContentElem.appendChild( tosContentItemElem );
493 }
494 tosElem.appendChild( tosContentElem );
495 elem.appendChild( tosElem );
496 }
497
498 return elem;
499}
500
501
502// -------------------------------------------------------------------------
503
504
510
512{
513 QList<QgsLayerTreeModelLegendNode *> nodes;
514
515 // temporary solution for WMS. Ideally should be done with a delegate.
516 if ( mLayer->dataProvider() && mLayer->dataProvider()->supportsLegendGraphic() )
517 {
518 nodes << new QgsWmsLegendNode( nodeLayer );
519 }
520
521 const QString placeholderImage = mLayer->legendPlaceholderImage();
522 if ( !placeholderImage.isEmpty() )
523 {
524 bool fitsInCache;
525 const QImage img = QgsApplication::imageCache()->pathAsImage( placeholderImage, QSize(), false, 1.0, fitsInCache );
526 nodes << new QgsImageLegendNode( nodeLayer, img );
527 }
528 else if ( mLayer->renderer() )
529 nodes.append( mLayer->renderer()->createLegendNodes( nodeLayer ) );
530 return nodes;
531}
532
533// -------------------------------------------------------------------------
534
540
542{
543 QList<QgsLayerTreeModelLegendNode *> nodes;
544
545 const QgsMeshRendererSettings rendererSettings = mLayer->rendererSettings();
546
547 const int indexScalar = rendererSettings.activeScalarDatasetGroup();
548 const int indexVector = rendererSettings.activeVectorDatasetGroup();
549
550 QString name;
551 if ( indexScalar > -1 && indexVector > -1 && indexScalar != indexVector )
552 name = QString( "%1 / %2" ).arg( mLayer->datasetGroupMetadata( indexScalar ).name(), mLayer->datasetGroupMetadata( indexVector ).name() );
553 else if ( indexScalar > -1 )
554 name = mLayer->datasetGroupMetadata( indexScalar ).name();
555 else if ( indexVector > -1 )
556 name = mLayer->datasetGroupMetadata( indexVector ).name();
557 else
558 {
559 // neither contours nor vectors get rendered - no legend needed
560 return nodes;
561 }
562
563 if ( indexScalar > -1 )
564 {
565 const QString scalarNameKey = QStringLiteral( "scalarName" );
566 nodes << new QgsSimpleLegendNode( nodeLayer, mLayer->datasetGroupMetadata( indexScalar ).name(),
567 QIcon(), nullptr, scalarNameKey );
568 const QgsMeshRendererScalarSettings settings = rendererSettings.scalarSettings( indexScalar );
569 const QgsColorRampShader shader = settings.colorRampShader();
570 switch ( shader.colorRampType() )
571 {
573 if ( !shader.legendSettings() || shader.legendSettings()->useContinuousLegend() )
574 {
575 // for interpolated shaders we use a ramp legend node
576 if ( !shader.colorRampItemList().isEmpty() )
577 {
578 nodes << new QgsColorRampLegendNode( nodeLayer, shader.createColorRamp(),
580 shader.minimumValue(),
581 shader.maximumValue(),
582 nullptr,
583 QStringLiteral( "scalarLegend" ),
584 scalarNameKey );
585 }
586 break;
587 }
588 [[fallthrough]];
591 {
592 // for all others we use itemised lists
593 QgsLegendColorList items;
594 settings.colorRampShader().legendSymbologyItems( items );
595 for ( const QPair< QString, QColor > &item : items )
596 {
597 nodes << new QgsRasterSymbolLegendNode( nodeLayer, item.second, item.first, nullptr, false,
598 QStringLiteral( "scalarLegend" ) + QUuid::createUuid().toString(),
599 scalarNameKey
600 );
601 }
602 break;
603 }
604 }
605 }
606
607 if ( indexVector > -1 )
608 {
609 const QgsMeshRendererVectorSettings settings = rendererSettings.vectorSettings( indexVector );
610 const QString vectorNameKey = QStringLiteral( "vectorName" );
611 switch ( settings.coloringMethod() )
612 {
614 {
615 const QColor arrowColor = settings.color();
616 const QIcon vectorIcon = QgsApplication::getThemeIcon( QStringLiteral( "/propertyicons/meshvectors.svg" ), arrowColor, arrowColor );
617 nodes << new QgsSimpleLegendNode( nodeLayer, mLayer->datasetGroupMetadata( indexVector ).name(),
618 vectorIcon, nullptr, vectorNameKey );
619 break;
620 }
622 {
623 const QIcon vectorIcon = QgsApplication::getThemeIcon( QStringLiteral( "/propertyicons/meshvectors.svg" ) );
624 nodes << new QgsSimpleLegendNode( nodeLayer, mLayer->datasetGroupMetadata( indexVector ).name(),
625 vectorIcon, nullptr, vectorNameKey );
626 const QgsColorRampShader shader = settings.colorRampShader();
627 switch ( shader.colorRampType() )
628 {
630 if ( !shader.legendSettings() || shader.legendSettings()->useContinuousLegend() )
631 {
632 // for interpolated shaders we use a ramp legend node
633 if ( !shader.colorRampItemList().isEmpty() )
634 {
635 nodes << new QgsColorRampLegendNode( nodeLayer, shader.createColorRamp(),
637 shader.minimumValue(),
638 shader.maximumValue(),
639 nullptr,
640 QStringLiteral( "vectorLegend" ),
641 vectorNameKey );
642 }
643 break;
644 }
645 [[fallthrough]];
648 {
649 // for all others we use itemised lists
650 QgsLegendColorList items;
651 settings.colorRampShader().legendSymbologyItems( items );
652 for ( const QPair< QString, QColor > &item : items )
653 {
654 nodes << new QgsRasterSymbolLegendNode( nodeLayer, item.second, item.first, nullptr, false,
655 QStringLiteral( "vectorLegend" ) + QUuid::createUuid().toString(),
656 vectorNameKey
657 );
658 }
659 break;
660 }
661 break;
662 }
663 }
664 }
665 }
666
667 return nodes;
668}
669
670//
671// QgsDefaultPointCloudLayerLegend
672//
673
679
681{
682 QgsPointCloudRenderer *renderer = mLayer->renderer();
683 if ( !renderer )
684 return QList<QgsLayerTreeModelLegendNode *>();
685
686 return renderer->createLegendNodes( nodeLayer );
687}
QFlags< MapLayerLegendFlag > MapLayerLegendFlags
Map layer legend flags.
Definition qgis.h:4564
@ Exact
Assigns the color of the exact matching value in the color ramp item list.
Definition qgis.h:1428
@ Linear
Interpolates the color between two class breaks linearly.
Definition qgis.h:1426
@ Discrete
Assigns the color of the higher class for every pixel between two class breaks.
Definition qgis.h:1427
@ ExcludeByDefault
If set, the layer should not be included in legends by default, and must be manually added by a user.
Definition qgis.h:4555
Abstract base class - its implementations define different approaches to the labeling of a vector lay...
virtual QStringList subProviders() const
Gets list of sub-providers within the layer's labeling.
virtual QgsPalLayerSettings settings(const QString &providerId=QString()) const =0
Gets associated label settings.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
Settings for a color ramp legend node.
bool useContinuousLegend() const
Returns true if a continuous gradient legend will be used.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads settings from an XML element.
void writeXml(QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context) const
Writes settings to an XML element.
A legend node which renders a color ramp.
A ramp shader will color a raster pixel based on a list of values ranges in a ramp.
void legendSymbologyItems(QList< QPair< QString, QColor > > &symbolItems) const override
Returns legend symbology items if provided by renderer.
Qgis::ShaderInterpolationMethod colorRampType() const
Returns the color ramp interpolation method.
const QgsColorRampLegendNodeSettings * legendSettings() const
Returns the color ramp shader legend settings.
QList< QgsColorRampShader::ColorRampItem > colorRampItemList() const
Returns the custom color map.
QgsColorRamp * createColorRamp() const
Creates a gradient color ramp from shader settings.
Default legend implementation for mesh layers.
QgsDefaultMeshLayerLegend(QgsMeshLayer *ml)
Creates an instance for the given mesh layer.
QList< QgsLayerTreeModelLegendNode * > createLayerTreeModelLegendNodes(QgsLayerTreeLayer *nodeLayer) override
Returns list of legend nodes to be used for a particular layer tree layer node.
Default legend implementation for point cloud layers.
QList< QgsLayerTreeModelLegendNode * > createLayerTreeModelLegendNodes(QgsLayerTreeLayer *nodeLayer) override
Returns list of legend nodes to be used for a particular layer tree layer node.
QgsDefaultPointCloudLayerLegend(QgsPointCloudLayer *layer)
Creates an instance for the given point cloud layer.
Default legend implementation for raster layers.
QgsDefaultRasterLayerLegend(QgsRasterLayer *rl)
QList< QgsLayerTreeModelLegendNode * > createLayerTreeModelLegendNodes(QgsLayerTreeLayer *nodeLayer) override
Returns list of legend nodes to be used for a particular layer tree layer node.
Default legend implementation for vector layers.
QList< QgsLayerTreeModelLegendNode * > createLayerTreeModelLegendNodes(QgsLayerTreeLayer *nodeLayer) override
Returns list of legend nodes to be used for a particular layer tree layer node.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const override
Writes configuration to a DOM element, to be used later with readXml().
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
Reads configuration from a DOM element previously written by writeXml().
QgsDefaultVectorLayerLegend(QgsVectorLayer *vl)
Abstract base class for all 2D vector feature renderers.
virtual QList< QgsLayerTreeModelLegendNode * > createLegendNodes(QgsLayerTreeLayer *nodeLayer) const
Returns a list of legend nodes to be used for the legend for the renderer.
virtual QString legendClassificationAttribute() const
If supported by the renderer, return classification attribute for the use in legend.
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache, bool blocking=false, double targetDpi=96, int frameNumber=-1, bool *isMissing=nullptr)
Returns the specified path rendered as an image.
Implementation of legend node interface for displaying arbitrary raster images.
@ ColorRamp
Render with a color ramp.
@ SingleColor
Render with a single color.
Layer tree node points to a map layer.
QString name() const override
Returns the layer's name.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
An abstract interface for legend items returned from QgsMapLayerLegend implementation.
virtual QVariant data(int role) const =0
Returns data associated with the item. Must be implemented in derived class.
virtual void setColumnBreak(bool breakBeforeNode)
Sets whether a forced column break should occur before the node.
virtual void setUserPatchSize(QSizeF size)
Sets the user (overridden) size for the legend node.
virtual void setUserLabel(const QString &userLabel)
void setCustomProperty(const QString &key, const QVariant &value)
Sets a custom property for the node. Properties are stored in a map and saved in project file.
void removeCustomProperty(const QString &key)
Remove a custom property from layer. Properties are stored in a map and saved in project file.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer. Properties are stored in a map and saved in project file.
QStringList customProperties() const
Returns list of keys stored in custom properties.
Represents a patch shape for use in map legends.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Read settings from a DOM element.
void writeXml(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
static void setLegendNodeOrder(QgsLayerTreeLayer *nodeLayer, const QList< int > &order)
static std::unique_ptr< QgsSymbol > legendNodeCustomSymbol(QgsLayerTreeLayer *nodeLayer, int originalIndex)
Returns the custom legend symbol for the legend node belonging to nodeLayer at the specified original...
static void setLegendNodeColorRampSettings(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsColorRampLegendNodeSettings *settings)
Sets a custom legend color ramp settings for the legend node belonging to nodeLayer at the specified ...
static void setLegendNodeCustomSymbol(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsSymbol *symbol)
Sets a custom legend symbol for the legend node belonging to nodeLayer at the specified originalIndex...
static QString legendNodeUserLabel(QgsLayerTreeLayer *nodeLayer, int originalIndex)
static QSizeF legendNodeSymbolSize(QgsLayerTreeLayer *nodeLayer, int originalIndex)
Returns the legend node symbol size for the legend node belonging to nodeLayer at the specified origi...
static bool hasLegendNodeUserLabel(QgsLayerTreeLayer *nodeLayer, int originalIndex)
static bool legendNodeColumnBreak(QgsLayerTreeLayer *nodeLayer, int originalIndex)
Returns whether a forced column break should occur before the node.
static bool hasLegendNodeOrder(QgsLayerTreeLayer *nodeLayer)
static void setLegendNodeUserLabel(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QString &newLabel)
static void setLegendNodeSymbolSize(QgsLayerTreeLayer *nodeLayer, int originalIndex, QSizeF size)
Sets the legend symbol size for the legend node belonging to nodeLayer at the specified originalIndex...
static QgsColorRampLegendNodeSettings * legendNodeColorRampSettings(QgsLayerTreeLayer *nodeLayer, int originalIndex)
Returns the custom legend color ramp settings for the legend node belonging to nodeLayer at the speci...
static void setLegendNodeColumnBreak(QgsLayerTreeLayer *nodeLayer, int originalIndex, bool columnBreakBeforeNode)
Sets whether a forced column break should occur before the node.
static void setLegendNodePatchShape(QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsLegendPatchShape &shape)
Sets the legend patch shape for the legend node belonging to nodeLayer at the specified originalIndex...
static QList< int > legendNodeOrder(QgsLayerTreeLayer *nodeLayer)
static void applyLayerNodeProperties(QgsLayerTreeLayer *nodeLayer, QList< QgsLayerTreeModelLegendNode * > &nodes)
update according to layer node's custom properties (order of items, user labels for items)
static QgsLegendPatchShape legendNodePatchShape(QgsLayerTreeLayer *nodeLayer, int originalIndex)
Returns the legend patch shape for the legend node belonging to nodeLayer at the specified originalIn...
virtual void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Reads configuration from a DOM element previously written by writeXml().
static QgsMapLayerLegend * defaultMeshLegend(QgsMeshLayer *ml)
Create new legend implementation for mesh layer.
static QgsMapLayerLegend * defaultPointCloudLegend(QgsPointCloudLayer *layer)
Create new legend implementation for a point cloud layer.
QgsMapLayerLegend(QObject *parent=nullptr)
Constructor for QgsMapLayerLegend.
virtual QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Writes configuration to a DOM element, to be used later with readXml().
static QgsMapLayerLegend * defaultRasterLegend(QgsRasterLayer *rl)
Create new legend implementation for raster layer.
static QgsMapLayerLegend * defaultVectorLegend(QgsVectorLayer *vl)
Create new legend implementation for vector layer.
virtual QList< QgsLayerTreeModelLegendNode * > createLayerTreeModelLegendNodes(QgsLayerTreeLayer *nodeLayer)=0
Returns list of legend nodes to be used for a particular layer tree layer node.
void itemsChanged()
Emitted when existing items/nodes got invalid and should be replaced by new ones.
QgsMapLayerLegend * legend() const
Can be nullptr.
void rendererChanged()
Signal emitted when renderer is changed.
void nameChanged()
Emitted when the name has been changed.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Represents a mesh renderer settings for scalar datasets.
QgsColorRampShader colorRampShader() const
Returns color ramp shader function.
Represents all mesh renderer settings.
QgsMeshRendererScalarSettings scalarSettings(int groupIndex) const
Returns renderer settings.
int activeVectorDatasetGroup() const
Returns the active vector dataset group.
int activeScalarDatasetGroup() const
Returns the active scalar dataset group.
QgsMeshRendererVectorSettings vectorSettings(int groupIndex) const
Returns renderer settings.
Represents a renderer settings for vector datasets.
QColor color() const
Returns color used for drawing arrows.
QgsColorRampShader colorRampShader() const
Sets the color ramp shader used to render vector datasets.
QgsInterpolatedLineColor::ColoringMethod coloringMethod() const
Returns the coloring method used to render vector datasets.
Contains settings for how a map layer will be labeled.
Represents a map layer supporting display of point clouds.
Abstract base class for 2d point cloud renderers.
virtual QList< QgsLayerTreeModelLegendNode * > createLegendNodes(QgsLayerTreeLayer *nodeLayer)
Creates a set of legend nodes representing the renderer.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Represents a raster layer.
double maximumValue() const
Returns the minimum value for the raster shader.
double minimumValue() const
Returns the maximum value for the raster shader.
Implementation of legend node interface for displaying raster legend entries.
A container for the context for various read/write operations on objects.
void setPathResolver(const QgsPathResolver &resolver)
Sets up path resolver for conversion between relative and absolute paths.
A child rule for QgsRuleBasedLabeling.
const QgsRuleBasedLabeling::Rule * findRuleByKey(const QString &key) const
Try to find a rule given its unique key.
QString description() const
A human readable description for this rule.
Rule based labeling for a vector layer.
QgsRuleBasedLabeling::Rule * rootRule()
Stores settings for use within QGIS.
Definition qgssettings.h:65
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Implementation of legend node interface for displaying arbitrary labels with icons.
static std::unique_ptr< QgsSymbol > loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
static QString encodeSize(QSizeF size)
Encodes a QSizeF to a string.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
static QSizeF decodeSize(const QString &string)
Decodes a QSizeF from a string.
Implementation of legend node interface for displaying preview of vector symbols and their labels and...
Abstract base class for all rendered symbols.
Definition qgssymbol.h:231
Container for all settings relating to text rendering.
A legend node for a labeling text symbol.
Represents a vector layer which manages a vector based dataset.
Implementation of legend node interface for displaying WMS legend entries.
#define QgsDebugError(str)
Definition qgslogger.h:57
QList< QPair< QString, QColor > > QgsLegendColorList