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.
Original file line number Diff line number Diff line change
Expand Up @@ -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/;

Expand Down
17 changes: 17 additions & 0 deletions src/core/symbology/qgsgeometrygeneratorsymbollayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() );
Expand Down Expand Up @@ -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();
Expand All @@ -205,6 +219,9 @@ void QgsGeometryGeneratorSymbolLayer::render( QgsSymbolRenderContext &context )
subSymbolExpressionContextScope->setFeature( f );

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
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
28 changes: 27 additions & 1 deletion tests/src/python/test_qgsgeometrygeneratorsymbollayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
QgsRectangle,
QgsGeometryGeneratorSymbolLayer,
QgsSymbol,
QgsMultiRenderChecker
QgsMultiRenderChecker,
QgsMapSettings
)

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.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()
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
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.