Skip to content

Commit 8fb20f0

Browse files
committedOct 24, 2013
Merge pull request #966 from luipir/SITA3-WmsGetLegendGraphicManagement
WMS getLegendGraphic management in QgsLegend and QgsComposer - Developed with funding from Regione Toscana-SITA
2 parents fc74f66 + f6a6a0c commit 8fb20f0

15 files changed

+598
-36
lines changed
 

‎src/app/composer/qgscomposerlegendwidget.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ void QgsComposerLegendWidget::setGuiElements()
168168
mEqualColumnWidthCheckBox->setChecked( mLegend->equalColumnWidth() );
169169
mSymbolWidthSpinBox->setValue( mLegend->symbolWidth() );
170170
mSymbolHeightSpinBox->setValue( mLegend->symbolHeight() );
171+
mWmsLegendWidthSpinBox->setValue( mLegend->wmsLegendWidth() );
172+
mWmsLegendHeightSpinBox->setValue( mLegend->wmsLegendHeight() );
171173
mTitleSpaceBottomSpinBox->setValue( mLegend->style( QgsComposerLegendStyle::Title ).margin( QgsComposerLegendStyle::Bottom ) );
172174
mGroupSpaceSpinBox->setValue( mLegend->style( QgsComposerLegendStyle::Group ).margin( QgsComposerLegendStyle::Top ) );
173175
mLayerSpaceSpinBox->setValue( mLegend->style( QgsComposerLegendStyle::Subgroup ).margin( QgsComposerLegendStyle::Top ) );
@@ -280,6 +282,30 @@ void QgsComposerLegendWidget::on_mSymbolHeightSpinBox_valueChanged( double d )
280282
}
281283
}
282284

285+
void QgsComposerLegendWidget::on_mWmsLegendWidthSpinBox_valueChanged( double d )
286+
{
287+
if ( mLegend )
288+
{
289+
mLegend->beginCommand( tr( "Wms Legend width" ), QgsComposerMergeCommand::LegendWmsLegendWidth );
290+
mLegend->setWmsLegendWidth( d );
291+
mLegend->adjustBoxSize();
292+
mLegend->update();
293+
mLegend->endCommand();
294+
}
295+
}
296+
297+
void QgsComposerLegendWidget::on_mWmsLegendHeightSpinBox_valueChanged( double d )
298+
{
299+
if ( mLegend )
300+
{
301+
mLegend->beginCommand( tr( "Wms Legend height" ), QgsComposerMergeCommand::LegendWmsLegendHeight );
302+
mLegend->setWmsLegendHeight( d );
303+
mLegend->adjustBoxSize();
304+
mLegend->update();
305+
mLegend->endCommand();
306+
}
307+
}
308+
283309
void QgsComposerLegendWidget::on_mTitleSpaceBottomSpinBox_valueChanged( double d )
284310
{
285311
if ( mLegend )

‎src/app/composer/qgscomposerlegendwidget.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ class QgsComposerLegendWidget: public QWidget, private Ui::QgsComposerLegendWidg
5959
void on_mEqualColumnWidthCheckBox_toggled( bool checked );
6060
void on_mSymbolWidthSpinBox_valueChanged( double d );
6161
void on_mSymbolHeightSpinBox_valueChanged( double d );
62+
void on_mWmsLegendWidthSpinBox_valueChanged( double d );
63+
void on_mWmsLegendHeightSpinBox_valueChanged( double d );
6264
void on_mTitleSpaceBottomSpinBox_valueChanged( double d );
6365
void on_mGroupSpaceSpinBox_valueChanged( double d );
6466
void on_mLayerSpaceSpinBox_valueChanged( double d );

‎src/app/legend/qgslegend.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ QgsLegend::QgsLegend( QgsMapCanvas *canvas, QWidget * parent, const char *name )
113113

114114
connect( mMapCanvas, SIGNAL( layersChanged() ),
115115
this, SLOT( refreshCheckStates() ) );
116+
connect( mMapCanvas, SIGNAL( extentsChanged() ),
117+
this, SLOT( updateLegendItemSymbologies() ) );
116118

117119
// Initialise the line indicator widget.
118120
mInsertionLine = new QWidget( viewport() );
@@ -141,6 +143,7 @@ QgsLegend::QgsLegend( QgsMapCanvas *canvas, QWidget * parent, const char *name )
141143
QgsLegend::~QgsLegend()
142144
{
143145
delete mInsertionLine;
146+
delete mGetLegendGraphicPopup;
144147
}
145148

146149
#ifdef QGISDEBUG
@@ -395,6 +398,24 @@ void QgsLegend::mousePressEvent( QMouseEvent * e )
395398
{
396399
if ( e->button() == Qt::LeftButton )
397400
{
401+
// show WMS legend in case itemAt( e->pos() ) is a wms legend
402+
// if it's not a legend later it return a null pixmap
403+
QImage legend = getWmsLegendPixmap( itemAt( e->pos() ) );
404+
if ( !legend.isNull() )
405+
{
406+
mGetLegendGraphicPopup = new QFrame();
407+
mGetLegendGraphicPopup->setFrameStyle(QFrame::Box | QFrame::Raised);
408+
mGetLegendGraphicPopup->setLineWidth(2);
409+
mGetLegendGraphicPopup->setAutoFillBackground(true);
410+
QVBoxLayout *layout = new QVBoxLayout;
411+
QLabel *label = new QLabel(mGetLegendGraphicPopup);
412+
label->setPixmap( QPixmap::fromImage(legend) );
413+
layout->addWidget(label);
414+
mGetLegendGraphicPopup->setLayout(layout);
415+
mGetLegendGraphicPopup->move(e->globalX(), e->globalY());
416+
mGetLegendGraphicPopup->show();
417+
}
418+
398419
mMousePressedFlag = true;
399420
mDropTarget = itemAt( e->pos() );
400421
if ( !mDropTarget )
@@ -624,6 +645,11 @@ void QgsLegend::updateGroupCheckStates( QTreeWidgetItem *item )
624645

625646
void QgsLegend::mouseReleaseEvent( QMouseEvent * e )
626647
{
648+
if (mGetLegendGraphicPopup) {
649+
delete mGetLegendGraphicPopup;
650+
mGetLegendGraphicPopup = 0;
651+
}
652+
627653
QStringList layersPriorToEvent = layerIDs();
628654
QTreeWidget::mouseReleaseEvent( e );
629655
mMousePressedFlag = false;
@@ -3208,3 +3234,43 @@ void QgsLegend::updateLegendItemSymbologies()
32083234
ll->refreshSymbology( ll->layer()->id() );
32093235
}
32103236
}
3237+
3238+
QImage QgsLegend::getWmsLegendPixmap( QTreeWidgetItem *item )
3239+
{
3240+
if ( !item )
3241+
{
3242+
return QImage();
3243+
}
3244+
3245+
QTreeWidgetItem *parent = item->parent();
3246+
if ( !parent )
3247+
{
3248+
return QImage();
3249+
}
3250+
3251+
QgsLegendItem* li = dynamic_cast<QgsLegendItem *>( parent );
3252+
if ( !li )
3253+
{
3254+
return QImage();
3255+
}
3256+
3257+
if ( li->type() != QgsLegendItem::LEGEND_LAYER )
3258+
{
3259+
return QImage();
3260+
}
3261+
3262+
QgsLegendLayer *lyr = qobject_cast<QgsLegendLayer*>( li );
3263+
QgsRasterLayer *rasterLayer = dynamic_cast<QgsRasterLayer*>( lyr->layer() );
3264+
if ( !rasterLayer )
3265+
{
3266+
return QImage();
3267+
}
3268+
3269+
if ( rasterLayer->providerType() != "wms" )
3270+
{
3271+
return QImage();
3272+
}
3273+
3274+
return rasterLayer->dataProvider()->getLegendGraphic( canvas()->scale() );
3275+
}
3276+

‎src/app/legend/qgslegend.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,16 @@ class QgsLegend : public QTreeWidget
590590

591591
bool verifyDrawingOrder();
592592

593+
/*!
594+
* Check if current LegendItem belogs to a WMS layer
595+
* @param item LegendItem to check if belongs to a WMS layer
596+
* @return QImage A valid Legend image if belogs to WMS otherwise QImage()
597+
*/
598+
QImage getWmsLegendPixmap( QTreeWidgetItem *item );
599+
600+
//! popup QFrame containing WMS getLegendGraphic pixmap
601+
QFrame *mGetLegendGraphicPopup;
602+
593603
signals:
594604
void itemAdded( QModelIndex index );
595605
void itemMoved( QModelIndex oldIndex, QModelIndex newIndex );

‎src/app/legend/qgslegendlayer.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,26 @@ void QgsLegendLayer::rasterLayerSymbology( QgsRasterLayer* layer )
208208
#if QT_VERSION >= 0x40700
209209
itemList.reserve( rasterItemList.size() );
210210
#endif
211+
212+
// GetLegendGraphics in case of WMS service... pixmap can return null if GetLegendGraphics
213+
// is not supported by server
214+
QgsDebugMsg( QString( "layer providertype:: %1" ).arg( layer->providerType() ) );
215+
if ( layer->providerType() == "wms" )
216+
{
217+
double currentScale = legend()->canvas()->scale();
218+
219+
QImage legendGraphic = layer->dataProvider()->getLegendGraphic( currentScale );
220+
if ( !legendGraphic.isNull() )
221+
{
222+
QgsDebugMsg( QString( "downloaded legend with dimension Width:" )+QString::number(legendGraphic.width())+QString(" and Height:")+QString::number(legendGraphic.height()) );
223+
224+
#if QT_VERSION >= 0x40700
225+
if ( rasterItemList.size() == 0) itemList.reserve( 1 );
226+
#endif
227+
itemList.append( qMakePair( QString(""), QPixmap::fromImage(legendGraphic) ) );
228+
}
229+
}
230+
211231
// Paletted raster may have many colors, for example UInt16 may have 65536 colors
212232
// and it is very slow, so we limit max count
213233
QSize iconSize = treeWidget()->iconSize();

‎src/app/qgsoptions.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,9 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
545545

546546
cmbLegendDoubleClickAction->setCurrentIndex( settings.value( "/qgis/legendDoubleClickAction", 0 ).toInt() );
547547

548+
// WMS getLegendGraphic setting
549+
mLegendGraphicResolutionSpinBox->setValue( settings.value("/qgis/defaultLegendGraphicResolution", 0).toInt() );
550+
548551
//
549552
// Raster properties
550553
//
@@ -965,6 +968,7 @@ void QgsOptions::saveOptions()
965968
settings.setValue( "/qgis/addPostgisDC", cbxAddPostgisDC->isChecked() );
966969
settings.setValue( "/qgis/addOracleDC", cbxAddOracleDC->isChecked() );
967970
settings.setValue( "/qgis/addNewLayersToCurrentGroup", cbxAddNewLayersToCurrentGroup->isChecked() );
971+
settings.setValue( "/qgis/defaultLegendGraphicResolution", mLegendGraphicResolutionSpinBox->value() );
968972
bool createRasterLegendIcons = settings.value( "/qgis/createRasterLegendIcons", false ).toBool();
969973
settings.setValue( "/qgis/createRasterLegendIcons", cbxCreateRasterLegendIcons->isChecked() );
970974
settings.setValue( "/qgis/copyGeometryAsWKT", cbxCopyWKTGeomFromTable->isChecked() );

‎src/core/composer/qgscomposeritemcommand.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ class CORE_EXPORT QgsComposerMergeCommand: public QgsComposerItemCommand
8585
LegendEqualColumnWidth,
8686
LegendSymbolWidth,
8787
LegendSymbolHeight,
88+
LegendWmsLegendWidth,
89+
LegendWmsLegendHeight,
8890
LegendTitleSpaceBottom,
8991
LegendGroupSpace,
9092
LegendLayerSpace,

‎src/core/composer/qgscomposerlegend.cpp

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ QgsComposerLegend::QgsComposerLegend( QgsComposition* composition )
5454

5555
mSymbolWidth = 7;
5656
mSymbolHeight = 4;
57+
mWmsLegendWidth = 50;
58+
mWmsLegendHeight = 25;
5759
mWrapChar = "";
5860
mlineSpacing = 1.5;
5961
adjustBoxSize();
@@ -347,13 +349,41 @@ QgsComposerLegend::Nucleon QgsComposerLegend::drawSymbolItem( QgsComposerLegendI
347349
}
348350
else if ( rasterItem )
349351
{
350-
if ( painter )
352+
// manage WMS lengendGraphic
353+
// actual code recognise if it's a legend because it has an icon and it's text is empty => this is not good MV pattern implementation :(
354+
QIcon symbolIcon = symbolItem->icon();
355+
if ( !symbolIcon.isNull() && symbolItem->text().isEmpty() )
351356
{
352-
painter->setBrush( rasterItem->color() );
353-
painter->drawRect( QRectF( point.x(), point.y() + ( itemHeight - mSymbolHeight ) / 2, mSymbolWidth, mSymbolHeight ) );
357+
// find max size
358+
QList<QSize> sizes = symbolIcon.availableSizes();
359+
double maxWidth = 0;
360+
double maxHeight = 0;
361+
foreach ( QSize size, sizes )
362+
{
363+
if ( maxWidth < size.width() ) maxWidth = size.width();
364+
if ( maxHeight < size.height() ) maxHeight = size.height();
365+
}
366+
QSize maxSize(maxWidth, maxHeight);
367+
368+
// get and print legend
369+
QImage legend = symbolIcon.pixmap(maxWidth, maxHeight).toImage();
370+
if ( painter )
371+
{
372+
painter->drawImage( QRectF( point.x(), point.y(), mWmsLegendWidth, mWmsLegendHeight ), legend, QRectF( 0, 0, maxWidth, maxHeight ) );
373+
}
374+
symbolSize.rwidth() = mWmsLegendWidth;
375+
symbolSize.rheight() = mWmsLegendHeight;
376+
}
377+
else
378+
{
379+
if ( painter )
380+
{
381+
painter->setBrush( rasterItem->color() );
382+
painter->drawRect( QRectF( point.x(), point.y() + ( itemHeight - mSymbolHeight ) / 2, mSymbolWidth, mSymbolHeight ) );
383+
}
384+
symbolSize.rwidth() = mSymbolWidth;
385+
symbolSize.rheight() = mSymbolHeight;
354386
}
355-
symbolSize.rwidth() = mSymbolWidth;
356-
symbolSize.rheight() = mSymbolHeight;
357387
}
358388
else //item with icon?
359389
{
@@ -555,6 +585,8 @@ bool QgsComposerLegend::writeXML( QDomElement& elem, QDomDocument & doc ) const
555585

556586
composerLegendElem.setAttribute( "symbolWidth", QString::number( mSymbolWidth ) );
557587
composerLegendElem.setAttribute( "symbolHeight", QString::number( mSymbolHeight ) );
588+
composerLegendElem.setAttribute( "wmsLegendWidth", QString::number( mWmsLegendWidth ) );
589+
composerLegendElem.setAttribute( "wmsLegendHeight", QString::number( mWmsLegendHeight ) );
558590
composerLegendElem.setAttribute( "wrapChar", mWrapChar );
559591
composerLegendElem.setAttribute( "fontColor", mFontColor.name() );
560592

@@ -622,6 +654,8 @@ bool QgsComposerLegend::readXML( const QDomElement& itemElem, const QDomDocument
622654

623655
mSymbolWidth = itemElem.attribute( "symbolWidth", "7.0" ).toDouble();
624656
mSymbolHeight = itemElem.attribute( "symbolHeight", "14.0" ).toDouble();
657+
mWmsLegendWidth = itemElem.attribute( "wmsLegendWidth", "50" ).toDouble();
658+
mWmsLegendHeight = itemElem.attribute( "wmsLegendHeight", "25" ).toDouble();
625659

626660
mWrapChar = itemElem.attribute( "wrapChar" );
627661

‎src/core/composer/qgscomposerlegend.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ class CORE_EXPORT QgsComposerLegend : public QgsComposerItem
8787
double symbolHeight() const {return mSymbolHeight;}
8888
void setSymbolHeight( double h ) {mSymbolHeight = h;}
8989

90+
double wmsLegendWidth() const {return mWmsLegendWidth;}
91+
void setWmsLegendWidth( double w ) {mWmsLegendWidth = w;}
92+
93+
double wmsLegendHeight() const {return mWmsLegendHeight;}
94+
void setWmsLegendHeight( double h ) {mWmsLegendHeight = h;}
95+
9096
void setWrapChar( const QString& t ) {mWrapChar = t;}
9197
QString wrapChar() const {return mWrapChar;}
9298

@@ -139,6 +145,11 @@ class CORE_EXPORT QgsComposerLegend : public QgsComposerItem
139145
/**Height of symbol icon*/
140146
double mSymbolHeight;
141147

148+
/**Width of WMS legendGraphic pixmap*/
149+
double mWmsLegendWidth;
150+
/**Height of WMS legendGraphic pixmap*/
151+
double mWmsLegendHeight;
152+
142153
/** Spacing between lines when wrapped */
143154
double mlineSpacing;
144155

0 commit comments

Comments
 (0)
Please sign in to comment.