Skip to content

Commit

Permalink
[symbology] When rendering a multipart geometry, ensure that
Browse files Browse the repository at this point in the history
geometry generator symbol is only rendered once, instead of
once per part

Fixes #23730
  • Loading branch information
nyalldawson committed Jun 15, 2020
1 parent 816d4b0 commit d98fe9f
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 3 deletions.
Expand Up @@ -40,9 +40,12 @@ that is created by this generator.


virtual void startRender( QgsSymbolRenderContext &context ); virtual void startRender( QgsSymbolRenderContext &context );



virtual void stopRender( QgsSymbolRenderContext &context ); virtual void stopRender( QgsSymbolRenderContext &context );


virtual void startFeatureRender( const QgsFeature &feature, QgsRenderContext &context );

virtual void stopFeatureRender( const QgsFeature &feature, QgsRenderContext &context );



virtual QgsSymbolLayer *clone() const /Factory/; virtual QgsSymbolLayer *clone() const /Factory/;


Expand Down
17 changes: 17 additions & 0 deletions src/core/symbology/qgsgeometrygeneratorsymbollayer.cpp
Expand Up @@ -96,6 +96,17 @@ void QgsGeometryGeneratorSymbolLayer::stopRender( QgsSymbolRenderContext &contex
mSymbol->stopRender( context.renderContext() ); mSymbol->stopRender( context.renderContext() );
} }


void QgsGeometryGeneratorSymbolLayer::startFeatureRender( const QgsFeature &, QgsRenderContext & )
{
mRenderingFeature = true;
mHasRenderedFeature = false;
}

void QgsGeometryGeneratorSymbolLayer::stopFeatureRender( const QgsFeature &, QgsRenderContext & )
{
mRenderingFeature = false;
}

QgsSymbolLayer *QgsGeometryGeneratorSymbolLayer::clone() const QgsSymbolLayer *QgsGeometryGeneratorSymbolLayer::clone() const
{ {
QgsGeometryGeneratorSymbolLayer *clone = new QgsGeometryGeneratorSymbolLayer( mExpression->expression() ); QgsGeometryGeneratorSymbolLayer *clone = new QgsGeometryGeneratorSymbolLayer( mExpression->expression() );
Expand Down Expand Up @@ -192,6 +203,9 @@ bool QgsGeometryGeneratorSymbolLayer::isCompatibleWithSymbol( QgsSymbol *symbol
} }
void QgsGeometryGeneratorSymbolLayer::render( QgsSymbolRenderContext &context ) void QgsGeometryGeneratorSymbolLayer::render( QgsSymbolRenderContext &context )
{ {
if ( mRenderingFeature && mHasRenderedFeature )
return;

if ( context.feature() ) if ( context.feature() )
{ {
QgsExpressionContext &expressionContext = context.renderContext().expressionContext(); QgsExpressionContext &expressionContext = context.renderContext().expressionContext();
Expand All @@ -205,6 +219,9 @@ void QgsGeometryGeneratorSymbolLayer::render( QgsSymbolRenderContext &context )
subSymbolExpressionContextScope->setFeature( f ); subSymbolExpressionContextScope->setFeature( f );


mSymbol->renderFeature( f, context.renderContext(), -1, context.selected() ); mSymbol->renderFeature( f, context.renderContext(), -1, context.selected() );

if ( mRenderingFeature )
mHasRenderedFeature = true;
} }
} }


Expand Down
6 changes: 5 additions & 1 deletion src/core/symbology/qgsgeometrygeneratorsymbollayer.h
Expand Up @@ -49,8 +49,9 @@ class CORE_EXPORT QgsGeometryGeneratorSymbolLayer : public QgsSymbolLayer
QgsSymbol::SymbolType symbolType() const { return mSymbolType; } QgsSymbol::SymbolType symbolType() const { return mSymbolType; }


void startRender( QgsSymbolRenderContext &context ) override; void startRender( QgsSymbolRenderContext &context ) override;

void stopRender( QgsSymbolRenderContext &context ) override; void stopRender( QgsSymbolRenderContext &context ) override;
void startFeatureRender( const QgsFeature &feature, QgsRenderContext &context ) override;
void stopFeatureRender( const QgsFeature &feature, QgsRenderContext &context ) override;


QgsSymbolLayer *clone() const override SIP_FACTORY; QgsSymbolLayer *clone() const override SIP_FACTORY;


Expand Down Expand Up @@ -113,6 +114,9 @@ class CORE_EXPORT QgsGeometryGeneratorSymbolLayer : public QgsSymbolLayer
* The type of the sub symbol. * The type of the sub symbol.
*/ */
QgsSymbol::SymbolType mSymbolType; QgsSymbol::SymbolType mSymbolType;

bool mRenderingFeature = false;
bool mHasRenderedFeature = false;
}; };


#endif // QGSGEOMETRYGENERATORSYMBOLLAYER_H #endif // QGSGEOMETRYGENERATORSYMBOLLAYER_H
28 changes: 27 additions & 1 deletion tests/src/python/test_qgsgeometrygeneratorsymbollayer.py
Expand Up @@ -37,7 +37,8 @@
QgsRectangle, QgsRectangle,
QgsGeometryGeneratorSymbolLayer, QgsGeometryGeneratorSymbolLayer,
QgsSymbol, QgsSymbol,
QgsMultiRenderChecker QgsMultiRenderChecker,
QgsMapSettings
) )


from qgis.testing import start_app, unittest from qgis.testing import start_app, unittest
Expand Down Expand Up @@ -163,6 +164,31 @@ def test_buffer_points(self):
self.report += renderchecker.report() self.report += renderchecker.report()
self.assertTrue(res) self.assertTrue(res)


def test_multi_poly_opacity(self):
# test that multi-type features are only rendered once

multipoly = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'multipatch.shp'), 'Polygons', 'ogr')

sym = QgsFillSymbol.createSimple({'color': '#77fdbf6f', 'outline_color': 'black'})

buffer_layer = QgsGeometryGeneratorSymbolLayer.create({'geometryModifier': 'buffer($geometry, -0.01)', 'outline_color': 'black'})
buffer_layer.setSymbolType(QgsSymbol.Fill)
buffer_layer.setSubSymbol(sym)
geom_symbol = QgsFillSymbol()
geom_symbol.changeSymbolLayer(0, buffer_layer)
multipoly.renderer().setSymbol(geom_symbol)

mapsettings = QgsMapSettings(self.mapsettings)
mapsettings.setExtent(multipoly.extent())
mapsettings.setLayers([multipoly])

renderchecker = QgsMultiRenderChecker()
renderchecker.setMapSettings(mapsettings)
renderchecker.setControlName('expected_geometrygenerator_opacity')
res = renderchecker.runTest('geometrygenerator_opacity')
self.report += renderchecker.report()
self.assertTrue(res)



if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit d98fe9f

Please sign in to comment.