Skip to content

Commit d464f86

Browse files
committed
[FEATURE] Null ("No symbol") renderer
Using this renderer no symbol will be drawn for features, but labeling, diagrams and other non-symbol parts will still be shown. Selections can still be made on the layer in the canvas and selected features will be rendered with a default symbol. Features being edited will also be shown. This is intended as a handy shortcut for layers which you only want to show labels or diagrams for, and avoids the need to render symbols with totally transparent fill/border to achieve this. (fix #12131)
1 parent 86ec27e commit d464f86

20 files changed

+566
-0
lines changed

ci/travis/linux/qt5/blacklist.txt

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ PyQgsLocalServer
3636
PyQgsMapUnitScale
3737
PyQgsMemoryProvider
3838
PyQgsNetworkContentFetcher
39+
PyQgsNullSymbolRenderer
3940
PyQgsPalLabelingBase
4041
PyQgsPalLabelingCanvas
4142
PyQgsPalLabelingComposer

images/images.qrc

+1
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@
486486
<file>themes/default/rendererCategorizedSymbol.svg</file>
487487
<file>themes/default/rendererGraduatedSymbol.png</file>
488488
<file>themes/default/rendererGraduatedSymbol.svg</file>
489+
<file>themes/default/rendererNullSymbol.svg</file>
489490
<file>themes/default/rendererSingleSymbol.png</file>
490491
<file>themes/default/rendererSingleSymbol.svg</file>
491492
<file>themes/default/rendererRuleBasedSymbol.svg</file>
Loading

python/core/core.sip

+1
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@
289289
%Include symbology-ng/qgsheatmaprenderer.sip
290290
%Include symbology-ng/qgsinvertedpolygonrenderer.sip
291291
%Include symbology-ng/qgslegendsymbolitemv2.sip
292+
%Include symbology-ng/qgsnullsymbolrenderer.sip
292293
%Include symbology-ng/qgspointdisplacementrenderer.sip
293294
%Include symbology-ng/qgsrendererv2.sip
294295
%Include symbology-ng/qgsrendererv2registry.sip
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/** \ingroup core
2+
* \class QgsNullSymbolRenderer
3+
* \brief Null symbol renderer. Renderer which draws no symbols for features by default, but allows for labeling
4+
* and diagrams for the layer. Selected features will also be drawn with a default symbol.
5+
* \note Added in version 2.16
6+
*/
7+
8+
class QgsNullSymbolRenderer : QgsFeatureRendererV2
9+
{
10+
%TypeHeaderCode
11+
#include <qgsnullsymbolrenderer.h>
12+
%End
13+
public:
14+
15+
QgsNullSymbolRenderer();
16+
17+
virtual ~QgsNullSymbolRenderer();
18+
19+
virtual QgsSymbolV2* symbolForFeature( QgsFeature& feature, QgsRenderContext& context );
20+
virtual QgsSymbolV2* originalSymbolForFeature( QgsFeature& feature, QgsRenderContext& context );
21+
22+
virtual bool renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer = -1, bool selected = false, bool drawVertexMarker = false );
23+
virtual void startRender( QgsRenderContext& context, const QgsFields& fields );
24+
virtual void stopRender( QgsRenderContext& context );
25+
virtual bool willRenderFeature( QgsFeature& feat, QgsRenderContext& context );
26+
27+
virtual QList<QString> usedAttributes();
28+
virtual QString dump() const;
29+
virtual QgsFeatureRendererV2* clone() const /Factory/;
30+
virtual QgsSymbolV2List symbols( QgsRenderContext& context ) /PyName=symbols2/;
31+
32+
/** Creates a null renderer from XML element.
33+
* @param element DOM element
34+
* @returns new null symbol renderer
35+
*/
36+
static QgsFeatureRendererV2* create( QDomElement& element ) /Factory/;
37+
38+
virtual QDomElement save( QDomDocument& doc );
39+
40+
/** Creates a QgsNullSymbolRenderer from an existing renderer.
41+
* @param renderer renderer to convert from
42+
* @returns a new renderer if the conversion was possible, otherwise nullptr.
43+
*/
44+
static QgsNullSymbolRenderer* convertFromRenderer( const QgsFeatureRendererV2 *renderer ) /Factory/;
45+
46+
};

python/core/symbology-ng/qgsrendererv2.sip

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class QgsFeatureRendererV2
5050
sipType = sipType_QgsPointDisplacementRenderer;
5151
else if (sipCpp->type() == "25dRenderer")
5252
sipType = sipType_Qgs25DRenderer;
53+
else if (sipCpp->type() == "nullSymbol")
54+
sipType = sipType_QgsNullSymbolRenderer;
5355
else
5456
sipType = 0;
5557
%End

python/gui/gui.sip

+1
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@
208208
%Include symbology-ng/qgsheatmaprendererwidget.sip
209209
%Include symbology-ng/qgsinvertedpolygonrendererwidget.sip
210210
%Include symbology-ng/qgslayerpropertieswidget.sip
211+
%Include symbology-ng/qgsnullsymbolrendererwidget.sip
211212
%Include symbology-ng/qgspenstylecombobox.sip
212213
%Include symbology-ng/qgspointdisplacementrendererwidget.sip
213214
%Include symbology-ng/qgsrendererv2propertiesdialog.sip
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/** \ingroup gui
2+
* \class QgsNullSymbolRendererWidget
3+
* \brief Blank widget for customising QgsNullSymbolRenderer.
4+
* \note Added in version 2.16
5+
*/
6+
7+
class QgsNullSymbolRendererWidget : QgsRendererV2Widget
8+
{
9+
%TypeHeaderCode
10+
#include <qgsnullsymbolrendererwidget.h>
11+
%End
12+
13+
public:
14+
15+
//! Creates a new QgsNullSymbolRendererWidget object
16+
static QgsRendererV2Widget* create( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer ) /Factory/;
17+
18+
//! Constructor for QgsNullSymbolRendererWidget
19+
QgsNullSymbolRendererWidget( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer );
20+
~QgsNullSymbolRendererWidget();
21+
22+
//! Returns a pointer to the configured renderer
23+
virtual QgsFeatureRendererV2* renderer();
24+
};

src/core/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ SET(QGIS_CORE_SRCS
2828
symbology-ng/qgslegendsymbolitemv2.cpp
2929
symbology-ng/qgslinesymbollayerv2.cpp
3030
symbology-ng/qgsmarkersymbollayerv2.cpp
31+
symbology-ng/qgsnullsymbolrenderer.cpp
3132
symbology-ng/qgspointdisplacementrenderer.cpp
3233
symbology-ng/qgsrendererv2.cpp
3334
symbology-ng/qgsrendererv2registry.cpp
@@ -796,6 +797,7 @@ SET(QGIS_CORE_HDRS
796797
symbology-ng/qgssinglesymbolrendererv2.h
797798
symbology-ng/qgsheatmaprenderer.h
798799
symbology-ng/qgsinvertedpolygonrenderer.h
800+
symbology-ng/qgsnullsymbolrenderer.h
799801
symbology-ng/qgssymbollayerv2.h
800802
symbology-ng/qgssymbollayerv2registry.h
801803
symbology-ng/qgssymbollayerv2utils.h
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/***************************************************************************
2+
qgsnullsymbolrenderer.cpp
3+
---------------------
4+
begin : November 2014
5+
copyright : (C) 2014 by Nyall Dawson
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgsnullsymbolrenderer.h"
17+
#include "qgssymbolv2.h"
18+
19+
#include <QDomDocument>
20+
#include <QDomElement>
21+
22+
QgsNullSymbolRenderer::QgsNullSymbolRenderer()
23+
: QgsFeatureRendererV2( "nullSymbol" )
24+
{
25+
}
26+
27+
QgsNullSymbolRenderer::~QgsNullSymbolRenderer()
28+
{
29+
}
30+
31+
QgsSymbolV2* QgsNullSymbolRenderer::symbolForFeature( QgsFeature& , QgsRenderContext& )
32+
{
33+
return nullptr;
34+
}
35+
36+
QgsSymbolV2* QgsNullSymbolRenderer::originalSymbolForFeature( QgsFeature&, QgsRenderContext& )
37+
{
38+
return nullptr;
39+
}
40+
41+
bool QgsNullSymbolRenderer::renderFeature( QgsFeature &feature, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker )
42+
{
43+
//render selected features or features being edited only
44+
if ( !selected && !drawVertexMarker )
45+
{
46+
return true;
47+
}
48+
49+
if ( !feature.constGeometry() ||
50+
feature.constGeometry()->type() == QGis::NoGeometry ||
51+
feature.constGeometry()->type() == QGis::UnknownGeometry )
52+
return true;
53+
54+
if ( mSymbol.isNull() )
55+
{
56+
//create default symbol
57+
mSymbol.reset( QgsSymbolV2::defaultSymbol( feature.constGeometry()->type() ) );
58+
mSymbol->startRender( context );
59+
}
60+
61+
mSymbol->renderFeature( feature, context, layer, selected, drawVertexMarker, mCurrentVertexMarkerType, mCurrentVertexMarkerSize );
62+
63+
return true;
64+
}
65+
66+
void QgsNullSymbolRenderer::startRender( QgsRenderContext& context, const QgsFields& fields )
67+
{
68+
Q_UNUSED( context );
69+
Q_UNUSED( fields );
70+
}
71+
72+
void QgsNullSymbolRenderer::stopRender( QgsRenderContext& context )
73+
{
74+
if ( mSymbol.data() )
75+
{
76+
mSymbol->stopRender( context );
77+
}
78+
}
79+
80+
bool QgsNullSymbolRenderer::willRenderFeature( QgsFeature&, QgsRenderContext& )
81+
{
82+
//return true for every feature - so they are still selectable
83+
return true;
84+
}
85+
86+
QList<QString> QgsNullSymbolRenderer::usedAttributes()
87+
{
88+
return QList<QString>();
89+
}
90+
91+
QString QgsNullSymbolRenderer::dump() const
92+
{
93+
return QString( "NULL" );
94+
}
95+
96+
QgsFeatureRendererV2* QgsNullSymbolRenderer::clone() const
97+
{
98+
QgsNullSymbolRenderer* r = new QgsNullSymbolRenderer();
99+
return r;
100+
}
101+
102+
QgsSymbolV2List QgsNullSymbolRenderer::symbols( QgsRenderContext& )
103+
{
104+
return QgsSymbolV2List();
105+
}
106+
107+
QgsFeatureRendererV2* QgsNullSymbolRenderer::create( QDomElement& element )
108+
{
109+
Q_UNUSED( element );
110+
QgsNullSymbolRenderer* r = new QgsNullSymbolRenderer();
111+
return r;
112+
}
113+
114+
QDomElement QgsNullSymbolRenderer::save( QDomDocument& doc )
115+
{
116+
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
117+
rendererElem.setAttribute( "type", "nullSymbol" );
118+
return rendererElem;
119+
}
120+
121+
QgsNullSymbolRenderer* QgsNullSymbolRenderer::convertFromRenderer( const QgsFeatureRendererV2 *renderer )
122+
{
123+
Q_UNUSED( renderer );
124+
return new QgsNullSymbolRenderer();
125+
}

0 commit comments

Comments
 (0)