Branch data Line data Source code
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 : :
18 : : #include "qgssettings.h"
19 : : #include "qgslayertree.h"
20 : : #include "qgslayertreemodellegendnode.h"
21 : : #include "qgsmeshlayer.h"
22 : : #include "qgspluginlayer.h"
23 : : #include "qgsrasterlayer.h"
24 : : #include "qgsrenderer.h"
25 : : #include "qgsvectorlayer.h"
26 : : #include "qgspointcloudlayer.h"
27 : : #include "qgsdiagramrenderer.h"
28 : : #include "qgssymbollayerutils.h"
29 : : #include "qgspointcloudrenderer.h"
30 : : #include "qgsrasterrenderer.h"
31 : : #include "qgscolorramplegendnode.h"
32 : :
33 : 78 : QgsMapLayerLegend::QgsMapLayerLegend( QObject *parent )
34 : 78 : : QObject( parent )
35 : 156 : {
36 : 78 : }
37 : :
38 : 0 : void QgsMapLayerLegend::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
39 : : {
40 : 0 : Q_UNUSED( elem )
41 : 0 : Q_UNUSED( context )
42 : 0 : }
43 : :
44 : 0 : QDomElement QgsMapLayerLegend::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
45 : : {
46 : 0 : Q_UNUSED( doc )
47 : 0 : Q_UNUSED( context )
48 : 0 : return QDomElement();
49 : : }
50 : :
51 : 78 : QgsMapLayerLegend *QgsMapLayerLegend::defaultVectorLegend( QgsVectorLayer *vl )
52 : : {
53 : 78 : return new QgsDefaultVectorLayerLegend( vl );
54 : 0 : }
55 : :
56 : 0 : QgsMapLayerLegend *QgsMapLayerLegend::defaultRasterLegend( QgsRasterLayer *rl )
57 : : {
58 : 0 : return new QgsDefaultRasterLayerLegend( rl );
59 : 0 : }
60 : :
61 : 0 : QgsMapLayerLegend *QgsMapLayerLegend::defaultMeshLegend( QgsMeshLayer *ml )
62 : : {
63 : 0 : return new QgsDefaultMeshLayerLegend( ml );
64 : 0 : }
65 : :
66 : 0 : QgsMapLayerLegend *QgsMapLayerLegend::defaultPointCloudLegend( QgsPointCloudLayer *layer )
67 : : {
68 : 0 : return new QgsDefaultPointCloudLayerLegend( layer );
69 : 0 : }
70 : :
71 : : // -------------------------------------------------------------------------
72 : :
73 : :
74 : 0 : void QgsMapLayerLegendUtils::setLegendNodeOrder( QgsLayerTreeLayer *nodeLayer, const QList<int> &order )
75 : : {
76 : 0 : QStringList orderStr;
77 : 0 : const auto constOrder = order;
78 : 0 : for ( int id : constOrder )
79 : 0 : orderStr << QString::number( id );
80 : 0 : QString str = orderStr.isEmpty() ? QStringLiteral( "empty" ) : orderStr.join( QLatin1Char( ',' ) );
81 : :
82 : 0 : nodeLayer->setCustomProperty( QStringLiteral( "legend/node-order" ), str );
83 : 0 : }
84 : :
85 : 0 : static int _originalLegendNodeCount( QgsLayerTreeLayer *nodeLayer )
86 : : {
87 : : // this is not particularly efficient way of finding out number of legend nodes
88 : 0 : QList<QgsLayerTreeModelLegendNode *> lst = nodeLayer->layer()->legend()->createLayerTreeModelLegendNodes( nodeLayer );
89 : 0 : int numNodes = lst.count();
90 : 0 : qDeleteAll( lst );
91 : 0 : return numNodes;
92 : 0 : }
93 : :
94 : 0 : static QList<int> _makeNodeOrder( QgsLayerTreeLayer *nodeLayer )
95 : : {
96 : 0 : if ( !nodeLayer->layer() || !nodeLayer->layer()->legend() )
97 : : {
98 : 0 : QgsDebugMsg( QStringLiteral( "Legend node order manipulation is invalid without existing legend" ) );
99 : 0 : return QList<int>();
100 : : }
101 : :
102 : 0 : int numNodes = _originalLegendNodeCount( nodeLayer );
103 : :
104 : 0 : QList<int> order;
105 : 0 : order.reserve( numNodes );
106 : 0 : for ( int i = 0; i < numNodes; ++i )
107 : 0 : order << i;
108 : 0 : return order;
109 : 0 : }
110 : :
111 : 0 : QList<int> QgsMapLayerLegendUtils::legendNodeOrder( QgsLayerTreeLayer *nodeLayer )
112 : : {
113 : 0 : QString orderStr = nodeLayer->customProperty( QStringLiteral( "legend/node-order" ) ).toString();
114 : :
115 : 0 : if ( orderStr.isEmpty() )
116 : 0 : return _makeNodeOrder( nodeLayer );
117 : :
118 : 0 : if ( orderStr == QLatin1String( "empty" ) )
119 : 0 : return QList<int>();
120 : :
121 : 0 : int numNodes = _originalLegendNodeCount( nodeLayer );
122 : :
123 : 0 : QList<int> lst;
124 : 0 : const auto constSplit = orderStr.split( ',' );
125 : 0 : for ( const QString &item : constSplit )
126 : : {
127 : : bool ok;
128 : 0 : int id = item.toInt( &ok );
129 : 0 : if ( !ok || id < 0 || id >= numNodes )
130 : 0 : return _makeNodeOrder( nodeLayer );
131 : :
132 : 0 : lst << id;
133 : : }
134 : :
135 : 0 : return lst;
136 : 0 : }
137 : :
138 : 0 : bool QgsMapLayerLegendUtils::hasLegendNodeOrder( QgsLayerTreeLayer *nodeLayer )
139 : : {
140 : 0 : return nodeLayer->customProperties().contains( QStringLiteral( "legend/node-order" ) );
141 : 0 : }
142 : :
143 : 0 : void QgsMapLayerLegendUtils::setLegendNodeUserLabel( QgsLayerTreeLayer *nodeLayer, int originalIndex, const QString &newLabel )
144 : : {
145 : 0 : nodeLayer->setCustomProperty( "legend/label-" + QString::number( originalIndex ), newLabel );
146 : 0 : }
147 : :
148 : 0 : QString QgsMapLayerLegendUtils::legendNodeUserLabel( QgsLayerTreeLayer *nodeLayer, int originalIndex )
149 : : {
150 : 0 : return nodeLayer->customProperty( "legend/label-" + QString::number( originalIndex ) ).toString();
151 : 0 : }
152 : :
153 : 0 : bool QgsMapLayerLegendUtils::hasLegendNodeUserLabel( QgsLayerTreeLayer *nodeLayer, int originalIndex )
154 : : {
155 : 0 : return nodeLayer->customProperties().contains( "legend/label-" + QString::number( originalIndex ) );
156 : 0 : }
157 : :
158 : 0 : void QgsMapLayerLegendUtils::setLegendNodePatchShape( QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsLegendPatchShape &shape )
159 : : {
160 : 0 : QDomDocument patchDoc;
161 : 0 : QDomElement patchElem = patchDoc.createElement( QStringLiteral( "patch" ) );
162 : 0 : shape.writeXml( patchElem, patchDoc, QgsReadWriteContext() );
163 : 0 : patchDoc.appendChild( patchElem );
164 : 0 : nodeLayer->setCustomProperty( "legend/patch-shape-" + QString::number( originalIndex ), patchDoc.toString() );
165 : 0 : }
166 : :
167 : 0 : QgsLegendPatchShape QgsMapLayerLegendUtils::legendNodePatchShape( QgsLayerTreeLayer *nodeLayer, int originalIndex )
168 : : {
169 : 0 : QString patchDef = nodeLayer->customProperty( "legend/patch-shape-" + QString::number( originalIndex ) ).toString();
170 : 0 : if ( patchDef.isEmpty() )
171 : 0 : return QgsLegendPatchShape();
172 : :
173 : 0 : QDomDocument doc( QStringLiteral( "patch" ) );
174 : 0 : doc.setContent( patchDef );
175 : 0 : QgsLegendPatchShape shape;
176 : 0 : shape.readXml( doc.documentElement(), QgsReadWriteContext() );
177 : 0 : return shape;
178 : 0 : }
179 : :
180 : 0 : void QgsMapLayerLegendUtils::setLegendNodeSymbolSize( QgsLayerTreeLayer *nodeLayer, int originalIndex, QSizeF size )
181 : : {
182 : 0 : if ( size.isValid() )
183 : 0 : nodeLayer->setCustomProperty( "legend/symbol-size-" + QString::number( originalIndex ), QgsSymbolLayerUtils::encodeSize( size ) );
184 : : else
185 : 0 : nodeLayer->removeCustomProperty( "legend/symbol-size-" + QString::number( originalIndex ) );
186 : 0 : }
187 : :
188 : 0 : QSizeF QgsMapLayerLegendUtils::legendNodeSymbolSize( QgsLayerTreeLayer *nodeLayer, int originalIndex )
189 : : {
190 : 0 : const QString size = nodeLayer->customProperty( "legend/symbol-size-" + QString::number( originalIndex ) ).toString();
191 : 0 : if ( size.isEmpty() )
192 : 0 : return QSizeF();
193 : : else
194 : 0 : return QgsSymbolLayerUtils::decodeSize( size );
195 : 0 : }
196 : :
197 : 0 : void QgsMapLayerLegendUtils::setLegendNodeCustomSymbol( QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsSymbol *symbol )
198 : : {
199 : 0 : if ( symbol )
200 : : {
201 : 0 : QDomDocument doc;
202 : 0 : QgsReadWriteContext rwContext;
203 : 0 : rwContext.setPathResolver( QgsProject::instance()->pathResolver() );
204 : 0 : QDomElement elem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "custom symbol" ), symbol, doc, rwContext );
205 : 0 : doc.appendChild( elem );
206 : 0 : nodeLayer->setCustomProperty( "legend/custom-symbol-" + QString::number( originalIndex ), doc.toString() );
207 : 0 : }
208 : : else
209 : 0 : nodeLayer->removeCustomProperty( "legend/custom-symbol-" + QString::number( originalIndex ) );
210 : 0 : }
211 : :
212 : 0 : QgsSymbol *QgsMapLayerLegendUtils::legendNodeCustomSymbol( QgsLayerTreeLayer *nodeLayer, int originalIndex )
213 : : {
214 : 0 : const QString symbolDef = nodeLayer->customProperty( "legend/custom-symbol-" + QString::number( originalIndex ) ).toString();
215 : 0 : if ( symbolDef.isEmpty() )
216 : 0 : return nullptr;
217 : :
218 : 0 : QDomDocument doc;
219 : 0 : doc.setContent( symbolDef );
220 : 0 : const QDomElement elem = doc.documentElement();
221 : :
222 : 0 : QgsReadWriteContext rwContext;
223 : 0 : rwContext.setPathResolver( QgsProject::instance()->pathResolver() );
224 : :
225 : 0 : return QgsSymbolLayerUtils::loadSymbol( elem, rwContext );
226 : 0 : }
227 : :
228 : 0 : void QgsMapLayerLegendUtils::setLegendNodeColorRampSettings( QgsLayerTreeLayer *nodeLayer, int originalIndex, const QgsColorRampLegendNodeSettings *settings )
229 : : {
230 : 0 : if ( settings )
231 : : {
232 : 0 : QDomDocument doc;
233 : 0 : QgsReadWriteContext rwContext;
234 : 0 : rwContext.setPathResolver( QgsProject::instance()->pathResolver() );
235 : 0 : QDomElement elem = doc.createElement( QStringLiteral( "rampSettings" ) );
236 : 0 : settings->writeXml( doc, elem, rwContext );
237 : 0 : doc.appendChild( elem );
238 : 0 : nodeLayer->setCustomProperty( "legend/custom-ramp-settings-" + QString::number( originalIndex ), doc.toString() );
239 : 0 : }
240 : : else
241 : 0 : nodeLayer->removeCustomProperty( "legend/custom-ramp-settings-" + QString::number( originalIndex ) );
242 : 0 : }
243 : :
244 : 0 : QgsColorRampLegendNodeSettings *QgsMapLayerLegendUtils::legendNodeColorRampSettings( QgsLayerTreeLayer *nodeLayer, int originalIndex )
245 : : {
246 : 0 : const QString settingsDef = nodeLayer->customProperty( "legend/custom-ramp-settings-" + QString::number( originalIndex ) ).toString();
247 : 0 : if ( settingsDef.isEmpty() )
248 : 0 : return nullptr;
249 : :
250 : 0 : QDomDocument doc;
251 : 0 : doc.setContent( settingsDef );
252 : 0 : const QDomElement elem = doc.documentElement();
253 : :
254 : 0 : QgsReadWriteContext rwContext;
255 : 0 : rwContext.setPathResolver( QgsProject::instance()->pathResolver() );
256 : :
257 : 0 : QgsColorRampLegendNodeSettings settings;
258 : 0 : settings.readXml( elem, rwContext );
259 : 0 : return new QgsColorRampLegendNodeSettings( settings );
260 : 0 : }
261 : :
262 : 0 : void QgsMapLayerLegendUtils::setLegendNodeColumnBreak( QgsLayerTreeLayer *nodeLayer, int originalIndex, bool columnBreakBeforeNode )
263 : : {
264 : 0 : if ( columnBreakBeforeNode )
265 : 0 : nodeLayer->setCustomProperty( "legend/column-break-" + QString::number( originalIndex ), QStringLiteral( "1" ) );
266 : : else
267 : 0 : nodeLayer->removeCustomProperty( "legend/column-break-" + QString::number( originalIndex ) );
268 : 0 : }
269 : :
270 : 0 : bool QgsMapLayerLegendUtils::legendNodeColumnBreak( QgsLayerTreeLayer *nodeLayer, int originalIndex )
271 : : {
272 : 0 : return nodeLayer->customProperty( "legend/column-break-" + QString::number( originalIndex ) ).toInt();
273 : 0 : }
274 : :
275 : 0 : void QgsMapLayerLegendUtils::applyLayerNodeProperties( QgsLayerTreeLayer *nodeLayer, QList<QgsLayerTreeModelLegendNode *> &nodes )
276 : : {
277 : : // handle user labels
278 : 0 : int i = 0;
279 : 0 : const auto constNodes = nodes;
280 : 0 : for ( QgsLayerTreeModelLegendNode *legendNode : constNodes )
281 : : {
282 : 0 : QString userLabel = QgsMapLayerLegendUtils::legendNodeUserLabel( nodeLayer, i );
283 : 0 : if ( !userLabel.isNull() )
284 : 0 : legendNode->setUserLabel( userLabel );
285 : :
286 : 0 : if ( QgsSymbolLegendNode *symbolNode = dynamic_cast< QgsSymbolLegendNode * >( legendNode ) )
287 : : {
288 : 0 : const QgsLegendPatchShape shape = QgsMapLayerLegendUtils::legendNodePatchShape( nodeLayer, i );
289 : 0 : symbolNode->setPatchShape( shape );
290 : :
291 : 0 : symbolNode->setCustomSymbol( QgsMapLayerLegendUtils::legendNodeCustomSymbol( nodeLayer, i ) );
292 : 0 : }
293 : 78 : else if ( QgsColorRampLegendNode *colorRampNode = dynamic_cast< QgsColorRampLegendNode * >( legendNode ) )
294 : : {
295 : 0 : std::unique_ptr< QgsColorRampLegendNodeSettings > settings( QgsMapLayerLegendUtils::legendNodeColorRampSettings( nodeLayer, i ) );
296 : 0 : if ( settings )
297 : : {
298 : 0 : colorRampNode->setSettings( *settings );
299 : 0 : }
300 : 0 : }
301 : :
302 : 0 : const QSizeF userSize = QgsMapLayerLegendUtils::legendNodeSymbolSize( nodeLayer, i );
303 : 0 : if ( userSize.isValid() )
304 : : {
305 : 0 : legendNode->setUserPatchSize( userSize );
306 : 0 : }
307 : :
308 : 0 : if ( legendNodeColumnBreak( nodeLayer, i ) )
309 : 0 : legendNode->setColumnBreak( true );
310 : :
311 : 0 : i++;
312 : 0 : }
313 : :
314 : : // handle user order of nodes
315 : 0 : if ( QgsMapLayerLegendUtils::hasLegendNodeOrder( nodeLayer ) )
316 : : {
317 : 0 : QList<int> order = QgsMapLayerLegendUtils::legendNodeOrder( nodeLayer );
318 : :
319 : 0 : QList<QgsLayerTreeModelLegendNode *> newOrder;
320 : 0 : QSet<int> usedIndices;
321 : 0 : const auto constOrder = order;
322 : 0 : for ( int idx : constOrder )
323 : : {
324 : 0 : if ( usedIndices.contains( idx ) )
325 : : {
326 : 0 : QgsDebugMsg( QStringLiteral( "invalid node order. ignoring." ) );
327 : 0 : return;
328 : : }
329 : :
330 : 0 : newOrder << nodes[idx];
331 : 0 : usedIndices << idx;
332 : : }
333 : :
334 : : // delete unused nodes
335 : 0 : for ( int i = 0; i < nodes.count(); ++i )
336 : : {
337 : 0 : if ( !usedIndices.contains( i ) )
338 : 0 : delete nodes[i];
339 : 0 : }
340 : :
341 : 0 : nodes = newOrder;
342 : 0 : }
343 : :
344 : 0 : }
345 : :
346 : : // -------------------------------------------------------------------------
347 : :
348 : :
349 : 78 : QgsDefaultVectorLayerLegend::QgsDefaultVectorLayerLegend( QgsVectorLayer *vl )
350 : 78 : : mLayer( vl )
351 : 156 : {
352 : 78 : connect( mLayer, &QgsMapLayer::rendererChanged, this, &QgsMapLayerLegend::itemsChanged );
353 : 78 : connect( mLayer, &QgsMapLayer::nameChanged, this, &QgsMapLayerLegend::itemsChanged );
354 : 78 : }
355 : :
356 : 0 : QList<QgsLayerTreeModelLegendNode *> QgsDefaultVectorLayerLegend::createLayerTreeModelLegendNodes( QgsLayerTreeLayer *nodeLayer )
357 : : {
358 : 0 : QList<QgsLayerTreeModelLegendNode *> nodes;
359 : :
360 : 0 : QgsFeatureRenderer *r = mLayer->renderer();
361 : 0 : if ( !r )
362 : 0 : return nodes;
363 : :
364 : 0 : if ( nodeLayer->customProperty( QStringLiteral( "showFeatureCount" ), 0 ).toBool() )
365 : 0 : mLayer->countSymbolFeatures();
366 : :
367 : 0 : QgsSettings settings;
368 : 0 : if ( settings.value( QStringLiteral( "qgis/showLegendClassifiers" ), false ).toBool() && !r->legendClassificationAttribute().isEmpty() )
369 : : {
370 : 0 : nodes.append( new QgsSimpleLegendNode( nodeLayer, r->legendClassificationAttribute() ) );
371 : 0 : }
372 : :
373 : 0 : const auto constLegendSymbolItems = r->legendSymbolItems();
374 : 0 : for ( const QgsLegendSymbolItem &i : constLegendSymbolItems )
375 : : {
376 : 0 : if ( auto *lDataDefinedSizeLegendSettings = i.dataDefinedSizeLegendSettings() )
377 : 0 : nodes << new QgsDataDefinedSizeLegendNode( nodeLayer, *lDataDefinedSizeLegendSettings );
378 : : else
379 : : {
380 : 0 : QgsSymbolLegendNode *legendNode = new QgsSymbolLegendNode( nodeLayer, i );
381 : 0 : if ( mTextOnSymbolEnabled && mTextOnSymbolContent.contains( i.ruleKey() ) )
382 : : {
383 : 0 : legendNode->setTextOnSymbolLabel( mTextOnSymbolContent.value( i.ruleKey() ) );
384 : 0 : legendNode->setTextOnSymbolTextFormat( mTextOnSymbolTextFormat );
385 : 0 : }
386 : 0 : nodes << legendNode;
387 : : }
388 : : }
389 : :
390 : 0 : if ( nodes.count() == 1 && nodes[0]->data( Qt::EditRole ).toString().isEmpty() )
391 : 0 : nodes[0]->setEmbeddedInParent( true );
392 : :
393 : :
394 : 0 : if ( mLayer->diagramsEnabled() )
395 : : {
396 : 0 : const auto constLegendItems = mLayer->diagramRenderer()->legendItems( nodeLayer );
397 : 0 : for ( QgsLayerTreeModelLegendNode *i : constLegendItems )
398 : : {
399 : 0 : nodes.append( i );
400 : : }
401 : 0 : }
402 : :
403 : :
404 : 0 : return nodes;
405 : 0 : }
406 : :
407 : 0 : void QgsDefaultVectorLayerLegend::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
408 : : {
409 : 0 : mTextOnSymbolEnabled = false;
410 : 0 : mTextOnSymbolTextFormat = QgsTextFormat();
411 : 0 : mTextOnSymbolContent.clear();
412 : :
413 : 0 : QDomElement tosElem = elem.firstChildElement( QStringLiteral( "text-on-symbol" ) );
414 : 0 : if ( !tosElem.isNull() )
415 : : {
416 : 0 : mTextOnSymbolEnabled = true;
417 : 0 : QDomElement tosFormatElem = tosElem.firstChildElement( QStringLiteral( "text-style" ) );
418 : 0 : mTextOnSymbolTextFormat.readXml( tosFormatElem, context );
419 : 0 : QDomElement tosContentElem = tosElem.firstChildElement( QStringLiteral( "content" ) );
420 : 0 : QDomElement tosContentItemElem = tosContentElem.firstChildElement( QStringLiteral( "item" ) );
421 : 0 : while ( !tosContentItemElem.isNull() )
422 : : {
423 : 0 : mTextOnSymbolContent.insert( tosContentItemElem.attribute( QStringLiteral( "key" ) ), tosContentItemElem.attribute( QStringLiteral( "value" ) ) );
424 : 0 : tosContentItemElem = tosContentItemElem.nextSiblingElement( QStringLiteral( "item" ) );
425 : : }
426 : 0 : }
427 : 0 : }
428 : :
429 : 0 : QDomElement QgsDefaultVectorLayerLegend::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
430 : : {
431 : 0 : QDomElement elem = doc.createElement( QStringLiteral( "legend" ) );
432 : 0 : elem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "default-vector" ) );
433 : :
434 : 0 : if ( mTextOnSymbolEnabled )
435 : : {
436 : 0 : QDomElement tosElem = doc.createElement( QStringLiteral( "text-on-symbol" ) );
437 : 0 : QDomElement tosFormatElem = mTextOnSymbolTextFormat.writeXml( doc, context );
438 : 0 : tosElem.appendChild( tosFormatElem );
439 : 0 : QDomElement tosContentElem = doc.createElement( QStringLiteral( "content" ) );
440 : 0 : for ( auto it = mTextOnSymbolContent.constBegin(); it != mTextOnSymbolContent.constEnd(); ++it )
441 : : {
442 : 0 : QDomElement tosContentItemElem = doc.createElement( QStringLiteral( "item" ) );
443 : 0 : tosContentItemElem.setAttribute( QStringLiteral( "key" ), it.key() );
444 : 0 : tosContentItemElem.setAttribute( QStringLiteral( "value" ), it.value() );
445 : 0 : tosContentElem.appendChild( tosContentItemElem );
446 : 0 : }
447 : 0 : tosElem.appendChild( tosContentElem );
448 : 0 : elem.appendChild( tosElem );
449 : 0 : }
450 : :
451 : 0 : return elem;
452 : 0 : }
453 : :
454 : :
455 : : // -------------------------------------------------------------------------
456 : :
457 : :
458 : 0 : QgsDefaultRasterLayerLegend::QgsDefaultRasterLayerLegend( QgsRasterLayer *rl )
459 : 0 : : mLayer( rl )
460 : 0 : {
461 : 0 : connect( mLayer, &QgsMapLayer::rendererChanged, this, &QgsMapLayerLegend::itemsChanged );
462 : 0 : }
463 : :
464 : 0 : QList<QgsLayerTreeModelLegendNode *> QgsDefaultRasterLayerLegend::createLayerTreeModelLegendNodes( QgsLayerTreeLayer *nodeLayer )
465 : : {
466 : 0 : QList<QgsLayerTreeModelLegendNode *> nodes;
467 : :
468 : : // temporary solution for WMS. Ideally should be done with a delegate.
469 : 0 : if ( mLayer->dataProvider() && mLayer->dataProvider()->supportsLegendGraphic() )
470 : : {
471 : 0 : nodes << new QgsWmsLegendNode( nodeLayer );
472 : 0 : }
473 : :
474 : 0 : if ( mLayer->renderer() )
475 : 0 : nodes.append( mLayer->renderer()->createLegendNodes( nodeLayer ) );
476 : 0 : return nodes;
477 : 0 : }
478 : :
479 : : // -------------------------------------------------------------------------
480 : :
481 : 0 : QgsDefaultMeshLayerLegend::QgsDefaultMeshLayerLegend( QgsMeshLayer *ml )
482 : 0 : : mLayer( ml )
483 : 0 : {
484 : 0 : connect( mLayer, &QgsMapLayer::rendererChanged, this, &QgsMapLayerLegend::itemsChanged );
485 : 0 : }
486 : :
487 : 0 : QList<QgsLayerTreeModelLegendNode *> QgsDefaultMeshLayerLegend::createLayerTreeModelLegendNodes( QgsLayerTreeLayer *nodeLayer )
488 : : {
489 : 0 : QList<QgsLayerTreeModelLegendNode *> nodes;
490 : :
491 : 0 : QgsMeshDataProvider *provider = mLayer->dataProvider();
492 : 0 : if ( !provider )
493 : 0 : return nodes;
494 : :
495 : 0 : QgsMeshRendererSettings rendererSettings = mLayer->rendererSettings();
496 : :
497 : 0 : int indexScalar = rendererSettings.activeScalarDatasetGroup();
498 : 0 : int indexVector = rendererSettings.activeVectorDatasetGroup();
499 : :
500 : 0 : QString name;
501 : 0 : if ( indexScalar > -1 && indexVector > -1 && indexScalar != indexVector )
502 : 0 : name = QString( "%1 / %2" ).arg( provider->datasetGroupMetadata( indexScalar ).name(), provider->datasetGroupMetadata( indexVector ).name() );
503 : 0 : else if ( indexScalar > -1 )
504 : 0 : name = provider->datasetGroupMetadata( indexScalar ).name();
505 : 0 : else if ( indexVector > -1 )
506 : 0 : name = provider->datasetGroupMetadata( indexVector ).name();
507 : : else
508 : : {
509 : : // neither contours nor vectors get rendered - no legend needed
510 : 0 : return nodes;
511 : : }
512 : :
513 : 0 : nodes << new QgsSimpleLegendNode( nodeLayer, name );
514 : :
515 : 0 : if ( indexScalar > -1 )
516 : : {
517 : 0 : QgsMeshRendererScalarSettings settings = rendererSettings.scalarSettings( indexScalar );
518 : 0 : const QgsColorRampShader shader = settings.colorRampShader();
519 : 0 : switch ( shader.colorRampType() )
520 : : {
521 : : case QgsColorRampShader::Interpolated:
522 : : // for interpolated shaders we use a ramp legend node
523 : 0 : nodes << new QgsColorRampLegendNode( nodeLayer, shader.sourceColorRamp()->clone(),
524 : 0 : shader.legendSettings() ? *shader.legendSettings() : QgsColorRampLegendNodeSettings(),
525 : 0 : shader.minimumValue(),
526 : 0 : shader.maximumValue() );
527 : 0 : break;
528 : :
529 : : case QgsColorRampShader::Discrete:
530 : : case QgsColorRampShader::Exact:
531 : : {
532 : : // for all others we use itemised lists
533 : 0 : QgsLegendColorList items;
534 : 0 : settings.colorRampShader().legendSymbologyItems( items );
535 : 0 : for ( const QPair< QString, QColor > &item : items )
536 : : {
537 : 0 : nodes << new QgsRasterSymbolLegendNode( nodeLayer, item.second, item.first );
538 : : }
539 : : break;
540 : 0 : }
541 : : }
542 : 0 : }
543 : :
544 : 0 : return nodes;
545 : 0 : }
546 : :
547 : : //
548 : : // QgsDefaultPointCloudLayerLegend
549 : : //
550 : :
551 : 0 : QgsDefaultPointCloudLayerLegend::QgsDefaultPointCloudLayerLegend( QgsPointCloudLayer *layer )
552 : 0 : : mLayer( layer )
553 : 0 : {
554 : 0 : connect( mLayer, &QgsMapLayer::rendererChanged, this, &QgsMapLayerLegend::itemsChanged );
555 : 0 : }
556 : :
557 : 0 : QList<QgsLayerTreeModelLegendNode *> QgsDefaultPointCloudLayerLegend::createLayerTreeModelLegendNodes( QgsLayerTreeLayer *nodeLayer )
558 : : {
559 : 0 : QgsPointCloudRenderer *renderer = mLayer->renderer();
560 : 0 : if ( !renderer )
561 : 0 : return QList<QgsLayerTreeModelLegendNode *>();
562 : :
563 : 0 : return renderer->createLegendNodes( nodeLayer );
564 : 0 : }
|