mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
refactor to a more general convertFromRenderer function
This commit is contained in:
parent
11d159cd85
commit
9931dde90a
@ -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();
|
||||
|
@ -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 );
|
||||
|
@ -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/;
|
||||
};
|
||||
|
@ -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 & );
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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 & );
|
||||
|
@ -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 & );
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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& );
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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 ) );
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user