Skip to content
Permalink
Browse files

[symbology] When rendering a multipart geometry, ensure that

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 d98fe9f989f3b0677282acdf2ba99f4aa4fa08cc
@@ -40,9 +40,12 @@ that is created by this generator.

virtual void startRender( 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/;

@@ -96,6 +96,17 @@ void QgsGeometryGeneratorSymbolLayer::stopRender( QgsSymbolRenderContext &contex
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
{
QgsGeometryGeneratorSymbolLayer *clone = new QgsGeometryGeneratorSymbolLayer( mExpression->expression() );
@@ -192,6 +203,9 @@ bool QgsGeometryGeneratorSymbolLayer::isCompatibleWithSymbol( QgsSymbol *symbol
}
void QgsGeometryGeneratorSymbolLayer::render( QgsSymbolRenderContext &context )
{
if ( mRenderingFeature && mHasRenderedFeature )
return;

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

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

if ( mRenderingFeature )
mHasRenderedFeature = true;
}
}

@@ -49,8 +49,9 @@ class CORE_EXPORT QgsGeometryGeneratorSymbolLayer : public QgsSymbolLayer
QgsSymbol::SymbolType symbolType() const { return mSymbolType; }

void startRender( 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;

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

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

#endif // QGSGEOMETRYGENERATORSYMBOLLAYER_H
@@ -37,7 +37,8 @@
QgsRectangle,
QgsGeometryGeneratorSymbolLayer,
QgsSymbol,
QgsMultiRenderChecker
QgsMultiRenderChecker,
QgsMapSettings
)

from qgis.testing import start_app, unittest
@@ -163,6 +164,31 @@ def test_buffer_points(self):
self.report += renderchecker.report()
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__':
unittest.main()
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 comments on commit d98fe9f

Please sign in to comment.
You can’t perform that action at this time.