mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-27 00:33:48 -05:00
This adds a new "edit symbol" item to the right-click menu for a renderer child legend item (eg categories for the categorised renderer). Selecting it opens a symbol editor dialog which allows for directly editing the classes symbol. It's much faster than opening the layer properties and going through the style tab.
414 lines
16 KiB
Plaintext
414 lines
16 KiB
Plaintext
/**
|
|
When drawing a vector layer with rule-based renderer, it goes through
|
|
the rules and draws features with symbols from rules that match.
|
|
*/
|
|
class QgsRuleBasedRendererV2 : QgsFeatureRendererV2
|
|
{
|
|
%TypeHeaderCode
|
|
#include <qgsrulebasedrendererv2.h>
|
|
%End
|
|
|
|
public:
|
|
// TODO: use QVarLengthArray instead of QList
|
|
|
|
enum FeatureFlags { FeatIsSelected, FeatDrawMarkers, };
|
|
|
|
// feature for rendering: QgsFeature and some flags
|
|
struct FeatureToRender
|
|
{
|
|
FeatureToRender( QgsFeature& _f, int _flags );
|
|
QgsFeature feat;
|
|
int flags; // selected and/or draw markers
|
|
};
|
|
|
|
// rendering job: a feature to be rendered with a particular symbol
|
|
// (both f, symbol are _not_ owned by this class)
|
|
struct RenderJob
|
|
{
|
|
RenderJob( QgsRuleBasedRendererV2::FeatureToRender& _ftr, QgsSymbolV2* _s );
|
|
QgsRuleBasedRendererV2::FeatureToRender& ftr;
|
|
QgsSymbolV2* symbol;
|
|
};
|
|
|
|
// render level: a list of jobs to be drawn at particular level
|
|
// (jobs are owned by this class)
|
|
struct RenderLevel
|
|
{
|
|
RenderLevel( int z );
|
|
~RenderLevel();
|
|
int zIndex;
|
|
QList<QgsRuleBasedRendererV2::RenderJob*> jobs;
|
|
};
|
|
|
|
// rendering queue: a list of rendering levels
|
|
typedef QList<QgsRuleBasedRendererV2::RenderLevel> RenderQueue;
|
|
|
|
/**
|
|
This class keeps data about a rules for rule-based renderer.
|
|
A rule consists of a symbol, filter expression and range of scales.
|
|
If filter is empty, it matches all features.
|
|
If scale range has both values zero, it matches all scales.
|
|
If one of the min/max scale denominators is zero, there is no lower/upper bound for scales.
|
|
A rule matches if both filter and scale range match.
|
|
*/
|
|
class Rule
|
|
{
|
|
public:
|
|
enum RenderResult
|
|
{
|
|
Filtered = 0, //!< The rule does not apply
|
|
Inactive, //!< The rule is inactive
|
|
Rendered //!< Something was rendered
|
|
};
|
|
|
|
//! Constructor takes ownership of the symbol
|
|
Rule( QgsSymbolV2* symbol /Transfer/, int scaleMinDenom = 0, int scaleMaxDenom = 0, const QString& filterExp = QString(),
|
|
const QString& label = QString(), const QString& description = QString(), bool elseRule = false );
|
|
~Rule();
|
|
QString dump( int offset = 0 ) const;
|
|
QSet<QString> usedAttributes();
|
|
|
|
//! @note available in python bindings as symbol2
|
|
QgsSymbolV2List symbols( const QgsRenderContext& context = QgsRenderContext() ) /PyName=symbols2/;
|
|
|
|
//! @note not available in python bindings
|
|
// QgsLegendSymbolList legendSymbolItems();
|
|
|
|
//! @note added in 2.6
|
|
QgsLegendSymbolListV2 legendSymbolItemsV2( int currentLevel = -1 ) const;
|
|
|
|
/**
|
|
* Check if a given feature shall be rendered by this rule
|
|
*
|
|
* @param f The feature to test
|
|
* @param context The context in which the rendering happens
|
|
* @return True if the feature shall be rendered
|
|
*/
|
|
bool isFilterOK( QgsFeature& f, QgsRenderContext *context = 0 ) const;
|
|
|
|
/**
|
|
* Check if this rule applies for a given scale
|
|
* @param scale The scale to check. If set to 0, it will always return true.
|
|
*
|
|
* @return If the rule will be evaluated at this scale
|
|
*/
|
|
bool isScaleOK( double scale ) const;
|
|
|
|
QgsSymbolV2* symbol();
|
|
QString label() const;
|
|
bool dependsOnScale() const;
|
|
int scaleMinDenom() const;
|
|
int scaleMaxDenom() const;
|
|
|
|
/**
|
|
* A filter that will check if this rule applies
|
|
* @return An expression
|
|
*/
|
|
QgsExpression* filter() const;
|
|
|
|
/**
|
|
* A filter that will check if this rule applies
|
|
* @return An expression
|
|
*/
|
|
QString filterExpression() const;
|
|
|
|
/**
|
|
* A human readable description for this rule
|
|
*
|
|
* @return Description
|
|
*/
|
|
QString description() const;
|
|
|
|
//! @note added in 2.6
|
|
//! @deprecated use active instead
|
|
bool checkState() const /Deprecated/;
|
|
/**
|
|
* Returns if this rule is active
|
|
*
|
|
* @return True if the rule is active
|
|
*/
|
|
bool active() const;
|
|
|
|
//! Unique rule identifier (for identification of rule within renderer)
|
|
//! @note added in 2.6
|
|
QString ruleKey() const;
|
|
//! Override the assigned rule key (should be used just internally by rule-based renderer)
|
|
//! @note added in 2.6
|
|
void setRuleKey( const QString& key );
|
|
|
|
//! set a new symbol (or NULL). Deletes old symbol.
|
|
void setSymbol( QgsSymbolV2* sym /Transfer/ );
|
|
void setLabel( const QString& label );
|
|
|
|
/**
|
|
* Set the minimum denominator for which this rule shall apply.
|
|
* E.g. 1000 if it shall be evaluated between 1:1000 and 1:100'000
|
|
* Set to 0 to disable the minimum check
|
|
* @param scaleMinDenom The minimum scale denominator for this rule
|
|
*/
|
|
void setScaleMinDenom( int scaleMinDenom );
|
|
|
|
/**
|
|
* Set the maximum denominator for which this rule shall apply.
|
|
* E.g. 100'000 if it shall be evaluated between 1:1000 and 1:100'000
|
|
* Set to 0 to disable the maximum check
|
|
* @param scaleMaxDenom maximum scale denominator for this rule
|
|
*/
|
|
void setScaleMaxDenom( int scaleMaxDenom );
|
|
|
|
/**
|
|
* Set the expression used to check if a given feature shall be rendered with this rule
|
|
*
|
|
* @param filterExp An expression
|
|
*/
|
|
void setFilterExpression( const QString& filterExp );
|
|
|
|
/**
|
|
* Set a human readable description for this rule
|
|
*
|
|
* @param description Description
|
|
*/
|
|
void setDescription( const QString& description );
|
|
|
|
//! @note added in 2.6
|
|
//! @deprecated use setActive instead
|
|
void setCheckState( bool state ) /Deprecated/;
|
|
|
|
/**
|
|
* Sets if this rule is active
|
|
* @param state Determines if the rule should be activated or deactivated
|
|
*/
|
|
void setActive( bool state );
|
|
|
|
//! clone this rule, return new instance
|
|
QgsRuleBasedRendererV2::Rule* clone() const /Factory/;
|
|
|
|
void toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props );
|
|
static QgsRuleBasedRendererV2::Rule* createFromSld( QDomElement& element, QGis::GeometryType geomType ) /Factory/;
|
|
|
|
QDomElement save( QDomDocument& doc, QgsSymbolV2Map& symbolMap );
|
|
|
|
/** Prepare the rule for rendering and its children (build active children array)
|
|
* @deprecated use startRender( QgsRenderContext& context, const QgsFields& fields, QString& filter ) instead
|
|
*/
|
|
bool startRender( QgsRenderContext& context, const QgsFields& fields ) /Deprecated/;
|
|
|
|
//! prepare the rule for rendering and its children (build active children array)
|
|
bool startRender( QgsRenderContext& context, const QgsFields& fields, QString& filter );
|
|
|
|
//! get all used z-levels from this rule and children
|
|
QSet<int> collectZLevels();
|
|
|
|
//! assign normalized z-levels [0..N-1] for this rule's symbol for quick access during rendering
|
|
//! @note not available in python bindings
|
|
// void setNormZLevels( const QMap<int, int>& zLevelsToNormLevels );
|
|
|
|
/**
|
|
* Render a given feature, will recursively call subclasses and only render if the constraints apply.
|
|
*
|
|
* @param featToRender The feature to render
|
|
* @param context The rendering context
|
|
* @param renderQueue The rendering queue to which the feature should be added
|
|
* @return The result of the rendering. In explicit if the feature is added to the queue or
|
|
* the reason for not rendering the feature.
|
|
*/
|
|
QgsRuleBasedRendererV2::Rule::RenderResult renderFeature( QgsRuleBasedRendererV2::FeatureToRender& featToRender, QgsRenderContext& context, QgsRuleBasedRendererV2::RenderQueue& renderQueue );
|
|
|
|
//! only tell whether a feature will be rendered without actually rendering it
|
|
bool willRenderFeature( QgsFeature& feat, QgsRenderContext* context = 0);
|
|
|
|
//! tell which symbols will be used to render the feature
|
|
QgsSymbolV2List symbolsForFeature( QgsFeature& feat, QgsRenderContext* context = 0 );
|
|
|
|
//! tell which rules will be used to render the feature
|
|
QList<QgsRuleBasedRendererV2::Rule*> rulesForFeature( QgsFeature& feat, QgsRenderContext* context = 0 );
|
|
|
|
/**
|
|
* Stop a rendering process. Used to clean up the internal state of this rule
|
|
*
|
|
* @param context The rendering context
|
|
*/
|
|
void stopRender( QgsRenderContext& context );
|
|
|
|
/**
|
|
* Create a rule from an XML definition
|
|
*
|
|
* @param ruleElem The XML rule element
|
|
* @param symbolMap Symbol map
|
|
*
|
|
* @return A new rule
|
|
*/
|
|
static QgsRuleBasedRendererV2::Rule* create( QDomElement& ruleElem, QgsSymbolV2Map& symbolMap ) /Factory/;
|
|
|
|
/**
|
|
* Return all children rules of this rule
|
|
*
|
|
* @return A list of rules
|
|
*/
|
|
QList<QgsRuleBasedRendererV2::Rule*>& children();
|
|
|
|
/**
|
|
* Returns all children, grand-children, grand-grand-children, grand-gra... you get it
|
|
*
|
|
* @return A list of descendant rules
|
|
*/
|
|
QList<QgsRuleBasedRendererV2::Rule*> descendants() const;
|
|
|
|
/**
|
|
* The parent rule
|
|
*
|
|
* @return Parent rule
|
|
*/
|
|
QgsRuleBasedRendererV2::Rule* parent();
|
|
|
|
//! add child rule, take ownership, sets this as parent
|
|
void appendChild( QgsRuleBasedRendererV2::Rule* rule /Transfer/ );
|
|
|
|
//! add child rule, take ownership, sets this as parent
|
|
void insertChild( int i, QgsRuleBasedRendererV2::Rule* rule /Transfer/ );
|
|
|
|
//! delete child rule
|
|
void removeChild( QgsRuleBasedRendererV2::Rule* rule );
|
|
|
|
//! delete child rule
|
|
void removeChildAt( int i );
|
|
|
|
//! take child rule out, set parent as null
|
|
void takeChild( QgsRuleBasedRendererV2::Rule* rule );
|
|
|
|
//! take child rule out, set parent as null
|
|
QgsRuleBasedRendererV2::Rule* takeChildAt( int i ) /TransferBack/;
|
|
|
|
//! Try to find a rule given its unique key
|
|
//! @note added in 2.6
|
|
QgsRuleBasedRendererV2::Rule* findRuleByKey( const QString& key );
|
|
|
|
/**
|
|
* Check which child rules are else rules and update the internal list of else rules
|
|
*
|
|
* TODO QGIS 3: Does this need to be public?
|
|
*/
|
|
void updateElseRules();
|
|
|
|
/**
|
|
* Sets if this rule is an ELSE rule
|
|
*
|
|
* @param iselse If true, this rule is an ELSE rule
|
|
*/
|
|
void setIsElse( bool iselse );
|
|
|
|
/**
|
|
* Check if this rule is an ELSE rule
|
|
*
|
|
* @return True if this rule is an else rule
|
|
*/
|
|
bool isElse();
|
|
|
|
protected:
|
|
void initFilter();
|
|
};
|
|
|
|
/////
|
|
|
|
static QgsFeatureRendererV2* create( QDomElement& element ) /Factory/;
|
|
|
|
//! Constructs the renderer from given tree of rules (takes ownership)
|
|
QgsRuleBasedRendererV2( QgsRuleBasedRendererV2::Rule* root /Transfer/ );
|
|
//! Constructor for convenience. Creates a root rule and adds a default rule with symbol (takes ownership)
|
|
QgsRuleBasedRendererV2( QgsSymbolV2* defaultSymbol /Transfer/ );
|
|
|
|
~QgsRuleBasedRendererV2();
|
|
|
|
//! return symbol for current feature. Should not be used individually: there could be more symbols for a feature
|
|
virtual QgsSymbolV2* symbolForFeature( QgsFeature& feature, QgsRenderContext &context );
|
|
|
|
virtual bool renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer = -1, bool selected = false, bool drawVertexMarker = false );
|
|
|
|
virtual void startRender( QgsRenderContext& context, const QgsFields& fields );
|
|
|
|
virtual void stopRender( QgsRenderContext& context );
|
|
|
|
virtual QString filter( const QgsFields& fields = QgsFields() );
|
|
|
|
virtual QList<QString> usedAttributes();
|
|
|
|
virtual QgsRuleBasedRendererV2* clone() const /Factory/;
|
|
|
|
virtual void toSld( QDomDocument& doc, QDomElement &element ) const;
|
|
|
|
static QgsFeatureRendererV2* createFromSld( QDomElement& element, QGis::GeometryType geomType ) /Factory/;
|
|
|
|
virtual QgsSymbolV2List symbols( QgsRenderContext &context );
|
|
|
|
//! store renderer info to XML element
|
|
virtual QDomElement save( QDomDocument& doc );
|
|
|
|
//! return a list of symbology items for the legend
|
|
virtual QgsLegendSymbologyList legendSymbologyItems( QSize iconSize );
|
|
|
|
//! items of symbology items in legend should be checkable
|
|
//! @note added in 2.5
|
|
virtual bool legendSymbolItemsCheckable() const;
|
|
|
|
//! items of symbology items in legend is checked
|
|
//! @note added in 2.5
|
|
virtual bool legendSymbolItemChecked( const QString& key );
|
|
|
|
//! item in symbology was checked
|
|
//! @note added in 2.5
|
|
virtual void checkLegendSymbolItem( const QString& key, bool state = true );
|
|
|
|
virtual void setLegendSymbolItem( const QString& key, QgsSymbolV2* symbol /Transfer/ );
|
|
|
|
//! return a list of item text / symbol
|
|
//! @note not available in python bindings
|
|
// virtual QgsLegendSymbolList legendSymbolItems();
|
|
|
|
//! Return a list of symbology items for the legend. Better choice than legendSymbolItems().
|
|
//! Default fallback implementation just uses legendSymbolItems() implementation
|
|
//! @note added in 2.6
|
|
virtual QgsLegendSymbolListV2 legendSymbolItemsV2() const;
|
|
|
|
//! for debugging
|
|
virtual QString dump() const;
|
|
|
|
//! return whether the renderer will render a feature or not.
|
|
//! Must be called between startRender() and stopRender() calls.
|
|
virtual bool willRenderFeature( QgsFeature& feat, QgsRenderContext &context );
|
|
|
|
//! return list of symbols used for rendering the feature.
|
|
//! For renderers that do not support MoreSymbolsPerFeature it is more efficient
|
|
//! to use symbolForFeature()
|
|
virtual QgsSymbolV2List symbolsForFeature( QgsFeature& feat, QgsRenderContext &context );
|
|
|
|
virtual QgsSymbolV2List originalSymbolsForFeature( QgsFeature& feat, QgsRenderContext &context );
|
|
|
|
//! returns bitwise OR-ed capabilities of the renderer
|
|
virtual int capabilities();
|
|
|
|
/////
|
|
|
|
QgsRuleBasedRendererV2::Rule* rootRule();
|
|
|
|
//////
|
|
|
|
//! take a rule and create a list of new rules based on the categories from categorized symbol renderer
|
|
static void refineRuleCategories( QgsRuleBasedRendererV2::Rule* initialRule, QgsCategorizedSymbolRendererV2* r );
|
|
//! take a rule and create a list of new rules based on the ranges from graduated symbol renderer
|
|
static void refineRuleRanges( QgsRuleBasedRendererV2::Rule* initialRule, QgsGraduatedSymbolRendererV2* r );
|
|
//! 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 );
|
|
|
|
//! creates a QgsRuleBasedRendererV2 from an existing renderer.
|
|
//! @note added in 2.5
|
|
//! @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, const QString& sizeScaleField, const QString& rotationField = QString() );
|
|
|
|
private:
|
|
QgsRuleBasedRendererV2( const QgsRuleBasedRendererV2 & );
|
|
QgsRuleBasedRendererV2 & operator=( const QgsRuleBasedRendererV2 & );
|
|
};
|