Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[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 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 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
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
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
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()
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.