Skip to content
Permalink
Browse files

Add RULE parameter support in GetLegendGraphic

  • Loading branch information
Stéphane Brunner
Stéphane Brunner committed Oct 19, 2013
1 parent af5a3a5 commit a0eb3c64e0f132fc6889d74a81143ded18c227f6
@@ -286,7 +286,7 @@ void QgsComposerLayerItem::readXML( const QDomElement& itemElem, bool xServerAva
}
}

void QgsComposerLayerItem::setDefaultStyle( double scaleDenominator )
void QgsComposerLayerItem::setDefaultStyle( double scaleDenominator, QString rule )
{
// set default style according to number of symbols
QgsVectorLayer* vLayer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( layerID() ) );
@@ -295,8 +295,8 @@ void QgsComposerLayerItem::setDefaultStyle( double scaleDenominator )
QgsFeatureRendererV2* renderer = vLayer->rendererV2();
if ( renderer )
{
QPair<QString, QgsSymbolV2*> symbolItem = renderer->legendSymbolItems( scaleDenominator ).value( 0 );
if ( renderer->legendSymbolItems().size() > 1 || !symbolItem.first.isEmpty() )
QPair<QString, QgsSymbolV2*> symbolItem = renderer->legendSymbolItems( scaleDenominator, rule ).value( 0 );
if ( renderer->legendSymbolItems( scaleDenominator, rule ).size() > 1 || !symbolItem.first.isEmpty() )
{
setStyle( QgsComposerLegendStyle::Subgroup );
}
@@ -138,7 +138,7 @@ class CORE_EXPORT QgsComposerLayerItem : public QgsComposerLegendItem
void setShowFeatureCount( bool show ) { mShowFeatureCount = show; }
bool showFeatureCount() const { return mShowFeatureCount; }

void setDefaultStyle( double scaleDenominator = -1 );
void setDefaultStyle( double scaleDenominator = -1, QString rule = "" );

private:
QString mLayerID;
@@ -98,7 +98,7 @@ void QgsLegendModel::setLayerSetAndGroups( const QStringList& layerIds, const QL
}
}

void QgsLegendModel::setLayerSet( const QStringList& layerIds, double scaleDenominator )
void QgsLegendModel::setLayerSet( const QStringList& layerIds, double scaleDenominator, QString rule )
{
mLayerIds = layerIds;

@@ -111,7 +111,7 @@ void QgsLegendModel::setLayerSet( const QStringList& layerIds, double scaleDenom
for ( ; idIter != mLayerIds.constEnd(); ++idIter )
{
currentLayer = QgsMapLayerRegistry::instance()->mapLayer( *idIter );
addLayer( currentLayer, scaleDenominator );
addLayer( currentLayer, scaleDenominator, rule );
}
}

@@ -135,7 +135,7 @@ QStandardItem* QgsLegendModel::addGroup( QString text, int position )
return groupItem;
}

int QgsLegendModel::addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLayer* vlayer, double scaleDenominator )
int QgsLegendModel::addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLayer* vlayer, double scaleDenominator, QString rule )
{
QgsComposerLayerItem* lItem = dynamic_cast<QgsComposerLayerItem*>( layerItem );

@@ -158,12 +158,12 @@ int QgsLegendModel::addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLa
}
}

QgsLegendSymbolList lst = renderer->legendSymbolItems( scaleDenominator );
QgsLegendSymbolList lst = renderer->legendSymbolItems( scaleDenominator, rule );
QgsLegendSymbolList::const_iterator symbolIt = lst.constBegin();
int row = 0;
for ( ; symbolIt != lst.constEnd(); ++symbolIt )
{
if ( scaleDenominator == -1 )
if ( scaleDenominator == -1 && rule.isEmpty() )
{
QgsComposerSymbolV2Item* currentSymbolItem = new QgsComposerSymbolV2Item( "" );

@@ -200,7 +200,8 @@ int QgsLegendModel::addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLa
}
}

if ( scaleDenominator == -1 )
// Don't remove row on getLegendGraphic (read only with filter)
if ( scaleDenominator == -1 && rule.isEmpty() )
{
// Delete following old items (if current number of items decreased)
for ( int i = layerItem->rowCount() - 1; i >= row; --i )
@@ -467,7 +468,7 @@ void QgsLegendModel::removeLayer( const QString& layerId )
}
}

void QgsLegendModel::addLayer( QgsMapLayer* theMapLayer, double scaleDenominator )
void QgsLegendModel::addLayer( QgsMapLayer* theMapLayer, double scaleDenominator, QString rule )
{
if ( !theMapLayer )
{
@@ -481,7 +482,7 @@ void QgsLegendModel::addLayer( QgsMapLayer* theMapLayer, double scaleDenominator
layerItem->setUserText( theMapLayer->title() );
}
layerItem->setLayerID( theMapLayer->id() );
layerItem->setDefaultStyle( scaleDenominator );
layerItem->setDefaultStyle( scaleDenominator, rule );
layerItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );

QList<QStandardItem *> itemsList;
@@ -495,7 +496,7 @@ void QgsLegendModel::addLayer( QgsMapLayer* theMapLayer, double scaleDenominator
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( theMapLayer );
if ( vl )
{
addVectorLayerItemsV2( layerItem, vl, scaleDenominator );
addVectorLayerItemsV2( layerItem, vl, scaleDenominator, rule );
}
break;
}
@@ -54,7 +54,7 @@ class CORE_EXPORT QgsLegendModel: public QStandardItemModel

/**Sets layer set and groups*/
void setLayerSetAndGroups( const QStringList& layerIds, const QList< GroupLayerInfo >& groupInfo );
void setLayerSet( const QStringList& layerIds, double scaleDenominator = -1 );
void setLayerSet( const QStringList& layerIds, double scaleDenominator = -1, QString rule = "" );
/**Adds a group
@param text name of group (defaults to translation of "Group")
@param position insertion position (toplevel position (or -1 if it should be placed at the end of the legend).
@@ -97,14 +97,14 @@ class CORE_EXPORT QgsLegendModel: public QStandardItemModel

public slots:
void removeLayer( const QString& layerId );
void addLayer( QgsMapLayer* theMapLayer, double scaleDenominator = -1 );
void addLayer( QgsMapLayer* theMapLayer, double scaleDenominator = -1, QString rule="" );

signals:
void layersChanged();

private:
/**Adds classification items of vector layers using new symbology*/
int addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLayer* vlayer, double scaleDenominator = -1 );
int addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLayer* vlayer, double scaleDenominator = -1, QString rule = "" );

/**Adds item of raster layer
@return 0 in case of success*/
@@ -507,7 +507,7 @@ QgsLegendSymbologyList QgsFeatureRendererV2::legendSymbologyItems( QSize iconSiz
return QgsLegendSymbologyList();
}

QgsLegendSymbolList QgsFeatureRendererV2::legendSymbolItems( double scaleDenominator )
QgsLegendSymbolList QgsFeatureRendererV2::legendSymbolItems( double scaleDenominator, QString rule )
{
Q_UNUSED( scaleDenominator );
return QgsLegendSymbolList();
@@ -149,7 +149,7 @@ class CORE_EXPORT QgsFeatureRendererV2
//! return a list of item text / symbol
//! @note: this method was added in version 1.5
//! @note: not available in python bindings
virtual QgsLegendSymbolList legendSymbolItems( double scaleDenominator = -1 );
virtual QgsLegendSymbolList legendSymbolItems( double scaleDenominator = -1, QString rule = "" );

//! set type and size of editing vertex markers for subsequent rendering
void setVertexMarkerAppearance( int type, int size );
@@ -175,10 +175,10 @@ void QgsRuleBasedRendererV2::Rule::setSymbol( QgsSymbolV2* sym )
mSymbol = sym;
}

QgsLegendSymbolList QgsRuleBasedRendererV2::Rule::legendSymbolItems( double scaleDenominator )
QgsLegendSymbolList QgsRuleBasedRendererV2::Rule::legendSymbolItems( double scaleDenominator, QString ruleFilter )
{
QgsLegendSymbolList lst;
if ( mSymbol )
if ( mSymbol && ( ruleFilter.isEmpty() || mLabel == ruleFilter ) )
lst << qMakePair( mLabel, mSymbol );

for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
@@ -188,7 +188,7 @@ QgsLegendSymbolList QgsRuleBasedRendererV2::Rule::legendSymbolItems( double scal
( rule->mScaleMinDenom == -1 || rule->mScaleMinDenom < scaleDenominator ) &&
( rule->mScaleMaxDenom == -1 || scaleDenominator < rule->mScaleMaxDenom ) ) )
{
lst << rule->legendSymbolItems( scaleDenominator );
lst << rule->legendSymbolItems( scaleDenominator, ruleFilter );
}
}
return lst;
@@ -849,9 +849,9 @@ QgsLegendSymbologyList QgsRuleBasedRendererV2::legendSymbologyItems( QSize iconS
return lst;
}

QgsLegendSymbolList QgsRuleBasedRendererV2::legendSymbolItems( double scaleDenominator )
QgsLegendSymbolList QgsRuleBasedRendererV2::legendSymbolItems( double scaleDenominator, QString rule )
{
return mRootRule->legendSymbolItems( scaleDenominator );
return mRootRule->legendSymbolItems( scaleDenominator, rule );
}


@@ -93,7 +93,7 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
QSet<QString> usedAttributes();
QgsSymbolV2List symbols();
//! @note not available in python bindings
QgsLegendSymbolList legendSymbolItems( double scaleDenominator = -1 );
QgsLegendSymbolList legendSymbolItems( double scaleDenominator = -1, QString rule = "" );
bool isFilterOK( QgsFeature& f ) const;
bool isScaleOK( double scale ) const;

@@ -226,7 +226,7 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
//! return a list of item text / symbol
//! @note: this method was added in version 1.5
//! @note not available in python bindings
virtual QgsLegendSymbolList legendSymbolItems( double scaleDenominator = -1 );
virtual QgsLegendSymbolList legendSymbolItems( double scaleDenominator = -1, QString rule = "" );

//! for debugging
virtual QString dump() const;
@@ -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 )
@@ -354,13 +351,81 @@ 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, theImage->dotsPerMeterX() * 0.0254, 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 );

0 comments on commit a0eb3c6

Please sign in to comment.
You can’t perform that action at this time.