Improve GetLegendGraphics output in wms server

git-svn-id: http://svn.osgeo.org/qgis/trunk@15077 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
mhugent 2011-01-25 13:29:16 +00:00
parent 895c4a4071
commit 4762be0ac4
4 changed files with 66 additions and 49 deletions

View File

@ -374,7 +374,8 @@ int main( int argc, char * argv[] )
} }
else else
{ {
QgsMSDebugMsg( "Error, 0 image in GetLegendGraphics" ) //do some error handling
QgsMSDebugMsg( "result image is 0" )
} }
delete result; delete result;
delete theRequestHandler; delete theRequestHandler;

View File

@ -630,7 +630,7 @@ QList<QDomElement> QgsProjectParser::legendGroupElements() const
groupList.push_back( groupNodeList.at( i ).toElement() ); groupList.push_back( groupNodeList.at( i ).toElement() );
} }
return groupList; return groupList;
} }
QMap< QString, QDomElement > QgsProjectParser::projectLayerElementsById() const QMap< QString, QDomElement > QgsProjectParser::projectLayerElementsById() const
@ -1104,11 +1104,8 @@ void QgsProjectParser::serviceCapabilities( QDomElement& parentElement, QDomDocu
contactInfoElem.appendChild( contactPersonPrimaryElem ); contactInfoElem.appendChild( contactPersonPrimaryElem );
//Contact address //Contact address
QDomElement contactAddressElem = doc.createElement( "ContactAddress" ); //QDomElement contactAddressElem = doc.createElement( "ContactAddress" );
//contactInfoElem.appendChild( contactAddressElem );
//
contactInfoElem.appendChild( contactAddressElem );
//phone //phone
QDomElement phoneElem = propertiesElem.firstChildElement( "WMSContactPhone" ); QDomElement phoneElem = propertiesElem.firstChildElement( "WMSContactPhone" );

View File

@ -261,7 +261,8 @@ QImage* QgsWMSServer::getLegendGraphics()
iconLabelSpace = mConfigParser->legendIconLabelSpace() * mmToPixelFactor; iconLabelSpace = mConfigParser->legendIconLabelSpace() * mmToPixelFactor;
symbolWidth = mConfigParser->legendSymbolWidth() * mmToPixelFactor; symbolWidth = mConfigParser->legendSymbolWidth() * mmToPixelFactor;
symbolHeight = mConfigParser->legendSymbolHeight() * mmToPixelFactor; symbolHeight = mConfigParser->legendSymbolHeight() * mmToPixelFactor;
double maxX = 0; double maxTextWidth = 0;
double maxSymbolWidth = 0;
double currentY = 0; double currentY = 0;
double fontOversamplingFactor = 10.0; double fontOversamplingFactor = 10.0;
QFont layerFont = mConfigParser->legendLayerFont(); QFont layerFont = mConfigParser->legendLayerFont();
@ -288,14 +289,15 @@ QImage* QgsWMSServer::getLegendGraphics()
QgsComposerLayerItem* layerItem = dynamic_cast<QgsComposerLayerItem*>( rootItem->child( i ) ); QgsComposerLayerItem* layerItem = dynamic_cast<QgsComposerLayerItem*>( rootItem->child( i ) );
if ( layerItem ) if ( layerItem )
{ {
drawLegendLayerItem( layerItem, 0, maxX, currentY, layerFont, itemFont, boxSpace, layerSpace, symbolSpace,
drawLegendLayerItem( layerItem, 0, maxTextWidth, maxSymbolWidth, currentY, layerFont, itemFont, boxSpace, layerSpace, symbolSpace,
iconLabelSpace, symbolWidth, symbolHeight, fontOversamplingFactor, theImage->dotsPerMeterX() * 0.0254 ); iconLabelSpace, symbolWidth, symbolHeight, fontOversamplingFactor, theImage->dotsPerMeterX() * 0.0254 );
} }
} }
currentY += boxSpace; currentY += boxSpace;
//create second image with the right dimensions //create second image with the right dimensions
QImage* paintImage = createImage( maxX, currentY ); QImage* paintImage = createImage( maxTextWidth + maxSymbolWidth, currentY );
//go through the items a second time for painting //go through the items a second time for painting
QPainter p( paintImage ); QPainter p( paintImage );
@ -307,7 +309,7 @@ QImage* QgsWMSServer::getLegendGraphics()
QgsComposerLayerItem* layerItem = dynamic_cast<QgsComposerLayerItem*>( rootItem->child( i ) ); QgsComposerLayerItem* layerItem = dynamic_cast<QgsComposerLayerItem*>( rootItem->child( i ) );
if ( layerItem ) if ( layerItem )
{ {
drawLegendLayerItem( layerItem, &p, maxX, currentY, layerFont, itemFont, boxSpace, layerSpace, symbolSpace, drawLegendLayerItem( layerItem, &p, maxTextWidth, maxSymbolWidth, currentY, layerFont, itemFont, boxSpace, layerSpace, symbolSpace,
iconLabelSpace, symbolWidth, symbolHeight, fontOversamplingFactor, theImage->dotsPerMeterX() * 0.0254 ); iconLabelSpace, symbolWidth, symbolHeight, fontOversamplingFactor, theImage->dotsPerMeterX() * 0.0254 );
} }
} }
@ -1155,7 +1157,7 @@ QStringList QgsWMSServer::layerSet( const QStringList& layersList,
return layerKeys; return layerKeys;
} }
void QgsWMSServer::drawLegendLayerItem( QgsComposerLayerItem* item, QPainter* p, double& maxX, double& currentY, const QFont& layerFont, void QgsWMSServer::drawLegendLayerItem( QgsComposerLayerItem* item, QPainter* p, double& maxTextWidth, double& maxSymbolWidth, double& currentY, const QFont& layerFont,
const QFont& itemFont, double boxSpace, double layerSpace, double symbolSpace, const QFont& itemFont, double boxSpace, double layerSpace, double symbolSpace,
double iconLabelSpace, double symbolWidth, double symbolHeight, double fontOversamplingFactor, double iconLabelSpace, double symbolWidth, double symbolHeight, double fontOversamplingFactor,
double dpi ) const double dpi ) const
@ -1177,13 +1179,16 @@ void QgsWMSServer::drawLegendLayerItem( QgsComposerLayerItem* item, QPainter* p,
p->drawText( boxSpace * fontOversamplingFactor, currentY * fontOversamplingFactor, item->text() ); p->drawText( boxSpace * fontOversamplingFactor, currentY * fontOversamplingFactor, item->text() );
p->restore(); p->restore();
} }
else
{
double layerItemWidth = layerFontMetrics.width( item->text() ) / fontOversamplingFactor + boxSpace;
if ( layerItemWidth > maxTextWidth )
{
maxTextWidth = layerItemWidth;
}
}
currentY += layerSpace; currentY += layerSpace;
double layerItemWidth = layerFontMetrics.width( item->text() ) / fontOversamplingFactor + 2 * boxSpace;
if ( layerItemWidth > maxX )
{
maxX = layerItemWidth;
}
int opacity = 0; int opacity = 0;
QgsMapLayer* layerInstance = QgsMapLayerRegistry::instance()->mapLayer( item->layerID() ); QgsMapLayer* layerInstance = QgsMapLayerRegistry::instance()->mapLayer( item->layerID() );
@ -1192,7 +1197,7 @@ void QgsWMSServer::drawLegendLayerItem( QgsComposerLayerItem* item, QPainter* p,
opacity = layerInstance->getTransparency(); //maplayer says transparency but means opacity opacity = layerInstance->getTransparency(); //maplayer says transparency but means opacity
} }
//then draw all the childs //then draw all the children
if ( p ) if ( p )
{ {
p->setFont( itemFont ); p->setFont( itemFont );
@ -1211,7 +1216,8 @@ void QgsWMSServer::drawLegendLayerItem( QgsComposerLayerItem* item, QPainter* p,
} }
double currentSymbolHeight = symbolHeight; double currentSymbolHeight = symbolHeight;
double currentSymbolWidth = symbolWidth; double currentSymbolWidth = symbolWidth; //symbol width (without box space and icon/label space
double currentTextWidth = 0;
//if the font is larger than the standard symbol size, try to draw the symbol centered (shifting towards the bottom) //if the font is larger than the standard symbol size, try to draw the symbol centered (shifting towards the bottom)
double symbolDownShift = ( itemFontMetrics.ascent() / fontOversamplingFactor - symbolHeight ) / 2.0; double symbolDownShift = ( itemFontMetrics.ascent() / fontOversamplingFactor - symbolHeight ) / 2.0;
@ -1233,44 +1239,46 @@ void QgsWMSServer::drawLegendLayerItem( QgsComposerLayerItem* item, QPainter* p,
drawRasterSymbol( currentComposerItem, p, boxSpace, currentY, currentSymbolWidth, currentSymbolHeight, symbolDownShift ); drawRasterSymbol( currentComposerItem, p, boxSpace, currentY, currentSymbolWidth, currentSymbolHeight, symbolDownShift );
break; break;
case QgsComposerLegendItem::GroupItem: case QgsComposerLegendItem::GroupItem:
QgsDebugMsg( "GroupItem not handled" ); //QgsDebugMsg( "GroupItem not handled" );
break; break;
case QgsComposerLegendItem::LayerItem: case QgsComposerLegendItem::LayerItem:
QgsDebugMsg( "GroupItem not handled" ); //QgsDebugMsg( "GroupItem not handled" );
break; break;
} }
//finally draw text //finally draw text
currentTextWidth = itemFontMetrics.width( currentComposerItem->text() ) / fontOversamplingFactor;
double symbolItemHeight = qMax( itemFontMetrics.ascent() / fontOversamplingFactor, currentSymbolHeight ); double symbolItemHeight = qMax( itemFontMetrics.ascent() / fontOversamplingFactor, currentSymbolHeight );
if ( p ) if ( p )
{ {
p->save(); p->save();
p->scale( 1.0 / fontOversamplingFactor, 1.0 / fontOversamplingFactor ); p->scale( 1.0 / fontOversamplingFactor, 1.0 / fontOversamplingFactor );
p->drawText(( boxSpace + currentSymbolWidth + iconLabelSpace ) * fontOversamplingFactor, p->drawText( maxSymbolWidth * fontOversamplingFactor,
( currentY + symbolItemHeight / 2.0 ) * fontOversamplingFactor + itemFontMetrics.ascent() / 2.0, currentComposerItem->text() ); ( currentY + symbolItemHeight / 2.0 ) * fontOversamplingFactor + itemFontMetrics.ascent() / 2.0, currentComposerItem->text() );
p->restore(); p->restore();
} }
else
{
if ( currentTextWidth > maxTextWidth )
{
maxTextWidth = currentTextWidth;
}
double symbolWidth = boxSpace + currentSymbolWidth + iconLabelSpace;
if ( symbolWidth > maxSymbolWidth )
{
maxSymbolWidth = symbolWidth;
}
}
currentY += symbolItemHeight; currentY += symbolItemHeight;
double symbolItemWidth = 2 * boxSpace + currentSymbolWidth + iconLabelSpace + itemFontMetrics.width( currentComposerItem->text() ) / fontOversamplingFactor;
currentY += symbolSpace; currentY += symbolSpace;
if ( symbolItemWidth > maxX )
{
maxX = symbolItemWidth;
}
} }
} }
void QgsWMSServer::drawLegendSymbol( QgsComposerLegendItem* item, QPainter* p, double boxSpace, double currentY, double& symbolWidth, double& symbolHeight, double layerOpacity, void QgsWMSServer::drawLegendSymbol( QgsComposerLegendItem* item, QPainter* p, double boxSpace, double currentY, double& symbolWidth, double& symbolHeight, double layerOpacity,
double dpi, double yDownShift ) const double dpi, double yDownShift ) const
{ {
if ( !p )
{
return;
}
QgsComposerSymbolItem* symbolItem = dynamic_cast< QgsComposerSymbolItem* >( item ); QgsComposerSymbolItem* symbolItem = dynamic_cast< QgsComposerSymbolItem* >( item );
if ( !symbolItem ) if ( !symbolItem )
{ {
@ -1304,7 +1312,7 @@ void QgsWMSServer::drawLegendSymbol( QgsComposerLegendItem* item, QPainter* p, d
void QgsWMSServer::drawPointSymbol( QPainter* p, QgsSymbol* s, double boxSpace, double currentY, double& symbolWidth, double& symbolHeight, double layerOpacity, double dpi ) const void QgsWMSServer::drawPointSymbol( QPainter* p, QgsSymbol* s, double boxSpace, double currentY, double& symbolWidth, double& symbolHeight, double layerOpacity, double dpi ) const
{ {
if ( !s || !p ) if ( !s )
{ {
return; return;
} }
@ -1371,14 +1379,9 @@ void QgsWMSServer::drawLineSymbol( QPainter* p, QgsSymbol* s, double boxSpace, d
p->restore(); p->restore();
} }
void QgsWMSServer::drawLegendSymbolV2( QgsComposerLegendItem* item, QPainter* p, double boxSpace, double currentY, double symbolWidth, void QgsWMSServer::drawLegendSymbolV2( QgsComposerLegendItem* item, QPainter* p, double boxSpace, double currentY, double& symbolWidth,
double symbolHeight, double dpi, double yDownShift ) const double& symbolHeight, double dpi, double yDownShift ) const
{ {
if ( !p )
{
return;
}
QgsComposerSymbolV2Item* symbolItem = dynamic_cast< QgsComposerSymbolV2Item* >( item ); QgsComposerSymbolV2Item* symbolItem = dynamic_cast< QgsComposerSymbolV2Item* >( item );
if ( !symbolItem ) if ( !symbolItem )
{ {
@ -1390,13 +1393,24 @@ void QgsWMSServer::drawLegendSymbolV2( QgsComposerLegendItem* item, QPainter* p,
return; 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;
}
double rasterScaleFactor = dpi / 2.0 / 25.4; double rasterScaleFactor = dpi / 2.0 / 25.4;
p->save(); if ( p )
p->translate( boxSpace, currentY + yDownShift ); {
p->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor ); p->save();
symbol->drawPreviewIcon( p, QSize( symbolWidth * rasterScaleFactor, symbolHeight * rasterScaleFactor ) ); p->translate( boxSpace, currentY + yDownShift );
p->restore(); p->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
symbol->drawPreviewIcon( p, QSize( symbolWidth * rasterScaleFactor, symbolHeight * rasterScaleFactor ) );
p->restore();
}
} }
void QgsWMSServer::drawRasterSymbol( QgsComposerLegendItem* item, QPainter* p, double boxSpace, double currentY, double symbolWidth, double symbolHeight, double yDownShift ) const void QgsWMSServer::drawRasterSymbol( QgsComposerLegendItem* item, QPainter* p, double boxSpace, double currentY, double symbolWidth, double symbolHeight, double yDownShift ) const

View File

@ -118,7 +118,12 @@ class QgsWMSServer
QStringList layerSet( const QStringList& layersList, const QStringList& stylesList, const QgsCoordinateReferenceSystem& destCRS ) const; QStringList layerSet( const QStringList& layersList, const QStringList& stylesList, const QgsCoordinateReferenceSystem& destCRS ) const;
//helper functions for GetLegendGraphics //helper functions for GetLegendGraphics
void drawLegendLayerItem( QgsComposerLayerItem* item, QPainter* p, double& maxX, double& currentY, const QFont& layerFont, /**Draws layer item and subitems
@param p painter if the item should be drawn, if 0 the size parameters are calculated only
@param maxTextWidth Includes boxSpace (on the right side). If p==0: maximumTextWidth is calculated, if p: maxTextWidth parameter is used for rendering
@param maxSymbolWidth Includes boxSpace and iconLabelSpace. If p==0: maximum Symbol width is calculated, if p: maxSymbolWidth is input parameter
*/
void drawLegendLayerItem( QgsComposerLayerItem* item, QPainter* p, double& maxTextWidth, double& maxSymbolWidth, double& currentY, const QFont& layerFont,
const QFont& itemFont, double boxSpace, double layerSpace, double symbolSpace, double iconLabelSpace, const QFont& itemFont, double boxSpace, double layerSpace, double symbolSpace, double iconLabelSpace,
double symbolWidth, double symbolHeight, double fontOversamplingFactor, double dpi ) const; double symbolWidth, double symbolHeight, double fontOversamplingFactor, double dpi ) const;
/**Draws a (old generation) symbol. Optionally, maxHeight is adapted (e.g. for large point markers) */ /**Draws a (old generation) symbol. Optionally, maxHeight is adapted (e.g. for large point markers) */
@ -127,7 +132,7 @@ class QgsWMSServer
void drawPointSymbol( QPainter* p, QgsSymbol* s, double boxSpace, double currentY, double& symbolWidth, double& symbolHeight, double layerOpacity, double dpi ) const; void drawPointSymbol( QPainter* p, QgsSymbol* s, double boxSpace, double currentY, double& symbolWidth, double& symbolHeight, double layerOpacity, double dpi ) const;
void drawLineSymbol( QPainter* p, QgsSymbol* s, double boxSpace, double currentY, double symbolWidth, double symbolHeight, double layerOpacity, double yDownShift ) const; void drawLineSymbol( QPainter* p, QgsSymbol* s, double boxSpace, double currentY, double symbolWidth, double symbolHeight, double layerOpacity, double yDownShift ) const;
void drawPolygonSymbol( QPainter* p, QgsSymbol* s, double boxSpace, double currentY, double symbolWidth, double symbolHeight, double layerOpacity, double yDownShift ) const; void drawPolygonSymbol( QPainter* p, QgsSymbol* s, double boxSpace, double currentY, double symbolWidth, double symbolHeight, double layerOpacity, double yDownShift ) const;
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 dpi, double yDownShift ) const;
void drawRasterSymbol( 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;
/**Map containing the WMS parameters*/ /**Map containing the WMS parameters*/