/
qgsinvertedpolygonrenderer.h
204 lines (169 loc) · 8.06 KB
/
qgsinvertedpolygonrenderer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/***************************************************************************
qgsinvertedpolygonrenderer.h
---------------------
begin : April 2014
copyright : (C) 2014 Hugo Mercier / Oslandia
email : hugo dot mercier at oslandia dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSINVERTEDPOLYGONRENDERER_H
#define QGSINVERTEDPOLYGONRENDERER_H
#include "qgis_core.h"
#include "qgis_sip.h"
#include "qgis.h"
#include "qgsrenderer.h"
#include "qgsexpression.h"
#include "qgsfeature.h"
#include "qgsgeometry.h"
/**
* \ingroup core
* QgsInvertedPolygonRenderer is a polygon-only feature renderer used to
* display features inverted, where the exterior is turned to an interior
* and where the exterior theoretically spans the entire plane, allowing
* to mask the surroundings of some features.
*
* It is designed on top of another feature renderer, which is called "embedded"
* Most of the methods are then only proxies to the embedded renderer.
*
* Features are collected to form one "inverted" polygon
* during renderFeature() and rendered on stopRender().
*
* \since QGIS 2.4
*/
class CORE_EXPORT QgsInvertedPolygonRenderer : public QgsFeatureRenderer
{
public:
/**
* Constructor
* \param embeddedRenderer optional embeddedRenderer. If null, a default one will be assigned.
* Ownership will be transferred.
*/
QgsInvertedPolygonRenderer( QgsFeatureRenderer *embeddedRenderer SIP_TRANSFER = nullptr );
//! Direct copies are forbidden. Use clone() instead.
QgsInvertedPolygonRenderer( const QgsInvertedPolygonRenderer & ) = delete;
//! Direct copies are forbidden. Use clone() instead.
QgsInvertedPolygonRenderer &operator=( const QgsInvertedPolygonRenderer & ) = delete;
QgsInvertedPolygonRenderer *clone() const override SIP_FACTORY;
void startRender( QgsRenderContext &context, const QgsFields &fields ) override;
/**
* Renders a given feature.
* This will here collect features. The actual rendering will be postponed to stopRender()
* \param feature the feature to render
* \param context the rendering context
* \param layer the symbol layer to render, if that makes sense
* \param selected whether this feature has been selected (this will add decorations)
* \param drawVertexMarker whether this feature has vertex markers (in edit mode usually)
* \returns true if the rendering was OK
*/
bool renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer = -1, bool selected = false, bool drawVertexMarker = false ) override;
/**
* The actual rendering will take place here.
* Features collected during renderFeature() are rendered using the embedded feature renderer
*/
void stopRender( QgsRenderContext &context ) override;
QString dump() const override;
//! Proxy that will call this method on the embedded renderer.
QSet<QString> usedAttributes( const QgsRenderContext &context ) const override;
bool filterNeedsGeometry() const override;
//! Proxy that will call this method on the embedded renderer.
QgsFeatureRenderer::Capabilities capabilities() override;
/**
* Proxy that will call this method on the embedded renderer.
*/
QgsSymbolList symbols( QgsRenderContext &context ) const override;
/**
* Proxy that will call this method on the embedded renderer.
*/
QgsSymbol *symbolForFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
/**
* Proxy that will call this method on the embedded renderer.
*/
QgsSymbol *originalSymbolForFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
/**
* Proxy that will call this method on the embedded renderer.
*/
QgsSymbolList symbolsForFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
/**
* Proxy that will call this method on the embedded renderer.
*/
QgsSymbolList originalSymbolsForFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
/**
* Proxy that will call this method on the embedded renderer.
*/
QgsLegendSymbolList legendSymbolItems() const override;
/**
* Proxy that will call this method on the embedded renderer.
*/
bool willRenderFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
//! Creates a renderer out of an XML, for loading
static QgsFeatureRenderer *create( QDomElement &element, const QgsReadWriteContext &context ) SIP_FACTORY;
QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) override;
void setEmbeddedRenderer( QgsFeatureRenderer *subRenderer SIP_TRANSFER ) override;
const QgsFeatureRenderer *embeddedRenderer() const override;
void setLegendSymbolItem( const QString &key, QgsSymbol *symbol ) override;
bool legendSymbolItemsCheckable() const override;
bool legendSymbolItemChecked( const QString &key ) override;
void checkLegendSymbolItem( const QString &key, bool state = true ) override;
//! \returns true if the geometries are to be preprocessed (merged with an union) before rendering.
bool preprocessingEnabled() const { return mPreprocessingEnabled; }
/**
* \param enabled enables or disables the preprocessing.
* When enabled, geometries will be merged with an union before being rendered.
* It allows fixing some rendering artifacts (when rendering overlapping polygons for instance).
* This will involve some CPU-demanding computations and is thus disabled by default.
*/
void setPreprocessingEnabled( bool enabled ) { mPreprocessingEnabled = enabled; }
/**
* Creates a QgsInvertedPolygonRenderer by a conversion from an existing renderer.
* \returns a new renderer if the conversion was possible, otherwise 0.
* \since QGIS 2.5
*/
static QgsInvertedPolygonRenderer *convertFromRenderer( const QgsFeatureRenderer *renderer ) SIP_FACTORY;
private:
//! Embedded renderer
std::unique_ptr<QgsFeatureRenderer> mSubRenderer;
//! Structure where the reversed geometry is built during renderFeature
struct CombinedFeature
{
QVector<QgsGeometry> geometries; //< list of geometries
QgsFeature feature; //< one feature (for attriute-based rendering)
};
typedef QVector<CombinedFeature> FeatureCategoryVector;
//! Where features are stored, based on the index of their symbol category \see mSymbolCategories
FeatureCategoryVector mFeaturesCategories;
//! Maps a category to an index
QMap<QByteArray, int> mSymbolCategories;
//! The polygon used as exterior ring that covers the current extent
QgsPolygonXY mExtentPolygon;
//! The context used for rendering
QgsRenderContext mContext;
//! Fields of each feature
QgsFields mFields;
/**
* Class used to represent features that must be rendered
* with decorations (selection, vertex markers)
*/
struct FeatureDecoration
{
QgsFeature feature;
bool selected;
bool drawMarkers;
int layer;
FeatureDecoration( const QgsFeature &a_feature, bool a_selected, bool a_drawMarkers, int a_layer )
: feature( a_feature )
, selected( a_selected )
, drawMarkers( a_drawMarkers )
, layer( a_layer )
{}
};
QList<FeatureDecoration> mFeatureDecorations;
//! Whether to preprocess (merge) geometries before rendering
bool mPreprocessingEnabled = false;
};
#endif // QGSMASKRENDERERV2_H