95 changes: 75 additions & 20 deletions src/mapserver/qgswmsserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,6 @@ QImage* QgsWMSServer::getLegendGraphics()
return 0;
}

QgsLegendModel legendModel;
legendModel.setLayerSet( layerIds, scaleDenominator );

//create first image (to find out dpi)
QImage* theImage = createImage( 10, 10 );
if ( !theImage )
Expand All @@ -354,16 +351,84 @@ QImage* QgsWMSServer::getLegendGraphics()
legendParameters( mmToPixelFactor, fontOversamplingFactor, boxSpace, layerSpace, layerTitleSpace, symbolSpace,
iconLabelSpace, symbolWidth, symbolHeight, layerFont, itemFont, layerFontColor, itemFontColor );

QString rule;
QMap<QString, QString>::const_iterator ruleIt = mParameterMap.find( "RULE" );
if ( ruleIt != mParameterMap.constEnd() )
{
rule = ruleIt.value();

QMap<QString, QString>::const_iterator widthIt = mParameterMap.find( "WIDTH" );
if ( widthIt != mParameterMap.constEnd() )
{
bool conversionSuccess;
double width = widthIt.value().toDouble( &conversionSuccess );
if ( conversionSuccess )
{
symbolWidth = width;
}
}

QMap<QString, QString>::const_iterator heightIt = mParameterMap.find( "HEIGHT" );
if ( heightIt != mParameterMap.constEnd() )
{
bool conversionSuccess;
double width = heightIt.value().toDouble( &conversionSuccess );
if ( conversionSuccess )
{
symbolHeight = width;
}
}
}

QgsLegendModel legendModel;
legendModel.setLayerSet( layerIds, scaleDenominator, rule );

//first find out image dimensions without painting
QStandardItem* rootItem = legendModel.invisibleRootItem();
if ( !rootItem )
{
return 0;
}

if ( !rule.isEmpty() ) {
//create second image with the right dimensions
QImage* paintImage = createImage( symbolWidth, symbolHeight );

//go through the items a second time for painting
QPainter p( paintImage );
p.setRenderHint( QPainter::Antialiasing, true );

QgsComposerLegendItem* currentComposerItem = dynamic_cast<QgsComposerLegendItem*>( rootItem->child( 0 )->child( 0 ) );
if ( currentComposerItem != NULL ) {
QgsComposerLegendItem::ItemType type = currentComposerItem->itemType();
switch ( type )
{
case QgsComposerLegendItem::SymbologyV2Item:
drawLegendSymbolV2( currentComposerItem, &p, 0., 0., symbolWidth, symbolHeight, 0. );
break;
case QgsComposerLegendItem::RasterSymbolItem:
drawRasterSymbol( currentComposerItem, &p, 0., 0., symbolWidth, symbolHeight, 0. );
break;
case QgsComposerLegendItem::GroupItem:
//QgsDebugMsg( "GroupItem not handled" );
break;
case QgsComposerLegendItem::LayerItem:
//QgsDebugMsg( "GroupItem not handled" );
break;
case QgsComposerLegendItem::StyleItem:
//QgsDebugMsg( "StyleItem not handled" );
break;
}
}

QgsMapLayerRegistry::instance()->removeAllMapLayers();
delete theImage;
return paintImage;
}

double currentY = drawLegendGraphics( 0, fontOversamplingFactor, rootItem, boxSpace, layerSpace, layerTitleSpace, symbolSpace,
iconLabelSpace, symbolWidth, symbolHeight, layerFont, itemFont, layerFontColor, itemFontColor, maxTextWidth,
maxSymbolWidth, theImage->dotsPerMeterX() * 0.0254 );
maxSymbolWidth );

//create second image with the right dimensions
QImage* paintImage = createImage( maxTextWidth + maxSymbolWidth, ceil( currentY ) );
Expand All @@ -374,7 +439,7 @@ QImage* QgsWMSServer::getLegendGraphics()

drawLegendGraphics( &p, fontOversamplingFactor, rootItem, boxSpace, layerSpace, layerTitleSpace, symbolSpace,
iconLabelSpace, symbolWidth, symbolHeight, layerFont, itemFont, layerFontColor, itemFontColor, maxTextWidth,
maxSymbolWidth, theImage->dotsPerMeterX() * 0.0254 );
maxSymbolWidth );

QgsMapLayerRegistry::instance()->removeAllMapLayers();
delete theImage;
Expand All @@ -384,7 +449,7 @@ QImage* QgsWMSServer::getLegendGraphics()
double QgsWMSServer::drawLegendGraphics( QPainter* p, double fontOversamplingFactor, QStandardItem* rootItem, double boxSpace,
double layerSpace, double layerTitleSpace, double symbolSpace, double iconLabelSpace,
double symbolWidth, double symbolHeight, const QFont& layerFont, const QFont& itemFont,
const QColor& layerFontColor, const QColor& itemFontColor, double& maxTextWidth, double& maxSymbolWidth, double dpi )
const QColor& layerFontColor, const QColor& itemFontColor, double& maxTextWidth, double& maxSymbolWidth )
{
if ( !rootItem )
{
Expand All @@ -408,8 +473,7 @@ double QgsWMSServer::drawLegendGraphics( QPainter* p, double fontOversamplingFac
currentY += layerSpace;
}
drawLegendLayerItem( layerItem, p, maxTextWidth, maxSymbolWidth, currentY, layerFont, layerFontColor, itemFont, itemFontColor,
boxSpace, layerSpace, layerTitleSpace, symbolSpace, iconLabelSpace, symbolWidth, symbolHeight, fontOversamplingFactor,
dpi );
boxSpace, layerSpace, layerTitleSpace, symbolSpace, iconLabelSpace, symbolWidth, symbolHeight, fontOversamplingFactor );
}
}
currentY += boxSpace;
Expand Down Expand Up @@ -1616,8 +1680,7 @@ QStringList QgsWMSServer::layerSet( const QStringList &layersList,

void QgsWMSServer::drawLegendLayerItem( QgsComposerLayerItem* item, QPainter* p, double& maxTextWidth, double& maxSymbolWidth, double& currentY, const QFont& layerFont,
const QColor& layerFontColor, const QFont& itemFont, const QColor& itemFontColor, double boxSpace, double layerSpace,
double layerTitleSpace, double symbolSpace, double iconLabelSpace, double symbolWidth, double symbolHeight, double fontOversamplingFactor,
double dpi ) const
double layerTitleSpace, double symbolSpace, double iconLabelSpace, double symbolWidth, double symbolHeight, double fontOversamplingFactor ) const
{
Q_UNUSED( layerSpace );
if ( !item )
Expand Down Expand Up @@ -1678,7 +1741,7 @@ void QgsWMSServer::drawLegendLayerItem( QgsComposerLayerItem* item, QPainter* p,
switch ( type )
{
case QgsComposerLegendItem::SymbologyV2Item:
drawLegendSymbolV2( currentComposerItem, p, boxSpace, currentY, currentSymbolWidth, currentSymbolHeight, dpi, symbolDownShift );
drawLegendSymbolV2( currentComposerItem, p, boxSpace, currentY, currentSymbolWidth, currentSymbolHeight, symbolDownShift );
break;
case QgsComposerLegendItem::RasterSymbolItem:
drawRasterSymbol( currentComposerItem, p, boxSpace, currentY, currentSymbolWidth, currentSymbolHeight, symbolDownShift );
Expand Down Expand Up @@ -1731,7 +1794,7 @@ void QgsWMSServer::drawLegendLayerItem( QgsComposerLayerItem* item, QPainter* p,


void QgsWMSServer::drawLegendSymbolV2( QgsComposerLegendItem* item, QPainter* p, double boxSpace, double currentY, double& symbolWidth,
double& symbolHeight, double dpi, double yDownShift ) const
double& symbolHeight, double yDownShift ) const
{
QgsComposerSymbolV2Item* symbolItem = dynamic_cast< QgsComposerSymbolV2Item* >( item );
if ( !symbolItem )
Expand All @@ -1744,14 +1807,6 @@ void QgsWMSServer::drawLegendSymbolV2( QgsComposerLegendItem* item, QPainter* p,
return;
}

//markers might have a different size
QgsMarkerSymbolV2* markerSymbol = dynamic_cast< QgsMarkerSymbolV2* >( symbol );
if ( markerSymbol )
{
symbolWidth = markerSymbol->size() * dpi / 25.4;
symbolHeight = markerSymbol->size() * dpi / 25.4;
}

if ( p )
{
p->save();
Expand Down
6 changes: 3 additions & 3 deletions src/mapserver/qgswmsserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class QgsWMSServer
double drawLegendGraphics( QPainter* p, double fontOversamplingFactor, QStandardItem* rootItem, double boxSpace, double layerSpace, double layerTitleSpace,
double symbolSpace, double iconLabelSpace, double symbolWidth, double symbolHeight,
const QFont& layerFont, const QFont& itemFont, const QColor& layerFontColor, const QColor& itemFontColor,
double& maxTextWidth, double& maxSymbolWidth, double dpi );
double& maxTextWidth, double& maxSymbolWidth );

//helper functions for GetLegendGraphics
/**Draws layer item and subitems
Expand All @@ -159,9 +159,9 @@ class QgsWMSServer
*/
void drawLegendLayerItem( QgsComposerLayerItem* item, QPainter* p, double& maxTextWidth, double& maxSymbolWidth, double& currentY, const QFont& layerFont,
const QColor& layerFontColor, const QFont& itemFont, const QColor& itemFontColor, double boxSpace, double layerSpace,
double layerTitleSpace, double symbolSpace, double iconLabelSpace, double symbolWidth, double symbolHeight, double fontOversamplingFactor, double dpi ) const;
double layerTitleSpace, double symbolSpace, double iconLabelSpace, double symbolWidth, double symbolHeight, double fontOversamplingFactor ) const;
/**Draws a symbol. Optionally, maxHeight is adapted (e.g. for large point markers) */
void drawLegendSymbolV2( QgsComposerLegendItem* item, QPainter* p, double boxSpace, double currentY, double& symbolWidth, double& symbolHeight, double dpi, double yDownShift ) const;
void drawLegendSymbolV2( QgsComposerLegendItem* item, QPainter* p, double boxSpace, double currentY, double& symbolWidth, double& symbolHeight, double yDownShift ) const;
void drawRasterSymbol( QgsComposerLegendItem* item, QPainter* p, double boxSpace, double currentY, double symbolWidth, double symbolHeight, double yDownShift ) const;

/**Read legend parameter from the request or from the first print composer in the project*/
Expand Down