diff --git a/src/core/symbology-ng/qgssymbol.cpp b/src/core/symbology-ng/qgssymbol.cpp index 25648668d171..04e590645f31 100644 --- a/src/core/symbology-ng/qgssymbol.cpp +++ b/src/core/symbology-ng/qgssymbol.cpp @@ -47,6 +47,7 @@ #include #include +#include inline QgsDataDefined* rotateWholeSymbol( double additionalRotation, const QgsDataDefined& dd ) @@ -842,30 +843,49 @@ void QgsSymbol::renderFeature( const QgsFeature& feature, QgsRenderContext& cont const QgsGeometryCollection& geomCollection = dynamic_cast( *segmentizedGeometry.geometry() ); const unsigned int num = geomCollection.numGeometries(); + // Sort components by approximate area (probably a bit faster than using + // area() ) + std::map > mapAreaToPartNum; for ( unsigned int i = 0; i < num; ++i ) { - mSymbolRenderContext->setGeometryPartNum( i + 1 ); - mSymbolRenderContext->expressionContextScope()->setVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1 ); - - context.setGeometry( geomCollection.geometryN( i ) ); const QgsPolygonV2& polygon = dynamic_cast( *geomCollection.geometryN( i ) ); - _getPolygon( pts, holes, context, polygon, !tileMapRendering && clipFeaturesToExtent() ); - static_cast( this )->renderPolygon( pts, ( !holes.isEmpty() ? &holes : nullptr ), &feature, context, layer, selected ); + const QgsRectangle r( polygon.boundingBox() ); + mapAreaToPartNum[ r.width() * r.height()] << i; + } - if ( drawVertexMarker && !usingSegmentizedGeometry ) + // Draw starting with larger parts down to smaller parts, so that in + // case of a part being incorrectly inside another part, it is drawn + // on top of it (#15419) + std::map >::const_reverse_iterator iter = mapAreaToPartNum.rbegin(); + for ( ; iter != mapAreaToPartNum.rend(); ++iter ) + { + const QList& listPartIndex = iter->second; + for ( int idx = 0; idx < listPartIndex.size(); ++idx ) { - if ( i == 0 ) - { - markers = pts; - } - else - { - markers << pts; - } + const unsigned i = listPartIndex[idx]; + mSymbolRenderContext->setGeometryPartNum( i + 1 ); + mSymbolRenderContext->expressionContextScope()->setVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1 ); + + context.setGeometry( geomCollection.geometryN( i ) ); + const QgsPolygonV2& polygon = dynamic_cast( *geomCollection.geometryN( i ) ); + _getPolygon( pts, holes, context, polygon, !tileMapRendering && clipFeaturesToExtent() ); + static_cast( this )->renderPolygon( pts, ( !holes.isEmpty() ? &holes : nullptr ), &feature, context, layer, selected ); - Q_FOREACH ( const QPolygonF& hole, holes ) + if ( drawVertexMarker && !usingSegmentizedGeometry ) { - markers << hole; + if ( i == 0 ) + { + markers = pts; + } + else + { + markers << pts; + } + + Q_FOREACH ( const QPolygonF& hole, holes ) + { + markers << hole; + } } } }