refactor to a more general convertFromRenderer function

This commit is contained in:
Leyan 2014-08-30 10:16:23 -06:00
parent 11d159cd85
commit 9931dde90a
29 changed files with 369 additions and 332 deletions

View File

@ -55,7 +55,7 @@ class QgsCategorizedSymbolRendererV2 : QgsFeatureRendererV2
virtual QString dump() const;
virtual QgsFeatureRendererV2* clone() /Factory/;
virtual QgsFeatureRendererV2* clone() const /Factory/;
virtual void toSld( QDomDocument& doc, QDomElement &element ) const;
@ -147,9 +147,10 @@ class QgsCategorizedSymbolRendererV2 : QgsFeatureRendererV2
// @note added in 2.5
virtual void checkLegendSymbolItem( QString key, bool state = true );
//! convert the renderer to a rule based renderer with equivalent rules
//! creates a QgsCategorizedSymbolRendererV2 from an existing renderer.
//! @note added in 2.5
virtual QgsRuleBasedRendererV2* convertToRuleBasedRenderer() /Factory/;
//! @returns a new renderer if the conversion was possible, otherwise 0.
static QgsCategorizedSymbolRendererV2* convertFromRenderer( const QgsFeatureRendererV2 *renderer ) /Factory/;
protected:
void rebuildHash();

View File

@ -59,7 +59,7 @@ class QgsGraduatedSymbolRendererV2 : QgsFeatureRendererV2
virtual QString dump() const;
virtual QgsFeatureRendererV2* clone() /Factory/;
virtual QgsFeatureRendererV2* clone() const /Factory/;
virtual void toSld( QDomDocument& doc, QDomElement &element ) const;
@ -173,11 +173,10 @@ class QgsGraduatedSymbolRendererV2 : QgsFeatureRendererV2
// @note added in 2.5
virtual void checkLegendSymbolItem( QString key, bool state = true );
//! convert the renderer to a rule based renderer with equivalent rules
//! creates a QgsGraduatedSymbolRendererV2 from an existing renderer.
//! @note added in 2.5
virtual QgsRuleBasedRendererV2* convertToRuleBasedRenderer() /Factory/;
//! @returns a new renderer if the conversion was possible, otherwise 0.
static QgsGraduatedSymbolRendererV2* convertFromRenderer( const QgsFeatureRendererV2 *renderer ) /Factory/;
protected:
QgsSymbolV2* symbolForValue( double value );

View File

@ -12,7 +12,7 @@ class QgsInvertedPolygonRenderer : QgsFeatureRendererV2
virtual ~QgsInvertedPolygonRenderer();
/** Used to clone this feature renderer.*/
virtual QgsFeatureRendererV2* clone() /Factory/;
virtual QgsFeatureRendererV2* clone() const /Factory/;
virtual void startRender( QgsRenderContext& context, const QgsFields& fields );
@ -81,4 +81,10 @@ class QgsInvertedPolygonRenderer : QgsFeatureRendererV2
This will involve some CPU-demanding computations and is thus disabled by default.
*/
void setPreprocessingEnabled( bool enabled );
/** creates a QgsInvertedPolygonRenderer by a conversion from an existing renderer.
@note added in 2.5
@returns a new renderer if the conversion was possible, otherwise 0.
*/
static QgsInvertedPolygonRenderer* convertFromRenderer( const QgsFeatureRendererV2* renderer ) /Factory/;
};

View File

@ -7,7 +7,7 @@ class QgsPointDisplacementRenderer : QgsFeatureRendererV2
QgsPointDisplacementRenderer( const QString& labelAttributeName = "" );
~QgsPointDisplacementRenderer();
QgsFeatureRendererV2* clone() /Factory/;
QgsFeatureRendererV2* clone() const /Factory/;
virtual void toSld( QDomDocument& doc, QDomElement &element ) const;
@ -69,6 +69,11 @@ class QgsPointDisplacementRenderer : QgsFeatureRendererV2
void setTolerance( double t );
double tolerance() const;
//! creates a QgsPointDisplacementRenderer from an existing renderer.
//! @note added in 2.5
//! @returns a new renderer if the conversion was possible, otherwise 0.
static QgsPointDisplacementRenderer* convertFromRenderer(const QgsFeatureRendererV2 *renderer ) /Factory/;
private:
QgsPointDisplacementRenderer( const QgsPointDisplacementRenderer & );
QgsPointDisplacementRenderer & operator=( const QgsPointDisplacementRenderer & );

View File

@ -71,7 +71,7 @@ class QgsFeatureRendererV2
virtual ~QgsFeatureRendererV2();
virtual QgsFeatureRendererV2* clone() = 0 /Factory/;
virtual QgsFeatureRendererV2* clone() const = 0 /Factory/;
virtual bool renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer = -1, bool selected = false, bool drawVertexMarker = false );
@ -175,10 +175,6 @@ class QgsFeatureRendererV2
//! @note added in 1.9
virtual QgsSymbolV2List symbolsForFeature( QgsFeature& feat );
//! convert the renderer to a rule based renderer with equivalent rules, if possible
//! @note added in 2.5
virtual QgsRuleBasedRendererV2* convertToRuleBasedRenderer() /Factory/;
protected:
QgsFeatureRendererV2( QString type );

View File

@ -164,7 +164,7 @@ class QgsRuleBasedRendererV2 : QgsFeatureRendererV2
virtual QList<QString> usedAttributes();
virtual QgsFeatureRendererV2* clone() /Factory/;
virtual QgsFeatureRendererV2* clone() const /Factory/;
virtual void toSld( QDomDocument& doc, QDomElement &element ) const;
@ -231,9 +231,13 @@ class QgsRuleBasedRendererV2 : QgsFeatureRendererV2
//! take a rule and create a list of new rules with intervals of scales given by the passed scale denominators
static void refineRuleScales( QgsRuleBasedRendererV2::Rule* initialRule, QList<int> scales );
//! convert the renderer to a rule based renderer with equivalent rules, if possible
//! creates a QgsRuleBasedRendererV2 from an existing renderer.
//! @note added in 2.5
virtual QgsRuleBasedRendererV2* convertToRuleBasedRenderer() /Factory/;
//! @returns a new renderer if the conversion was possible, otherwise 0.
static QgsRuleBasedRendererV2* convertFromRenderer( const QgsFeatureRendererV2 *renderer ) /Factory/;
//! helper function to convert the size scale and rotation fields present in some other renderers to data defined symbology
static void convertToDataDefinedSymbology( QgsSymbolV2* symbol, QString sizeScaleField, QString rotationField );
private:
QgsRuleBasedRendererV2( const QgsRuleBasedRendererV2 & );

View File

@ -37,7 +37,7 @@ class QgsSingleSymbolRendererV2 : QgsFeatureRendererV2
virtual QString dump() const;
virtual QgsFeatureRendererV2* clone() /Factory/;
virtual QgsFeatureRendererV2* clone() const /Factory/;
virtual void toSld( QDomDocument& doc, QDomElement &element ) const;
static QgsFeatureRendererV2* createFromSld( QDomElement& element, QGis::GeometryType geomType );
@ -66,9 +66,10 @@ class QgsSingleSymbolRendererV2 : QgsFeatureRendererV2
//! @note added in 2.6
virtual QgsLegendSymbolListV2 legendSymbolItemsV2() const;
//! convert the renderer to a rule based renderer with equivalent rules
//! creates a QgsSingleSymbolRendererV2 from an existing renderer.
//! @note added in 2.5
virtual QgsRuleBasedRendererV2* convertToRuleBasedRenderer() /Factory/;
//! @returns a new renderer if the conversion was possible, otherwise 0.
static QgsSingleSymbolRendererV2* convertFromRenderer( const QgsFeatureRendererV2 *renderer ) /Factory/;
private:
QgsSingleSymbolRendererV2( const QgsSingleSymbolRendererV2 & );

View File

@ -19,7 +19,8 @@
#include "qgssymbolv2.h"
#include "qgssymbollayerv2utils.h"
#include "qgsvectorcolorrampv2.h"
#include "qgsrulebasedrendererv2.h"
#include "qgspointdisplacementrenderer.h"
#include "qgsinvertedpolygonrenderer.h"
#include "qgsfeature.h"
#include "qgsvectorlayer.h"
@ -463,7 +464,7 @@ QString QgsCategorizedSymbolRendererV2::dump() const
return s;
}
QgsFeatureRendererV2* QgsCategorizedSymbolRendererV2::clone()
QgsFeatureRendererV2* QgsCategorizedSymbolRendererV2::clone() const
{
QgsCategorizedSymbolRendererV2* r = new QgsCategorizedSymbolRendererV2( mAttrName, mCategories );
if ( mSourceSymbol.data() )
@ -760,93 +761,21 @@ void QgsCategorizedSymbolRendererV2::checkLegendSymbolItem( QString key, bool st
QgsMarkerSymbolV2 QgsCategorizedSymbolRendererV2::sSkipRender;
QgsRuleBasedRendererV2* QgsCategorizedSymbolRendererV2::convertToRuleBasedRenderer()
QgsCategorizedSymbolRendererV2* QgsCategorizedSymbolRendererV2::convertFromRenderer( const QgsFeatureRendererV2 *renderer )
{
QgsRuleBasedRendererV2::Rule* rootrule = new QgsRuleBasedRendererV2::Rule( NULL );
QString expression;
QString sizeExpression;
QString value;
for ( int i = 0; i < mCategories.size();++i )
if ( renderer->type() == "categorizedSymbol" )
{
QgsRuleBasedRendererV2::Rule* rule = new QgsRuleBasedRendererV2::Rule( NULL );
rule->setLabel( mCategories[i].label() );
//We first define the rule corresponding to the category
//If the value is a number, we can use it directly, otherwise we need to quote it in the rule
if ( QVariant( mCategories[i].value() ).convert( QVariant::Double ) )
{
value = mCategories[i].value().toString();
}
else
{
value = "'" + mCategories[i].value().toString() + "'";
}
//An empty category is equivalent to the ELSE keyword
if ( value == "''" )
expression = "ELSE";
else
expression = classAttribute() + " = " + value;
rule->setFilterExpression( expression );
//Then we construct an equivalent symbol.
//Ideally we could simply copy the symbol, but the categorized renderer allows a separate interface to specify
//data dependent area and rotation, so we need to convert these to obtain the same rendering
QgsSymbolV2* origSymbol = mCategories[i].symbol()->clone();
switch ( origSymbol->type() )
{
case QgsSymbolV2::Marker:
for ( int j = 0; j < origSymbol->symbolLayerCount();++j )
{
QgsMarkerSymbolLayerV2* msl = static_cast<QgsMarkerSymbolLayerV2*>( origSymbol->symbolLayer( j ) );
if ( mSizeScale.data() )
{
sizeExpression = QString( "%1*(%2)" ).arg( msl->size() ).arg( sizeScaleField() );
msl->setDataDefinedProperty( "size", sizeExpression );
}
if ( mRotation.data() )
{
msl->setDataDefinedProperty( "angle", rotationField() );
}
}
break;
case QgsSymbolV2::Line:
if ( mSizeScale.data() )
{
for ( int j = 0; j < origSymbol->symbolLayerCount();++j )
{
if ( origSymbol->symbolLayer( j )->layerType() == "SimpleLine" )
{
QgsLineSymbolLayerV2* lsl = static_cast<QgsLineSymbolLayerV2*>( origSymbol->symbolLayer( j ) );
sizeExpression = QString( "%1*(%2)" ).arg( lsl->width() ).arg( sizeScaleField() );
lsl->setDataDefinedProperty( "width", sizeExpression );
}
if ( origSymbol->symbolLayer( j )->layerType() == "MarkerLine" )
{
QgsSymbolV2* marker = origSymbol->symbolLayer( j )->subSymbol();
for ( int k = 0; k < marker->symbolLayerCount();++k )
{
QgsMarkerSymbolLayerV2* msl = static_cast<QgsMarkerSymbolLayerV2*>( marker->symbolLayer( k ) );
sizeExpression = QString( "%1*(%2)" ).arg( msl->size() ).arg( sizeScaleField() );
msl->setDataDefinedProperty( "size", sizeExpression );
}
}
}
}
break;
default:
break;
}
rule->setSymbol( origSymbol );
rootrule->appendChild( rule );
return dynamic_cast<QgsCategorizedSymbolRendererV2*>( renderer->clone() );
}
return new QgsRuleBasedRendererV2( rootrule );
if ( renderer->type() == "pointDisplacement" )
{
const QgsPointDisplacementRenderer* pointDisplacementRenderer = dynamic_cast<const QgsPointDisplacementRenderer*>( renderer );
return convertFromRenderer( pointDisplacementRenderer->embeddedRenderer() );
}
if ( renderer->type() == "invertedPolygonRenderer" )
{
const QgsInvertedPolygonRenderer* invertedPolygonRenderer = dynamic_cast<const QgsInvertedPolygonRenderer*>( renderer );
return convertFromRenderer( invertedPolygonRenderer->embeddedRenderer() );
}
return 0;
}

View File

@ -24,7 +24,6 @@
class QgsVectorColorRampV2;
class QgsVectorLayer;
class QgsRuleBasedRendererV2;
/* \brief categorized renderer */
class CORE_EXPORT QgsRendererCategoryV2
@ -86,7 +85,7 @@ class CORE_EXPORT QgsCategorizedSymbolRendererV2 : public QgsFeatureRendererV2
virtual QString dump() const;
virtual QgsFeatureRendererV2* clone();
virtual QgsFeatureRendererV2* clone() const;
virtual void toSld( QDomDocument& doc, QDomElement &element ) const;
@ -166,9 +165,8 @@ class CORE_EXPORT QgsCategorizedSymbolRendererV2 : public QgsFeatureRendererV2
//! @note added in 2.0
QgsSymbolV2::ScaleMethod scaleMethod() const { return mScaleMethod; }
//! items of symbology items in legend should be checkable
// @note added in 2.5
//! @note added in 2.5
virtual bool legendSymbolItemsCheckable() const;
//! item in symbology was checked
@ -183,9 +181,10 @@ class CORE_EXPORT QgsCategorizedSymbolRendererV2 : public QgsFeatureRendererV2
//! @note added in 2.6
virtual QString legendClassificationAttribute() const { return classAttribute(); }
//! convert the renderer to a rule based renderer with equivalent rules
//! creates a QgsCategorizedSymbolRendererV2 from an existing renderer.
//! @note added in 2.5
virtual QgsRuleBasedRendererV2* convertToRuleBasedRenderer();
//! @returns a new renderer if the conversion was possible, otherwise 0.
static QgsCategorizedSymbolRendererV2* convertFromRenderer( const QgsFeatureRendererV2 *renderer );
protected:
QString mAttrName;

View File

@ -17,7 +17,8 @@
#include "qgssymbolv2.h"
#include "qgssymbollayerv2utils.h"
#include "qgsvectorcolorrampv2.h"
#include "qgsrulebasedrendererv2.h"
#include "qgspointdisplacementrenderer.h"
#include "qgsinvertedpolygonrenderer.h"
#include "qgsfeature.h"
#include "qgsvectorlayer.h"
@ -358,7 +359,7 @@ QString QgsGraduatedSymbolRendererV2::dump() const
return s;
}
QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::clone()
QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::clone() const
{
QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2( mAttrName, mRanges );
r->setMode( mMode );
@ -1312,85 +1313,21 @@ void QgsGraduatedSymbolRendererV2::sortByLabel( Qt::SortOrder order )
}
}
QgsRuleBasedRendererV2* QgsGraduatedSymbolRendererV2::convertToRuleBasedRenderer()
QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::convertFromRenderer( const QgsFeatureRendererV2 *renderer )
{
QgsRuleBasedRendererV2::Rule* rootrule = new QgsRuleBasedRendererV2::Rule( NULL );
QString sizeExpression;
QString expression;
for ( int i = 0; i < mRanges.size();++i )
if ( renderer->type() == "graduatedSymbol" )
{
QgsRuleBasedRendererV2::Rule* rule = new QgsRuleBasedRendererV2::Rule( NULL );
rule->setSymbol( mRanges[i].symbol() );
rule->setLabel( mRanges[i].label() );
if ( i == 0 )//The lower boundary of the first range is included, while it is excluded for the others
{
expression = classAttribute() + " >= " + QString::number( mRanges[i].lowerValue(), 'f' ) + " AND " + \
classAttribute() + " <= " + QString::number( mRanges[i].upperValue(), 'f' );
}
else
{
expression = classAttribute() + " > " + QString::number( mRanges[i].lowerValue(), 'f' ) + " AND " + \
classAttribute() + " <= " + QString::number( mRanges[i].upperValue(), 'f' );
}
rule->setFilterExpression( expression );
//Then we construct an equivalent symbol.
//Ideally we could simply copy the symbol, but the graduated renderer allows a separate interface to specify
//data dependent area and rotation, so we need to convert these to obtain the same rendering
QgsSymbolV2* origSymbol = mRanges[i].symbol()->clone();
switch ( origSymbol->type() )
{
case QgsSymbolV2::Marker:
for ( int j = 0; j < origSymbol->symbolLayerCount();++j )
{
QgsMarkerSymbolLayerV2* msl = static_cast<QgsMarkerSymbolLayerV2*>( origSymbol->symbolLayer( j ) );
if ( mSizeScale.data() )
{
sizeExpression = QString( "%1*(%2)" ).arg( msl->size() ).arg( sizeScaleField() );
msl->setDataDefinedProperty( "size", sizeExpression );
if ( mRotation.data() )
{
msl->setDataDefinedProperty( "angle", rotationField() );
}
}
}
break;
case QgsSymbolV2::Line:
if ( mSizeScale.data() )
{
for ( int j = 0; j < origSymbol->symbolLayerCount();++j )
{
if ( origSymbol->symbolLayer( j )->layerType() == "SimpleLine" )
{
QgsLineSymbolLayerV2* lsl = static_cast<QgsLineSymbolLayerV2*>( origSymbol->symbolLayer( j ) );
sizeExpression = QString( "%1*(%2)" ).arg( lsl->width() ).arg( sizeScaleField() );
lsl->setDataDefinedProperty( "width", sizeExpression );
}
if ( origSymbol->symbolLayer( j )->layerType() == "MarkerLine" )
{
QgsSymbolV2* marker = origSymbol->symbolLayer( j )->subSymbol();
for ( int k = 0; k < marker->symbolLayerCount();++k )
{
QgsMarkerSymbolLayerV2* msl = static_cast<QgsMarkerSymbolLayerV2*>( marker->symbolLayer( k ) );
sizeExpression = QString( "%1*(%2)" ).arg( msl->size() ).arg( sizeScaleField() );
msl->setDataDefinedProperty( "size", sizeExpression );
}
}
}
}
break;
default:
break;
}
rule->setSymbol( origSymbol );
rootrule->appendChild( rule );
return dynamic_cast<QgsGraduatedSymbolRendererV2*>( renderer->clone() );
}
return new QgsRuleBasedRendererV2( rootrule );
if ( renderer->type() == "pointDisplacement" )
{
const QgsPointDisplacementRenderer* pointDisplacementRenderer = dynamic_cast<const QgsPointDisplacementRenderer*>( renderer );
return convertFromRenderer( pointDisplacementRenderer->embeddedRenderer() );
}
if ( renderer->type() == "invertedPolygonRenderer" )
{
const QgsInvertedPolygonRenderer* invertedPolygonRenderer = dynamic_cast<const QgsInvertedPolygonRenderer*>( renderer );
return convertFromRenderer( invertedPolygonRenderer->embeddedRenderer() );
}
return 0;
}

View File

@ -64,7 +64,6 @@ typedef QList<QgsRendererRangeV2> QgsRangeList;
class QgsVectorLayer;
class QgsVectorColorRampV2;
class QgsRuleBasedRenderedV2;
class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
{
@ -84,7 +83,7 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
virtual QString dump() const;
virtual QgsFeatureRendererV2* clone();
virtual QgsFeatureRendererV2* clone() const;
virtual void toSld( QDomDocument& doc, QDomElement &element ) const;
@ -97,7 +96,7 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
QString classAttribute() const { return mAttrName; }
void setClassAttribute( QString attr ) { mAttrName = attr; }
const QgsRangeList& ranges() { return mRanges; }
const QgsRangeList& ranges() const { return mRanges; }
bool updateRangeSymbol( int rangeIndex, QgsSymbolV2* symbol );
bool updateRangeLabel( int rangeIndex, QString label );
@ -169,7 +168,7 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
*/
void updateColorRamp( QgsVectorColorRampV2* ramp, bool inverted = false );
/** Update the all symbols but leave breaks and colors. */
/** Update all the symbols but leave breaks and colors. */
void updateSymbols( QgsSymbolV2* sym );
//! @note added in 1.6
@ -188,7 +187,7 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
QgsSymbolV2::ScaleMethod scaleMethod() const { return mScaleMethod; }
//! items of symbology items in legend should be checkable
// @note added in 2.5
//! @note added in 2.5
virtual bool legendSymbolItemsCheckable() const;
//! item in symbology was checked
@ -203,9 +202,10 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
//! @note added in 2.6
virtual QString legendClassificationAttribute() const { return classAttribute(); }
//! convert the renderer to a rule based renderer with equivalent rules
//! creates a QgsGraduatedSymbolRendererV2 from an existing renderer.
//! @note added in 2.5
virtual QgsRuleBasedRendererV2* convertToRuleBasedRenderer();
//! @returns a new renderer if the conversion was possible, otherwise 0.
static QgsGraduatedSymbolRendererV2* convertFromRenderer( const QgsFeatureRendererV2 *renderer );
protected:
QString mAttrName;

View File

@ -325,7 +325,7 @@ QString QgsInvertedPolygonRenderer::dump() const
return "INVERTED [" + mSubRenderer->dump() + "]";
}
QgsFeatureRendererV2* QgsInvertedPolygonRenderer::clone()
QgsFeatureRendererV2* QgsInvertedPolygonRenderer::clone() const
{
QgsInvertedPolygonRenderer* newRenderer;
if ( mSubRenderer.isNull() )
@ -440,3 +440,20 @@ bool QgsInvertedPolygonRenderer::willRenderFeature( QgsFeature& feat )
return mSubRenderer->willRenderFeature( feat );
}
QgsInvertedPolygonRenderer* QgsInvertedPolygonRenderer::convertFromRenderer( const QgsFeatureRendererV2 *renderer )
{
if ( renderer->type() == "invertedPolygonRenderer" )
{
return dynamic_cast<QgsInvertedPolygonRenderer*>( renderer->clone() );
}
if ( renderer->type() == "singleSymbol" ||
renderer->type() == "categorizedSymbol" ||
renderer->type() == "graduatedSymbol" ||
renderer->type() == "ruleRenderer" )
{
return new QgsInvertedPolygonRenderer( renderer->clone() );
}
return 0;
}

View File

@ -48,7 +48,7 @@ class CORE_EXPORT QgsInvertedPolygonRenderer : public QgsFeatureRendererV2
virtual ~QgsInvertedPolygonRenderer();
/** Used to clone this feature renderer.*/
virtual QgsFeatureRendererV2* clone();
virtual QgsFeatureRendererV2* clone() const;
virtual void startRender( QgsRenderContext& context, const QgsFields& fields );
@ -118,6 +118,12 @@ class CORE_EXPORT QgsInvertedPolygonRenderer : public QgsFeatureRendererV2
*/
void setPreprocessingEnabled( bool enabled ) { mPreprocessingEnabled = enabled; }
/** creates a QgsInvertedPolygonRenderer by a conversion from an existing renderer.
@note added in 2.5
@returns a new renderer if the conversion was possible, otherwise 0.
*/
static QgsInvertedPolygonRenderer* convertFromRenderer( const QgsFeatureRendererV2* renderer );
private:
/** Private copy constructor. @see clone() */
QgsInvertedPolygonRenderer( const QgsInvertedPolygonRenderer& );

View File

@ -22,6 +22,7 @@
#include "qgssymbolv2.h"
#include "qgssymbollayerv2utils.h"
#include "qgsvectorlayer.h"
#include "qgssinglesymbolrendererv2.h"
#include <QDomElement>
#include <QPainter>
@ -49,7 +50,7 @@ QgsPointDisplacementRenderer::~QgsPointDisplacementRenderer()
delete mRenderer;
}
QgsFeatureRendererV2* QgsPointDisplacementRenderer::clone()
QgsFeatureRendererV2* QgsPointDisplacementRenderer::clone() const
{
QgsPointDisplacementRenderer* r = new QgsPointDisplacementRenderer( mLabelAttributeName );
r->setEmbeddedRenderer( mRenderer->clone() );
@ -517,4 +518,21 @@ QgsSymbolV2* QgsPointDisplacementRenderer::firstSymbolForFeature( QgsFeatureRend
return symbolList.at( 0 );
}
QgsPointDisplacementRenderer* QgsPointDisplacementRenderer::convertFromRenderer( const QgsFeatureRendererV2* renderer )
{
if ( renderer->type() == "pointDisplacement" )
{
return dynamic_cast<QgsPointDisplacementRenderer*>( renderer->clone() );
}
if ( renderer->type() == "singleSymbol" ||
renderer->type() == "categorizedSymbol" ||
renderer->type() == "graduatedSymbol" ||
renderer->type() == "ruleRenderer" )
{
QgsPointDisplacementRenderer* pointRenderer = new QgsPointDisplacementRenderer();
pointRenderer->setEmbeddedRenderer( renderer->clone() );
return pointRenderer;
}
return 0;
}

View File

@ -34,7 +34,7 @@ class CORE_EXPORT QgsPointDisplacementRenderer: public QgsFeatureRendererV2
QgsPointDisplacementRenderer( const QString& labelAttributeName = "" );
~QgsPointDisplacementRenderer();
QgsFeatureRendererV2* clone();
QgsFeatureRendererV2* clone() const;
virtual void toSld( QDomDocument& doc, QDomElement &element ) const;
@ -64,7 +64,7 @@ class CORE_EXPORT QgsPointDisplacementRenderer: public QgsFeatureRendererV2
/**Sets embedded renderer (takes ownership)*/
void setEmbeddedRenderer( QgsFeatureRendererV2* r );
QgsFeatureRendererV2* embeddedRenderer() { return mRenderer;}
QgsFeatureRendererV2* embeddedRenderer() const { return mRenderer;}
//! not available in python bindings
//! @deprecated since 2.4
@ -96,6 +96,11 @@ class CORE_EXPORT QgsPointDisplacementRenderer: public QgsFeatureRendererV2
void setTolerance( double t ) { mTolerance = t; }
double tolerance() const { return mTolerance; }
//! creates a QgsPointDisplacementRenderer from an existing renderer.
//! @note added in 2.5
//! @returns a new renderer if the conversion was possible, otherwise 0.
static QgsPointDisplacementRenderer* convertFromRenderer(const QgsFeatureRendererV2 *renderer );
private:
/**Embedded renderer. Like This, it is possible to use a classification together with point displacement*/

View File

@ -467,7 +467,7 @@ QgsFeatureRendererV2* QgsFeatureRendererV2::loadSld( const QDomNode &node, QGis:
QString rendererType;
if ( needRuleRenderer )
{
rendererType = "RuleRenderer";
rendererType = "ruleRenderer";
}
else
{
@ -586,8 +586,3 @@ QgsSymbolV2List QgsFeatureRendererV2::symbolsForFeature( QgsFeature& feat )
if ( s ) lst.append( s );
return lst;
}
QgsRuleBasedRendererV2* QgsFeatureRendererV2::convertToRuleBasedRenderer()
{
return 0;
}

View File

@ -31,7 +31,6 @@ class QgsRenderContext;
class QgsFeature;
class QgsFields;
class QgsVectorLayer;
class QgsRuleBasedRendererV2;
typedef QMap<QString, QString> QgsStringMap;
@ -97,7 +96,7 @@ class CORE_EXPORT QgsFeatureRendererV2
virtual ~QgsFeatureRendererV2() {}
virtual QgsFeatureRendererV2* clone() = 0;
virtual QgsFeatureRendererV2* clone() const = 0;
virtual bool renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer = -1, bool selected = false, bool drawVertexMarker = false );
@ -202,10 +201,6 @@ class CORE_EXPORT QgsFeatureRendererV2
//! @note added in 1.9
virtual QgsSymbolV2List symbolsForFeature( QgsFeature& feat );
//! convert the renderer to a rule based renderer with equivalent rules, if possible
//! @note added in 2.5
virtual QgsRuleBasedRendererV2* convertToRuleBasedRenderer();
protected:
QgsFeatureRendererV2( QString type );

View File

@ -33,11 +33,12 @@ QgsRendererV2Registry::QgsRendererV2Registry()
addRenderer( new QgsRendererV2Metadata( "categorizedSymbol",
QObject::tr( "Categorized" ),
QgsCategorizedSymbolRendererV2::create ) );
addRenderer( new QgsRendererV2Metadata( "graduatedSymbol",
QObject::tr( "Graduated" ),
QgsGraduatedSymbolRendererV2::create ) );
addRenderer( new QgsRendererV2Metadata( "RuleRenderer",
addRenderer( new QgsRendererV2Metadata( "ruleRenderer",
QObject::tr( "Rule-based" ),
QgsRuleBasedRendererV2::create,
QgsRuleBasedRendererV2::createFromSld ) );

View File

@ -21,6 +21,9 @@
#include "qgsvectorlayer.h"
#include "qgslogger.h"
#include "qgsogcutils.h"
#include "qgssinglesymbolrendererv2.h"
#include "qgspointdisplacementrenderer.h"
#include "qgsinvertedpolygonrenderer.h"
#include <QSet>
@ -726,12 +729,12 @@ QgsRuleBasedRendererV2::Rule* QgsRuleBasedRendererV2::Rule::createFromSld( QDomE
/////////////////////
QgsRuleBasedRendererV2::QgsRuleBasedRendererV2( QgsRuleBasedRendererV2::Rule* root )
: QgsFeatureRendererV2( "RuleRenderer" ), mRootRule( root )
: QgsFeatureRendererV2( "ruleRenderer" ), mRootRule( root )
{
}
QgsRuleBasedRendererV2::QgsRuleBasedRendererV2( QgsSymbolV2* defaultSymbol )
: QgsFeatureRendererV2( "RuleRenderer" )
: QgsFeatureRendererV2( "ruleRenderer" )
{
mRootRule = new Rule( NULL ); // root has no symbol, no filter etc - just a container
mRootRule->appendChild( new Rule( defaultSymbol ) );
@ -835,12 +838,11 @@ QList<QString> QgsRuleBasedRendererV2::usedAttributes()
return attrs.values();
}
QgsFeatureRendererV2* QgsRuleBasedRendererV2::clone()
QgsFeatureRendererV2* QgsRuleBasedRendererV2::clone() const
{
QgsRuleBasedRendererV2* r = new QgsRuleBasedRendererV2( mRootRule->clone() );
r->setUsingSymbolLevels( usingSymbolLevels() );
setUsingSymbolLevels( usingSymbolLevels() );
return r;
}
@ -1044,7 +1046,173 @@ QgsSymbolV2List QgsRuleBasedRendererV2::symbolsForFeature( QgsFeature& feat )
return mRootRule->symbolsForFeature( feat );
}
QgsRuleBasedRendererV2* QgsRuleBasedRendererV2::convertToRuleBasedRenderer()
QgsRuleBasedRendererV2* QgsRuleBasedRendererV2::convertFromRenderer( const QgsFeatureRendererV2* renderer )
{
return dynamic_cast<QgsRuleBasedRendererV2*>( this->clone() ) ;
if ( renderer->type() == "ruleRenderer" )
{
return dynamic_cast<QgsRuleBasedRendererV2*>( renderer->clone() );
}
if ( renderer->type() == "singleSymbol" )
{
const QgsSingleSymbolRendererV2* singleSymbolRenderer = dynamic_cast<const QgsSingleSymbolRendererV2*>( renderer );
QgsSymbolV2* origSymbol = singleSymbolRenderer->symbol()->clone();
convertToDataDefinedSymbology( origSymbol, singleSymbolRenderer->sizeScaleField(), singleSymbolRenderer->rotationField() );
return new QgsRuleBasedRendererV2( origSymbol );
}
if ( renderer->type() == "categorizedSymbol" )
{
const QgsCategorizedSymbolRendererV2* categorizedRenderer = dynamic_cast<const QgsCategorizedSymbolRendererV2*>( renderer );
QgsRuleBasedRendererV2::Rule* rootrule = new QgsRuleBasedRendererV2::Rule( NULL );
QString expression;
QString value;
QgsRendererCategoryV2 category;
for ( int i = 0; i < categorizedRenderer->categories().size(); ++i )
{
category = categorizedRenderer->categories().value( i );
QgsRuleBasedRendererV2::Rule* rule = new QgsRuleBasedRendererV2::Rule( NULL );
rule->setLabel( category.label() );
//We first define the rule corresponding to the category
//If the value is a number, we can use it directly, otherwise we need to quote it in the rule
if ( QVariant( category.value() ).convert( QVariant::Double ) )
{
value = category.value().toString();
}
else
{
value = "'" + category.value().toString() + "'";
}
//An empty category is equivalent to the ELSE keyword
if ( value == "''" )
{
expression = "ELSE";
}
else
{
expression = categorizedRenderer->classAttribute() + " = " + value;
}
rule->setFilterExpression( expression );
//Then we construct an equivalent symbol.
//Ideally we could simply copy the symbol, but the categorized renderer allows a separate interface to specify
//data dependent area and rotation, so we need to convert these to obtain the same rendering
QgsSymbolV2* origSymbol = category.symbol()->clone();
convertToDataDefinedSymbology( origSymbol, categorizedRenderer->sizeScaleField(), categorizedRenderer->rotationField() );
rule->setSymbol( origSymbol );
rootrule->appendChild( rule );
}
return new QgsRuleBasedRendererV2( rootrule );
}
if ( renderer->type() == "graduatedSymbol" )
{
const QgsGraduatedSymbolRendererV2* graduatedRenderer = dynamic_cast<const QgsGraduatedSymbolRendererV2*>( renderer );
QgsRuleBasedRendererV2::Rule* rootrule = new QgsRuleBasedRendererV2::Rule( NULL );
QString expression;
QgsRendererRangeV2 range;
for ( int i = 0; i < graduatedRenderer->ranges().size();++i )
{
range = graduatedRenderer->ranges().value( i );
QgsRuleBasedRendererV2::Rule* rule = new QgsRuleBasedRendererV2::Rule( NULL );
rule->setSymbol( range.symbol() );
rule->setLabel( range.label() );
if ( i == 0 )//The lower boundary of the first range is included, while it is excluded for the others
{
expression = graduatedRenderer->classAttribute() + " >= " + QString::number( range.lowerValue(), 'f' ) + " AND " + \
graduatedRenderer->classAttribute() + " <= " + QString::number( range.upperValue(), 'f' );
}
else
{
expression = graduatedRenderer->classAttribute() + " > " + QString::number( range.lowerValue(), 'f' ) + " AND " + \
graduatedRenderer->classAttribute() + " <= " + QString::number( range.upperValue(), 'f' );
}
rule->setFilterExpression( expression );
//Then we construct an equivalent symbol.
//Ideally we could simply copy the symbol, but the graduated renderer allows a separate interface to specify
//data dependent area and rotation, so we need to convert these to obtain the same rendering
QgsSymbolV2* symbol = range.symbol()->clone();
convertToDataDefinedSymbology( symbol, graduatedRenderer->sizeScaleField(), graduatedRenderer->rotationField() );
rule->setSymbol( symbol );
rootrule->appendChild( rule );
}
return new QgsRuleBasedRendererV2( rootrule );
}
if ( renderer->type() == "pointDisplacement" )
{
const QgsPointDisplacementRenderer* pointDisplacementRenderer = dynamic_cast<const QgsPointDisplacementRenderer*>( renderer );
return convertFromRenderer( pointDisplacementRenderer->embeddedRenderer() );
}
if ( renderer->type() == "invertedPolygonRenderer" )
{
const QgsInvertedPolygonRenderer* invertedPolygonRenderer = dynamic_cast<const QgsInvertedPolygonRenderer*>( renderer );
return convertFromRenderer( invertedPolygonRenderer->embeddedRenderer() );
}
return NULL;
}
void QgsRuleBasedRendererV2::convertToDataDefinedSymbology( QgsSymbolV2* symbol, QString sizeScaleField, QString rotationField )
{
QString sizeExpression;
switch ( symbol->type() )
{
case QgsSymbolV2::Marker:
for ( int j = 0; j < symbol->symbolLayerCount();++j )
{
QgsMarkerSymbolLayerV2* msl = static_cast<QgsMarkerSymbolLayerV2*>( symbol->symbolLayer( j ) );
if ( ! sizeScaleField.isNull() )
{
sizeExpression = QString( "%1*(%2)" ).arg( msl->size() ).arg( sizeScaleField );
msl->setDataDefinedProperty( "size", sizeExpression );
}
if ( ! rotationField.isNull() )
{
msl->setDataDefinedProperty( "angle", rotationField );
}
}
break;
case QgsSymbolV2::Line:
if ( ! sizeScaleField.isNull() )
{
for ( int j = 0; j < symbol->symbolLayerCount();++j )
{
if ( symbol->symbolLayer( j )->layerType() == "SimpleLine" )
{
QgsLineSymbolLayerV2* lsl = static_cast<QgsLineSymbolLayerV2*>( symbol->symbolLayer( j ) );
sizeExpression = QString( "%1*(%2)" ).arg( lsl->width() ).arg( sizeScaleField );
lsl->setDataDefinedProperty( "width", sizeExpression );
}
if ( symbol->symbolLayer( j )->layerType() == "MarkerLine" )
{
QgsSymbolV2* marker = symbol->symbolLayer( j )->subSymbol();
for ( int k = 0; k < marker->symbolLayerCount();++k )
{
QgsMarkerSymbolLayerV2* msl = static_cast<QgsMarkerSymbolLayerV2*>( marker->symbolLayer( k ) );
sizeExpression = QString( "%1*(%2)" ).arg( msl->size() ).arg( sizeScaleField );
msl->setDataDefinedProperty( "size", sizeExpression );
}
}
}
}
break;
default:
break;
}
}

View File

@ -226,7 +226,7 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
virtual QList<QString> usedAttributes();
virtual QgsFeatureRendererV2* clone();
virtual QgsFeatureRendererV2* clone() const;
virtual void toSld( QDomDocument& doc, QDomElement &element ) const;
@ -293,9 +293,13 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
//! take a rule and create a list of new rules with intervals of scales given by the passed scale denominators
static void refineRuleScales( Rule* initialRule, QList<int> scales );
//! convert the renderer to a rule based renderer with equivalent rules, if possible
//! creates a QgsRuleBasedRendererV2 from an existing renderer.
//! @note added in 2.5
virtual QgsRuleBasedRendererV2* convertToRuleBasedRenderer();
//! @returns a new renderer if the conversion was possible, otherwise 0.
static QgsRuleBasedRendererV2* convertFromRenderer( const QgsFeatureRendererV2 *renderer );
//! helper function to convert the size scale and rotation fields present in some other renderers to data defined symbology
static void convertToDataDefinedSymbology( QgsSymbolV2* symbol, QString sizeScaleField, QString rotationField );
protected:
//! the root node with hierarchical list of rules

View File

@ -23,7 +23,8 @@
#include "qgsvectorlayer.h"
#include "qgssymbollayerv2.h"
#include "qgsogcutils.h"
#include "qgsrulebasedrendererv2.h"
#include "qgspointdisplacementrenderer.h"
#include "qgsinvertedpolygonrenderer.h"
#include <QDomDocument>
#include <QDomElement>
@ -168,7 +169,7 @@ QString QgsSingleSymbolRendererV2::dump() const
return mSymbol.data() ? QString( "SINGLE: %1" ).arg( mSymbol->dump() ) : "" ;
}
QgsFeatureRendererV2* QgsSingleSymbolRendererV2::clone()
QgsFeatureRendererV2* QgsSingleSymbolRendererV2::clone() const
{
QgsSingleSymbolRendererV2* r = new QgsSingleSymbolRendererV2( mSymbol->clone() );
r->setUsingSymbolLevels( usingSymbolLevels() );
@ -375,59 +376,22 @@ QgsLegendSymbolListV2 QgsSingleSymbolRendererV2::legendSymbolItemsV2() const
return lst;
}
QgsRuleBasedRendererV2* QgsSingleSymbolRendererV2::convertToRuleBasedRenderer()
QgsSingleSymbolRendererV2* QgsSingleSymbolRendererV2::convertFromRenderer( const QgsFeatureRendererV2 *renderer )
{
//We construct an equivalent symbol for the rule based renderer.
//Ideally we could simply copy the symbol, but the single symbol renderer allows a separate interface to specify
//data dependent area and rotation, so we need to convert these to obtain the same rendering
QString sizeExpression;
QgsSymbolV2* origSymbol = symbol()->clone();
switch ( origSymbol->type() )
if ( renderer->type() == "singleSymbol" )
{
case QgsSymbolV2::Marker:
for ( int j = 0; j < origSymbol->symbolLayerCount();++j )
{
QgsMarkerSymbolLayerV2* msl = static_cast<QgsMarkerSymbolLayerV2*>( origSymbol->symbolLayer( j ) );
if ( mSizeScale.data() )
{
sizeExpression = QString( "%1*(%2)" ).arg( msl->size() ).arg( sizeScaleField() );
msl->setDataDefinedProperty( "size", sizeExpression );
}
if ( mRotation.data() )
{
msl->setDataDefinedProperty( "angle", rotationField() );
}
}
break;
case QgsSymbolV2::Line:
if ( mSizeScale.data() )
{
for ( int j = 0; j < origSymbol->symbolLayerCount();++j )
{
if ( origSymbol->symbolLayer( j )->layerType() == "SimpleLine" )
{
QgsLineSymbolLayerV2* lsl = static_cast<QgsLineSymbolLayerV2*>( origSymbol->symbolLayer( j ) );
sizeExpression = QString( "%1*(%2)" ).arg( lsl->width() ).arg( sizeScaleField() );
lsl->setDataDefinedProperty( "width", sizeExpression );
}
if ( origSymbol->symbolLayer( j )->layerType() == "MarkerLine" )
{
QgsSymbolV2* marker = origSymbol->symbolLayer( j )->subSymbol();
for ( int k = 0; k < marker->symbolLayerCount();++k )
{
QgsMarkerSymbolLayerV2* msl = static_cast<QgsMarkerSymbolLayerV2*>( marker->symbolLayer( k ) );
sizeExpression = QString( "%1*(%2)" ).arg( msl->size() ).arg( sizeScaleField() );
msl->setDataDefinedProperty( "size", sizeExpression );
}
}
}
}
break;
default:
break;
return dynamic_cast<QgsSingleSymbolRendererV2*>( renderer->clone() );
}
if ( renderer->type() == "pointDisplacement" )
{
const QgsPointDisplacementRenderer* pointDisplacementRenderer = dynamic_cast<const QgsPointDisplacementRenderer*>( renderer );
return convertFromRenderer( pointDisplacementRenderer->embeddedRenderer() );
}
if ( renderer->type() == "invertedPolygonRenderer" )
{
const QgsInvertedPolygonRenderer* invertedPolygonRenderer = dynamic_cast<const QgsInvertedPolygonRenderer*>( renderer );
return convertFromRenderer( invertedPolygonRenderer->embeddedRenderer() );
return new QgsRuleBasedRendererV2( origSymbol );
}
return 0;
}

View File

@ -21,8 +21,6 @@
#include "qgsexpression.h"
#include <QScopedPointer>
class QgsRuleBasedRenderedV2;
class CORE_EXPORT QgsSingleSymbolRendererV2 : public QgsFeatureRendererV2
{
public:
@ -59,7 +57,7 @@ class CORE_EXPORT QgsSingleSymbolRendererV2 : public QgsFeatureRendererV2
virtual QString dump() const;
virtual QgsFeatureRendererV2* clone();
virtual QgsFeatureRendererV2* clone() const ;
virtual void toSld( QDomDocument& doc, QDomElement &element ) const;
static QgsFeatureRendererV2* createFromSld( QDomElement& element, QGis::GeometryType geomType );
@ -89,9 +87,10 @@ class CORE_EXPORT QgsSingleSymbolRendererV2 : public QgsFeatureRendererV2
//! @note added in 2.6
virtual QgsLegendSymbolListV2 legendSymbolItemsV2() const;
//! convert the renderer to a rule based renderer with equivalent rules
//! creates a QgsSingleSymbolRendererV2 from an existing renderer.
//! @note added in 2.5
virtual QgsRuleBasedRendererV2* convertToRuleBasedRenderer();
//! @returns a new renderer if the conversion was possible, otherwise 0.
static QgsSingleSymbolRendererV2* convertFromRenderer( const QgsFeatureRendererV2 *renderer );
protected:

View File

@ -372,16 +372,13 @@ QgsCategorizedSymbolRendererV2Widget::QgsCategorizedSymbolRendererV2Widget( QgsV
// try to recognize the previous renderer
// (null renderer means "no previous renderer")
if ( !renderer || renderer->type() != "categorizedSymbol" )
if ( renderer )
{
// we're not going to use it - so let's delete the renderer
delete renderer;
mRenderer = new QgsCategorizedSymbolRendererV2( "", QgsCategoryList() );
mRenderer = QgsCategorizedSymbolRendererV2::convertFromRenderer( renderer );
}
else
if ( !mRenderer )
{
mRenderer = static_cast<QgsCategorizedSymbolRendererV2*>( renderer );
mRenderer = new QgsCategorizedSymbolRendererV2( "", QgsCategoryList() );
}
QString attrName = mRenderer->classAttribute();

View File

@ -365,16 +365,13 @@ QgsGraduatedSymbolRendererV2Widget::QgsGraduatedSymbolRendererV2Widget( QgsVecto
// try to recognize the previous renderer
// (null renderer means "no previous renderer")
if ( !renderer || renderer->type() != "graduatedSymbol" )
if ( renderer )
{
// we're not going to use it - so let's delete the renderer
delete renderer;
mRenderer = new QgsGraduatedSymbolRendererV2( "", QgsRangeList() );
mRenderer = QgsGraduatedSymbolRendererV2::convertFromRenderer( renderer );
}
else
if ( !mRenderer )
{
mRenderer = static_cast<QgsGraduatedSymbolRendererV2*>( renderer );
mRenderer = new QgsGraduatedSymbolRendererV2( "", QgsRangeList() );
}
// setup user interface

View File

@ -53,25 +53,18 @@ QgsInvertedPolygonRendererWidget::QgsInvertedPolygonRendererWidget( QgsVectorLay
// try to recognize the previous renderer
// (null renderer means "no previous renderer")
if ( !renderer )
if ( renderer )
{
mRenderer.reset( QgsInvertedPolygonRenderer::convertFromRenderer( renderer ) );
}
if ( ! mRenderer )
{
// a new renderer
mRenderer.reset( new QgsInvertedPolygonRenderer() );
}
else if ( renderer && renderer->type() != "invertedPolygonRenderer" )
{
// an existing renderer, but not an inverted renderer
// create an inverted renderer, with the existing renderer embedded
mRenderer.reset( new QgsInvertedPolygonRenderer( renderer ) );
}
else
{
// an existing inverted renderer
mRenderer.reset( static_cast<QgsInvertedPolygonRenderer*>( renderer ) );
mMergePolygonsCheckBox->blockSignals( true );
mMergePolygonsCheckBox->setCheckState( mRenderer->preprocessingEnabled() ? Qt::Checked : Qt::Unchecked );
mMergePolygonsCheckBox->blockSignals( false );
}
mMergePolygonsCheckBox->blockSignals( true );
mMergePolygonsCheckBox->setCheckState( mRenderer->preprocessingEnabled() ? Qt::Checked : Qt::Unchecked );
mMergePolygonsCheckBox->blockSignals( false );
int currentEmbeddedIdx = 0;
//insert possible renderer types

View File

@ -49,11 +49,12 @@ QgsPointDisplacementRendererWidget::QgsPointDisplacementRendererWidget( QgsVecto
}
setupUi( this );
if ( renderer && renderer->type() == "pointDisplacement" )
if ( renderer )
{
mRenderer = dynamic_cast<QgsPointDisplacementRenderer*>( renderer->clone() );
mRenderer = QgsPointDisplacementRenderer::convertFromRenderer(renderer);
}
else
if ( !mRenderer )
{
mRenderer = new QgsPointDisplacementRenderer();
}

View File

@ -65,7 +65,7 @@ static void _initRendererWidgetFunctions()
_initRenderer( "singleSymbol", QgsSingleSymbolRendererV2Widget::create, "rendererSingleSymbol.png" );
_initRenderer( "categorizedSymbol", QgsCategorizedSymbolRendererV2Widget::create, "rendererCategorizedSymbol.png" );
_initRenderer( "graduatedSymbol", QgsGraduatedSymbolRendererV2Widget::create, "rendererGraduatedSymbol.png" );
_initRenderer( "RuleRenderer", QgsRuleBasedRendererV2Widget::create );
_initRenderer( "ruleRenderer", QgsRuleBasedRendererV2Widget::create );
_initRenderer( "pointDisplacement", QgsPointDisplacementRendererWidget::create );
_initRenderer( "invertedPolygonRenderer", QgsInvertedPolygonRendererWidget::create );
initialized = true;
@ -146,7 +146,7 @@ void QgsRendererV2PropertiesDialog::rendererChanged()
//Retrieve the previous renderer: from the old active widget if possible, otherwise from the layer
QgsFeatureRendererV2* oldRenderer;
if ( mActiveWidget )
if ( mActiveWidget && mActiveWidget->renderer() )
{
oldRenderer = mActiveWidget->renderer()->clone();
}

View File

@ -24,6 +24,7 @@
#include "qgssymbolv2selectordialog.h"
#include "qgslogger.h"
#include "qstring.h"
#include "qgssinglesymbolrendererv2.h"
#include <QKeyEvent>
#include <QMenu>
@ -46,9 +47,11 @@ QgsRuleBasedRendererV2Widget::QgsRuleBasedRendererV2Widget( QgsVectorLayer* laye
mRenderer = 0;
// try to recognize the previous renderer
// (null renderer means "no previous renderer")
if ( renderer )
{
mRenderer = renderer->convertToRuleBasedRenderer();
mRenderer = QgsRuleBasedRendererV2::convertFromRenderer(renderer);
}
if ( !mRenderer )
{

View File

@ -34,20 +34,17 @@ QgsSingleSymbolRendererV2Widget::QgsSingleSymbolRendererV2Widget( QgsVectorLayer
{
// try to recognize the previous renderer
// (null renderer means "no previous renderer")
if ( !renderer || renderer->type() != "singleSymbol" )
{
// we're not going to use it - so let's delete the renderer
delete renderer;
// some default options
if ( renderer )
{
mRenderer = QgsSingleSymbolRendererV2::convertFromRenderer( renderer );
}
if ( !mRenderer )
{
QgsSymbolV2* symbol = QgsSymbolV2::defaultSymbol( mLayer->geometryType() );
mRenderer = new QgsSingleSymbolRendererV2( symbol );
}
else
{
mRenderer = static_cast<QgsSingleSymbolRendererV2*>( renderer );
}
// load symbol from it
mSingleSymbol = mRenderer->symbol()->clone();