Skip to content

Commit

Permalink
Merge pull request #966 from luipir/SITA3-WmsGetLegendGraphicManagement
Browse files Browse the repository at this point in the history
WMS getLegendGraphic management in QgsLegend and QgsComposer - Developed with funding from Regione Toscana-SITA
  • Loading branch information
jef-n committed Oct 24, 2013
2 parents fc74f66 + f6a6a0c commit 8fb20f0
Show file tree
Hide file tree
Showing 15 changed files with 598 additions and 36 deletions.
26 changes: 26 additions & 0 deletions src/app/composer/qgscomposerlegendwidget.cpp
Expand Up @@ -168,6 +168,8 @@ void QgsComposerLegendWidget::setGuiElements()
mEqualColumnWidthCheckBox->setChecked( mLegend->equalColumnWidth() );
mSymbolWidthSpinBox->setValue( mLegend->symbolWidth() );
mSymbolHeightSpinBox->setValue( mLegend->symbolHeight() );
mWmsLegendWidthSpinBox->setValue( mLegend->wmsLegendWidth() );
mWmsLegendHeightSpinBox->setValue( mLegend->wmsLegendHeight() );
mTitleSpaceBottomSpinBox->setValue( mLegend->style( QgsComposerLegendStyle::Title ).margin( QgsComposerLegendStyle::Bottom ) );
mGroupSpaceSpinBox->setValue( mLegend->style( QgsComposerLegendStyle::Group ).margin( QgsComposerLegendStyle::Top ) );
mLayerSpaceSpinBox->setValue( mLegend->style( QgsComposerLegendStyle::Subgroup ).margin( QgsComposerLegendStyle::Top ) );
Expand Down Expand Up @@ -280,6 +282,30 @@ void QgsComposerLegendWidget::on_mSymbolHeightSpinBox_valueChanged( double d )
}
}

void QgsComposerLegendWidget::on_mWmsLegendWidthSpinBox_valueChanged( double d )
{
if ( mLegend )
{
mLegend->beginCommand( tr( "Wms Legend width" ), QgsComposerMergeCommand::LegendWmsLegendWidth );
mLegend->setWmsLegendWidth( d );
mLegend->adjustBoxSize();
mLegend->update();
mLegend->endCommand();
}
}

void QgsComposerLegendWidget::on_mWmsLegendHeightSpinBox_valueChanged( double d )
{
if ( mLegend )
{
mLegend->beginCommand( tr( "Wms Legend height" ), QgsComposerMergeCommand::LegendWmsLegendHeight );
mLegend->setWmsLegendHeight( d );
mLegend->adjustBoxSize();
mLegend->update();
mLegend->endCommand();
}
}

void QgsComposerLegendWidget::on_mTitleSpaceBottomSpinBox_valueChanged( double d )
{
if ( mLegend )
Expand Down
2 changes: 2 additions & 0 deletions src/app/composer/qgscomposerlegendwidget.h
Expand Up @@ -59,6 +59,8 @@ class QgsComposerLegendWidget: public QWidget, private Ui::QgsComposerLegendWidg
void on_mEqualColumnWidthCheckBox_toggled( bool checked );
void on_mSymbolWidthSpinBox_valueChanged( double d );
void on_mSymbolHeightSpinBox_valueChanged( double d );
void on_mWmsLegendWidthSpinBox_valueChanged( double d );
void on_mWmsLegendHeightSpinBox_valueChanged( double d );
void on_mTitleSpaceBottomSpinBox_valueChanged( double d );
void on_mGroupSpaceSpinBox_valueChanged( double d );
void on_mLayerSpaceSpinBox_valueChanged( double d );
Expand Down
66 changes: 66 additions & 0 deletions src/app/legend/qgslegend.cpp
Expand Up @@ -113,6 +113,8 @@ QgsLegend::QgsLegend( QgsMapCanvas *canvas, QWidget * parent, const char *name )

connect( mMapCanvas, SIGNAL( layersChanged() ),
this, SLOT( refreshCheckStates() ) );
connect( mMapCanvas, SIGNAL( extentsChanged() ),
this, SLOT( updateLegendItemSymbologies() ) );

// Initialise the line indicator widget.
mInsertionLine = new QWidget( viewport() );
Expand Down Expand Up @@ -141,6 +143,7 @@ QgsLegend::QgsLegend( QgsMapCanvas *canvas, QWidget * parent, const char *name )
QgsLegend::~QgsLegend()
{
delete mInsertionLine;
delete mGetLegendGraphicPopup;
}

#ifdef QGISDEBUG
Expand Down Expand Up @@ -395,6 +398,24 @@ void QgsLegend::mousePressEvent( QMouseEvent * e )
{
if ( e->button() == Qt::LeftButton )
{
// show WMS legend in case itemAt( e->pos() ) is a wms legend
// if it's not a legend later it return a null pixmap
QImage legend = getWmsLegendPixmap( itemAt( e->pos() ) );
if ( !legend.isNull() )
{
mGetLegendGraphicPopup = new QFrame();
mGetLegendGraphicPopup->setFrameStyle(QFrame::Box | QFrame::Raised);
mGetLegendGraphicPopup->setLineWidth(2);
mGetLegendGraphicPopup->setAutoFillBackground(true);
QVBoxLayout *layout = new QVBoxLayout;
QLabel *label = new QLabel(mGetLegendGraphicPopup);
label->setPixmap( QPixmap::fromImage(legend) );
layout->addWidget(label);
mGetLegendGraphicPopup->setLayout(layout);
mGetLegendGraphicPopup->move(e->globalX(), e->globalY());
mGetLegendGraphicPopup->show();
}

mMousePressedFlag = true;
mDropTarget = itemAt( e->pos() );
if ( !mDropTarget )
Expand Down Expand Up @@ -624,6 +645,11 @@ void QgsLegend::updateGroupCheckStates( QTreeWidgetItem *item )

void QgsLegend::mouseReleaseEvent( QMouseEvent * e )
{
if (mGetLegendGraphicPopup) {
delete mGetLegendGraphicPopup;
mGetLegendGraphicPopup = 0;
}

QStringList layersPriorToEvent = layerIDs();
QTreeWidget::mouseReleaseEvent( e );
mMousePressedFlag = false;
Expand Down Expand Up @@ -3208,3 +3234,43 @@ void QgsLegend::updateLegendItemSymbologies()
ll->refreshSymbology( ll->layer()->id() );
}
}

QImage QgsLegend::getWmsLegendPixmap( QTreeWidgetItem *item )
{
if ( !item )
{
return QImage();
}

QTreeWidgetItem *parent = item->parent();
if ( !parent )
{
return QImage();
}

QgsLegendItem* li = dynamic_cast<QgsLegendItem *>( parent );
if ( !li )
{
return QImage();
}

if ( li->type() != QgsLegendItem::LEGEND_LAYER )
{
return QImage();
}

QgsLegendLayer *lyr = qobject_cast<QgsLegendLayer*>( li );
QgsRasterLayer *rasterLayer = dynamic_cast<QgsRasterLayer*>( lyr->layer() );
if ( !rasterLayer )
{
return QImage();
}

if ( rasterLayer->providerType() != "wms" )
{
return QImage();
}

return rasterLayer->dataProvider()->getLegendGraphic( canvas()->scale() );
}

10 changes: 10 additions & 0 deletions src/app/legend/qgslegend.h
Expand Up @@ -590,6 +590,16 @@ class QgsLegend : public QTreeWidget

bool verifyDrawingOrder();

/*!
* Check if current LegendItem belogs to a WMS layer
* @param item LegendItem to check if belongs to a WMS layer
* @return QImage A valid Legend image if belogs to WMS otherwise QImage()
*/
QImage getWmsLegendPixmap( QTreeWidgetItem *item );

//! popup QFrame containing WMS getLegendGraphic pixmap
QFrame *mGetLegendGraphicPopup;

signals:
void itemAdded( QModelIndex index );
void itemMoved( QModelIndex oldIndex, QModelIndex newIndex );
Expand Down
20 changes: 20 additions & 0 deletions src/app/legend/qgslegendlayer.cpp
Expand Up @@ -208,6 +208,26 @@ void QgsLegendLayer::rasterLayerSymbology( QgsRasterLayer* layer )
#if QT_VERSION >= 0x40700
itemList.reserve( rasterItemList.size() );
#endif

// GetLegendGraphics in case of WMS service... pixmap can return null if GetLegendGraphics
// is not supported by server
QgsDebugMsg( QString( "layer providertype:: %1" ).arg( layer->providerType() ) );
if ( layer->providerType() == "wms" )
{
double currentScale = legend()->canvas()->scale();

QImage legendGraphic = layer->dataProvider()->getLegendGraphic( currentScale );
if ( !legendGraphic.isNull() )
{
QgsDebugMsg( QString( "downloaded legend with dimension Width:" )+QString::number(legendGraphic.width())+QString(" and Height:")+QString::number(legendGraphic.height()) );

#if QT_VERSION >= 0x40700
if ( rasterItemList.size() == 0) itemList.reserve( 1 );
#endif
itemList.append( qMakePair( QString(""), QPixmap::fromImage(legendGraphic) ) );
}
}

// Paletted raster may have many colors, for example UInt16 may have 65536 colors
// and it is very slow, so we limit max count
QSize iconSize = treeWidget()->iconSize();
Expand Down
4 changes: 4 additions & 0 deletions src/app/qgsoptions.cpp
Expand Up @@ -545,6 +545,9 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :

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

// WMS getLegendGraphic setting
mLegendGraphicResolutionSpinBox->setValue( settings.value("/qgis/defaultLegendGraphicResolution", 0).toInt() );

//
// Raster properties
//
Expand Down Expand Up @@ -965,6 +968,7 @@ void QgsOptions::saveOptions()
settings.setValue( "/qgis/addPostgisDC", cbxAddPostgisDC->isChecked() );
settings.setValue( "/qgis/addOracleDC", cbxAddOracleDC->isChecked() );
settings.setValue( "/qgis/addNewLayersToCurrentGroup", cbxAddNewLayersToCurrentGroup->isChecked() );
settings.setValue( "/qgis/defaultLegendGraphicResolution", mLegendGraphicResolutionSpinBox->value() );
bool createRasterLegendIcons = settings.value( "/qgis/createRasterLegendIcons", false ).toBool();
settings.setValue( "/qgis/createRasterLegendIcons", cbxCreateRasterLegendIcons->isChecked() );
settings.setValue( "/qgis/copyGeometryAsWKT", cbxCopyWKTGeomFromTable->isChecked() );
Expand Down
2 changes: 2 additions & 0 deletions src/core/composer/qgscomposeritemcommand.h
Expand Up @@ -85,6 +85,8 @@ class CORE_EXPORT QgsComposerMergeCommand: public QgsComposerItemCommand
LegendEqualColumnWidth,
LegendSymbolWidth,
LegendSymbolHeight,
LegendWmsLegendWidth,
LegendWmsLegendHeight,
LegendTitleSpaceBottom,
LegendGroupSpace,
LegendLayerSpace,
Expand Down
44 changes: 39 additions & 5 deletions src/core/composer/qgscomposerlegend.cpp
Expand Up @@ -54,6 +54,8 @@ QgsComposerLegend::QgsComposerLegend( QgsComposition* composition )

mSymbolWidth = 7;
mSymbolHeight = 4;
mWmsLegendWidth = 50;
mWmsLegendHeight = 25;
mWrapChar = "";
mlineSpacing = 1.5;
adjustBoxSize();
Expand Down Expand Up @@ -347,13 +349,41 @@ QgsComposerLegend::Nucleon QgsComposerLegend::drawSymbolItem( QgsComposerLegendI
}
else if ( rasterItem )
{
if ( painter )
// manage WMS lengendGraphic
// 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 :(
QIcon symbolIcon = symbolItem->icon();
if ( !symbolIcon.isNull() && symbolItem->text().isEmpty() )
{
painter->setBrush( rasterItem->color() );
painter->drawRect( QRectF( point.x(), point.y() + ( itemHeight - mSymbolHeight ) / 2, mSymbolWidth, mSymbolHeight ) );
// find max size
QList<QSize> sizes = symbolIcon.availableSizes();
double maxWidth = 0;
double maxHeight = 0;
foreach ( QSize size, sizes )
{
if ( maxWidth < size.width() ) maxWidth = size.width();
if ( maxHeight < size.height() ) maxHeight = size.height();
}
QSize maxSize(maxWidth, maxHeight);

// get and print legend
QImage legend = symbolIcon.pixmap(maxWidth, maxHeight).toImage();
if ( painter )
{
painter->drawImage( QRectF( point.x(), point.y(), mWmsLegendWidth, mWmsLegendHeight ), legend, QRectF( 0, 0, maxWidth, maxHeight ) );
}
symbolSize.rwidth() = mWmsLegendWidth;
symbolSize.rheight() = mWmsLegendHeight;
}
else
{
if ( painter )
{
painter->setBrush( rasterItem->color() );
painter->drawRect( QRectF( point.x(), point.y() + ( itemHeight - mSymbolHeight ) / 2, mSymbolWidth, mSymbolHeight ) );
}
symbolSize.rwidth() = mSymbolWidth;
symbolSize.rheight() = mSymbolHeight;
}
symbolSize.rwidth() = mSymbolWidth;
symbolSize.rheight() = mSymbolHeight;
}
else //item with icon?
{
Expand Down Expand Up @@ -555,6 +585,8 @@ bool QgsComposerLegend::writeXML( QDomElement& elem, QDomDocument & doc ) const

composerLegendElem.setAttribute( "symbolWidth", QString::number( mSymbolWidth ) );
composerLegendElem.setAttribute( "symbolHeight", QString::number( mSymbolHeight ) );
composerLegendElem.setAttribute( "wmsLegendWidth", QString::number( mWmsLegendWidth ) );
composerLegendElem.setAttribute( "wmsLegendHeight", QString::number( mWmsLegendHeight ) );
composerLegendElem.setAttribute( "wrapChar", mWrapChar );
composerLegendElem.setAttribute( "fontColor", mFontColor.name() );

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

mSymbolWidth = itemElem.attribute( "symbolWidth", "7.0" ).toDouble();
mSymbolHeight = itemElem.attribute( "symbolHeight", "14.0" ).toDouble();
mWmsLegendWidth = itemElem.attribute( "wmsLegendWidth", "50" ).toDouble();
mWmsLegendHeight = itemElem.attribute( "wmsLegendHeight", "25" ).toDouble();

mWrapChar = itemElem.attribute( "wrapChar" );

Expand Down
11 changes: 11 additions & 0 deletions src/core/composer/qgscomposerlegend.h
Expand Up @@ -87,6 +87,12 @@ class CORE_EXPORT QgsComposerLegend : public QgsComposerItem
double symbolHeight() const {return mSymbolHeight;}
void setSymbolHeight( double h ) {mSymbolHeight = h;}

double wmsLegendWidth() const {return mWmsLegendWidth;}
void setWmsLegendWidth( double w ) {mWmsLegendWidth = w;}

double wmsLegendHeight() const {return mWmsLegendHeight;}
void setWmsLegendHeight( double h ) {mWmsLegendHeight = h;}

void setWrapChar( const QString& t ) {mWrapChar = t;}
QString wrapChar() const {return mWrapChar;}

Expand Down Expand Up @@ -139,6 +145,11 @@ class CORE_EXPORT QgsComposerLegend : public QgsComposerItem
/**Height of symbol icon*/
double mSymbolHeight;

/**Width of WMS legendGraphic pixmap*/
double mWmsLegendWidth;
/**Height of WMS legendGraphic pixmap*/
double mWmsLegendHeight;

/** Spacing between lines when wrapped */
double mlineSpacing;

Expand Down

0 comments on commit 8fb20f0

Please sign in to comment.