mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-16 00:05:45 -04:00
[symbology] When rendering features, split the geometry fetching
and preparation stage from the symbol layer rendering stage, and ensure that QgsSymbolLayer::startFeatureRender and ::stopFeatureRender is correctly called in the right sequence when rendering multi-layer symbols This fixes issues with symbol layers which rely on startFeatureRender and stopFeatureRender to correctly render, e.g. the Random Marker Fill symbol layer. Before this fix, the logic looked like: - for every symbol layer in the symbol, call startFeatureRender - for each part in polygon, prepare the part geometry and then render each symbol layer - for every symbol layer in the symbol, call stopFeatureRender The issue with this approach is that symbol layers which defer rendering to the stopFeatureRender stage are always rendered after ALL other symbol layers in the symbol, regardless of the actual order of the symbol layers. Ultimately this causes Random Marker Fill layers to always render on the top of symbols. The new logic is: - for each part in polygon, prepare the geometry and store the result - for each symbol layer in the symbol: - call startFeatureRender - render the layer using each of the previously prepared parts - call stopFeatureRender This results in correct stacking of the random marker fill in multi layer symbols, because the stopFeatureRender call is correctly called before the next layer's startFeatureRender and renderPolygon calls Also, use QVector instead of QList for rings for improved efficiency
This commit is contained in:
parent
ea4f2bbfb9
commit
ef97e8c6fc
@ -45,7 +45,7 @@ Caller takes ownership of the returned symbol layer.
|
||||
virtual void stopRender( QgsSymbolRenderContext &context );
|
||||
|
||||
|
||||
virtual void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
virtual void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
|
||||
|
||||
virtual QgsStringMap properties() const;
|
||||
@ -214,7 +214,7 @@ Caller takes ownership of the returned symbol layer.
|
||||
virtual void stopRender( QgsSymbolRenderContext &context );
|
||||
|
||||
|
||||
virtual void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
virtual void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
|
||||
|
||||
virtual QgsStringMap properties() const;
|
||||
@ -374,7 +374,7 @@ Caller takes ownership of the returned symbol layer.
|
||||
virtual void stopRender( QgsSymbolRenderContext &context );
|
||||
|
||||
|
||||
virtual void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
virtual void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
|
||||
|
||||
virtual QgsStringMap properties() const;
|
||||
@ -686,7 +686,7 @@ Base class for polygon renderers generating texture images*
|
||||
public:
|
||||
|
||||
QgsImageFillSymbolLayer();
|
||||
virtual void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
virtual void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
|
||||
|
||||
virtual QgsSymbol *subSymbol();
|
||||
@ -806,7 +806,7 @@ Used internally when reading/writing symbols.
|
||||
|
||||
virtual QString layerType() const;
|
||||
|
||||
virtual void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
virtual void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
|
||||
virtual void startRender( QgsSymbolRenderContext &context );
|
||||
|
||||
@ -1952,7 +1952,7 @@ Caller takes ownership of the returned symbol layer.
|
||||
|
||||
virtual void stopRender( QgsSymbolRenderContext &context );
|
||||
|
||||
virtual void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
virtual void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
|
||||
virtual QgsStringMap properties() const;
|
||||
|
||||
@ -2139,7 +2139,7 @@ Caller takes ownership of the returned symbol layer.
|
||||
virtual void stopRender( QgsSymbolRenderContext &context );
|
||||
|
||||
|
||||
virtual void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
virtual void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
|
||||
|
||||
virtual QgsStringMap properties() const;
|
||||
|
@ -52,7 +52,7 @@ Creates a new QgsSimpleLineSymbolLayer from an SLD XML DOM ``element``.
|
||||
|
||||
virtual void renderPolyline( const QPolygonF &points, QgsSymbolRenderContext &context );
|
||||
|
||||
virtual void renderPolygonStroke( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
virtual void renderPolygonStroke( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
|
||||
virtual QgsStringMap properties() const;
|
||||
|
||||
@ -506,7 +506,7 @@ calculating individual symbol angles.
|
||||
|
||||
virtual void renderPolyline( const QPolygonF &points, QgsSymbolRenderContext &context ) ${SIP_FINAL};
|
||||
|
||||
virtual void renderPolygonStroke( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) ${SIP_FINAL};
|
||||
virtual void renderPolygonStroke( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context ) ${SIP_FINAL};
|
||||
|
||||
virtual QgsUnitTypes::RenderUnit outputUnit() const ${SIP_FINAL};
|
||||
|
||||
|
@ -548,7 +548,7 @@ If ``correctRingOrientation`` is ``True`` then the ring will be oriented to matc
|
||||
clockwise for exterior rings and counter-clockwise for interior rings.
|
||||
%End
|
||||
|
||||
static void _getPolygon( QPolygonF &pts, QList<QPolygonF> &holes, QgsRenderContext &context, const QgsPolygon &polygon, bool clipToExtent = true, bool correctRingOrientation = false );
|
||||
static void _getPolygon( QPolygonF &pts, QVector<QPolygonF> &holes, QgsRenderContext &context, const QgsPolygon &polygon, bool clipToExtent = true, bool correctRingOrientation = false );
|
||||
%Docstring
|
||||
Creates a polygon in screen coordinates from a QgsPolygonXYin map coordinates
|
||||
|
||||
@ -1206,7 +1206,7 @@ Ownership of the ``layers`` are transferred to the symbol.
|
||||
%End
|
||||
void setAngle( double angle );
|
||||
|
||||
void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, const QgsFeature *f, QgsRenderContext &context, int layer = -1, bool selected = false );
|
||||
void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, const QgsFeature *f, QgsRenderContext &context, int layer = -1, bool selected = false );
|
||||
%Docstring
|
||||
Renders the symbol using the given render ``context``.
|
||||
|
||||
|
@ -979,7 +979,7 @@ Renders the line symbol layer along the line joining ``points``, using the given
|
||||
.. seealso:: :py:func:`renderPolygonStroke`
|
||||
%End
|
||||
|
||||
virtual void renderPolygonStroke( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
virtual void renderPolygonStroke( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
%Docstring
|
||||
Renders the line symbol layer along the outline of polygon, using the given render ``context``.
|
||||
|
||||
@ -1167,9 +1167,11 @@ class QgsFillSymbolLayer : QgsSymbolLayer
|
||||
|
||||
|
||||
|
||||
virtual void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) = 0;
|
||||
virtual void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context ) = 0;
|
||||
%Docstring
|
||||
QgsFillSymbolLayer cannot be copied
|
||||
Renders the fill symbol layer for the polygon whose outer ring is defined by ``points``, using the given render ``context``.
|
||||
|
||||
The ``rings`` argument optionally specifies a list of polygon rings to render as holes.
|
||||
%End
|
||||
|
||||
virtual void drawPreviewIcon( QgsSymbolRenderContext &context, QSize size );
|
||||
@ -1180,7 +1182,7 @@ QgsFillSymbolLayer cannot be copied
|
||||
|
||||
protected:
|
||||
QgsFillSymbolLayer( bool locked = false );
|
||||
void _renderPolygon( QPainter *p, const QPolygonF &points, const QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
void _renderPolygon( QPainter *p, const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
%Docstring
|
||||
Default method to render polygon
|
||||
%End
|
||||
|
@ -713,7 +713,7 @@ Determines an SVG symbol's name from its ``path``.
|
||||
Calculate the centroid point of a QPolygonF
|
||||
%End
|
||||
|
||||
static QPointF polygonPointOnSurface( const QPolygonF &points, QList<QPolygonF> *rings = 0 );
|
||||
static QPointF polygonPointOnSurface( const QPolygonF &points, const QVector<QPolygonF> *rings = 0 );
|
||||
%Docstring
|
||||
Calculate a point on the surface of a QPolygonF
|
||||
%End
|
||||
|
@ -358,7 +358,7 @@ void QgsAnnotation::drawFrame( QgsRenderContext &context ) const
|
||||
|
||||
QPolygonF poly;
|
||||
poly.reserve( 9 + ( mHasFixedMapPosition ? 3 : 0 ) );
|
||||
QList<QPolygonF> rings; //empty list
|
||||
QVector<QPolygonF> rings; //empty list
|
||||
for ( int i = 0; i < 4; ++i )
|
||||
{
|
||||
QLineF currentSegment = segment( i, &context );
|
||||
|
@ -127,7 +127,7 @@ void QgsLayoutItemMapOverview::draw( QPainter *painter )
|
||||
QPolygonF intersectPolygon;
|
||||
intersectPolygon = mapTransform.map( intersectExtent );
|
||||
|
||||
QList<QPolygonF> rings; //empty list
|
||||
QVector<QPolygonF> rings; //empty list
|
||||
if ( !mInverted )
|
||||
{
|
||||
//Render the intersecting map extent
|
||||
|
@ -280,7 +280,7 @@ void QgsLayoutItemPage::draw( QgsLayoutItemRenderContext &context )
|
||||
// round up
|
||||
QPolygonF pagePolygon = QPolygonF( QRectF( maxBleedPixels, maxBleedPixels,
|
||||
std::ceil( rect().width() * scale ) - 2 * maxBleedPixels, std::ceil( rect().height() * scale ) - 2 * maxBleedPixels ) );
|
||||
QList<QPolygonF> rings; //empty list
|
||||
QVector<QPolygonF> rings; //empty list
|
||||
|
||||
symbol->renderPolygon( pagePolygon, &rings, nullptr, context.renderContext() );
|
||||
symbol->stopRender( context.renderContext() );
|
||||
|
@ -117,7 +117,7 @@ void QgsLayoutItemPolygon::_draw( QgsLayoutItemRenderContext &context, const QSt
|
||||
double scale = context.renderContext().convertToPainterUnits( 1, QgsUnitTypes::RenderMillimeters );
|
||||
QTransform t = QTransform::fromScale( scale, scale );
|
||||
|
||||
QList<QPolygonF> rings; //empty
|
||||
QVector<QPolygonF> rings; //empty
|
||||
QPainterPath polygonPath;
|
||||
polygonPath.addPolygon( mPolygon );
|
||||
|
||||
|
@ -217,7 +217,7 @@ void QgsLayoutItemShape::draw( QgsLayoutItemRenderContext &context )
|
||||
}
|
||||
}
|
||||
|
||||
QList<QPolygonF> rings; //empty list
|
||||
QVector<QPolygonF> rings; //empty list
|
||||
|
||||
symbol()->startRender( context.renderContext() );
|
||||
symbol()->renderPolygon( shapePolygon, &rings, nullptr, context.renderContext() );
|
||||
|
@ -263,7 +263,7 @@ void QgsSimpleFillSymbolLayer::stopRender( QgsSymbolRenderContext &context )
|
||||
Q_UNUSED( context )
|
||||
}
|
||||
|
||||
void QgsSimpleFillSymbolLayer::renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
void QgsSimpleFillSymbolLayer::renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
{
|
||||
QPainter *p = context.renderContext().painter();
|
||||
if ( !p )
|
||||
@ -842,7 +842,7 @@ void QgsGradientFillSymbolLayer::stopRender( QgsSymbolRenderContext &context )
|
||||
Q_UNUSED( context )
|
||||
}
|
||||
|
||||
void QgsGradientFillSymbolLayer::renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
void QgsGradientFillSymbolLayer::renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
{
|
||||
QPainter *p = context.renderContext().painter();
|
||||
if ( !p )
|
||||
@ -1129,7 +1129,7 @@ void QgsShapeburstFillSymbolLayer::stopRender( QgsSymbolRenderContext &context )
|
||||
Q_UNUSED( context )
|
||||
}
|
||||
|
||||
void QgsShapeburstFillSymbolLayer::renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
void QgsShapeburstFillSymbolLayer::renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
{
|
||||
QPainter *p = context.renderContext().painter();
|
||||
if ( !p )
|
||||
@ -1560,7 +1560,7 @@ QgsImageFillSymbolLayer::QgsImageFillSymbolLayer()
|
||||
setSubSymbol( new QgsLineSymbol() );
|
||||
}
|
||||
|
||||
void QgsImageFillSymbolLayer::renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
void QgsImageFillSymbolLayer::renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
{
|
||||
QPainter *p = context.renderContext().painter();
|
||||
if ( !p )
|
||||
@ -1606,8 +1606,7 @@ void QgsImageFillSymbolLayer::renderPolygon( const QPolygonF &points, QList<QPol
|
||||
mStroke->renderPolyline( points, context.feature(), context.renderContext(), -1, SELECT_FILL_BORDER && context.selected() );
|
||||
if ( rings )
|
||||
{
|
||||
QList<QPolygonF>::const_iterator ringIt = rings->constBegin();
|
||||
for ( ; ringIt != rings->constEnd(); ++ringIt )
|
||||
for ( auto ringIt = rings->constBegin(); ringIt != rings->constEnd(); ++ringIt )
|
||||
{
|
||||
mStroke->renderPolyline( *ringIt, context.feature(), context.renderContext(), -1, SELECT_FILL_BORDER && context.selected() );
|
||||
}
|
||||
@ -3507,7 +3506,7 @@ void QgsCentroidFillSymbolLayer::stopRender( QgsSymbolRenderContext &context )
|
||||
mMarker->stopRender( context.renderContext() );
|
||||
}
|
||||
|
||||
void QgsCentroidFillSymbolLayer::renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
void QgsCentroidFillSymbolLayer::renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
{
|
||||
if ( !mPointOnAllParts )
|
||||
{
|
||||
@ -3758,7 +3757,7 @@ QString QgsRasterFillSymbolLayer::layerType() const
|
||||
return QStringLiteral( "RasterFill" );
|
||||
}
|
||||
|
||||
void QgsRasterFillSymbolLayer::renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
void QgsRasterFillSymbolLayer::renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
{
|
||||
QPainter *p = context.renderContext().painter();
|
||||
if ( !p )
|
||||
@ -4009,7 +4008,7 @@ void QgsRandomMarkerFillSymbolLayer::stopRender( QgsSymbolRenderContext &context
|
||||
mMarker->stopRender( context.renderContext() );
|
||||
}
|
||||
|
||||
void QgsRandomMarkerFillSymbolLayer::renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
void QgsRandomMarkerFillSymbolLayer::renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
{
|
||||
Part part;
|
||||
part.exterior = points;
|
||||
|
@ -65,7 +65,7 @@ class CORE_EXPORT QgsSimpleFillSymbolLayer : public QgsFillSymbolLayer
|
||||
|
||||
void stopRender( QgsSymbolRenderContext &context ) override;
|
||||
|
||||
void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
|
||||
QgsStringMap properties() const override;
|
||||
|
||||
@ -229,7 +229,7 @@ class CORE_EXPORT QgsGradientFillSymbolLayer : public QgsFillSymbolLayer
|
||||
|
||||
void stopRender( QgsSymbolRenderContext &context ) override;
|
||||
|
||||
void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
|
||||
QgsStringMap properties() const override;
|
||||
|
||||
@ -391,7 +391,7 @@ class CORE_EXPORT QgsShapeburstFillSymbolLayer : public QgsFillSymbolLayer
|
||||
|
||||
void stopRender( QgsSymbolRenderContext &context ) override;
|
||||
|
||||
void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
|
||||
QgsStringMap properties() const override;
|
||||
|
||||
@ -648,7 +648,7 @@ class CORE_EXPORT QgsImageFillSymbolLayer: public QgsFillSymbolLayer
|
||||
public:
|
||||
|
||||
QgsImageFillSymbolLayer();
|
||||
void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
|
||||
QgsSymbol *subSymbol() override { return mStroke.get(); }
|
||||
bool setSubSymbol( QgsSymbol *symbol SIP_TRANSFER ) override;
|
||||
@ -754,7 +754,7 @@ class CORE_EXPORT QgsRasterFillSymbolLayer: public QgsImageFillSymbolLayer
|
||||
|
||||
// implemented from base classes
|
||||
QString layerType() const override;
|
||||
void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
void startRender( QgsSymbolRenderContext &context ) override;
|
||||
void stopRender( QgsSymbolRenderContext &context ) override;
|
||||
QgsStringMap properties() const override;
|
||||
@ -1759,7 +1759,7 @@ class CORE_EXPORT QgsRandomMarkerFillSymbolLayer : public QgsFillSymbolLayer
|
||||
QString layerType() const override;
|
||||
void startRender( QgsSymbolRenderContext &context ) override;
|
||||
void stopRender( QgsSymbolRenderContext &context ) override;
|
||||
void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
QgsStringMap properties() const override;
|
||||
QgsRandomMarkerFillSymbolLayer *clone() const override SIP_FACTORY;
|
||||
|
||||
@ -1895,7 +1895,7 @@ class CORE_EXPORT QgsRandomMarkerFillSymbolLayer : public QgsFillSymbolLayer
|
||||
struct Part
|
||||
{
|
||||
QPolygonF exterior;
|
||||
QList<QPolygonF> rings;
|
||||
QVector<QPolygonF> rings;
|
||||
};
|
||||
|
||||
QVector< Part > mCurrentParts;
|
||||
@ -1942,7 +1942,7 @@ class CORE_EXPORT QgsCentroidFillSymbolLayer : public QgsFillSymbolLayer
|
||||
|
||||
void stopRender( QgsSymbolRenderContext &context ) override;
|
||||
|
||||
void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
|
||||
QgsStringMap properties() const override;
|
||||
|
||||
|
@ -238,7 +238,7 @@ void QgsSimpleLineSymbolLayer::stopRender( QgsSymbolRenderContext &context )
|
||||
Q_UNUSED( context )
|
||||
}
|
||||
|
||||
void QgsSimpleLineSymbolLayer::renderPolygonStroke( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
void QgsSimpleLineSymbolLayer::renderPolygonStroke( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
{
|
||||
QPainter *p = context.renderContext().painter();
|
||||
if ( !p )
|
||||
@ -263,8 +263,7 @@ void QgsSimpleLineSymbolLayer::renderPolygonStroke( const QPolygonF &points, QLi
|
||||
if ( rings )
|
||||
{
|
||||
//add polygon rings
|
||||
QList<QPolygonF>::const_iterator it = rings->constBegin();
|
||||
for ( ; it != rings->constEnd(); ++it )
|
||||
for ( auto it = rings->constBegin(); it != rings->constEnd(); ++it )
|
||||
{
|
||||
QPolygonF ring = *it;
|
||||
clipPath.addPolygon( ring );
|
||||
@ -867,7 +866,7 @@ void QgsTemplatedLineSymbolLayerBase::renderPolyline( const QPolygonF &points, Q
|
||||
context.renderContext().painter()->restore();
|
||||
}
|
||||
|
||||
void QgsTemplatedLineSymbolLayerBase::renderPolygonStroke( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
void QgsTemplatedLineSymbolLayerBase::renderPolygonStroke( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
{
|
||||
const QgsCurvePolygon *curvePolygon = dynamic_cast<const QgsCurvePolygon *>( context.renderContext().geometry() );
|
||||
|
||||
|
@ -68,7 +68,7 @@ class CORE_EXPORT QgsSimpleLineSymbolLayer : public QgsLineSymbolLayer
|
||||
void stopRender( QgsSymbolRenderContext &context ) override;
|
||||
void renderPolyline( const QPolygonF &points, QgsSymbolRenderContext &context ) override;
|
||||
//overridden so that clip path can be set when using draw inside polygon option
|
||||
void renderPolygonStroke( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
void renderPolygonStroke( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
QgsStringMap properties() const override;
|
||||
QgsSimpleLineSymbolLayer *clone() const override SIP_FACTORY;
|
||||
void toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap &props ) const override;
|
||||
@ -467,7 +467,7 @@ class CORE_EXPORT QgsTemplatedLineSymbolLayerBase : public QgsLineSymbolLayer
|
||||
const QgsMapUnitScale &averageAngleMapUnitScale() const { return mAverageAngleLengthMapUnitScale; }
|
||||
|
||||
void renderPolyline( const QPolygonF &points, QgsSymbolRenderContext &context ) FINAL;
|
||||
void renderPolygonStroke( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) FINAL;
|
||||
void renderPolygonStroke( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context ) FINAL;
|
||||
QgsUnitTypes::RenderUnit outputUnit() const FINAL;
|
||||
void setMapUnitScale( const QgsMapUnitScale &scale ) FINAL;
|
||||
QgsMapUnitScale mapUnitScale() const FINAL;
|
||||
|
@ -214,15 +214,18 @@ QPolygonF QgsSymbol::_getPolygonRing( QgsRenderContext &context, const QgsCurve
|
||||
return poly;
|
||||
}
|
||||
|
||||
void QgsSymbol::_getPolygon( QPolygonF &pts, QList<QPolygonF> &holes, QgsRenderContext &context, const QgsPolygon &polygon, const bool clipToExtent, const bool correctRingOrientation )
|
||||
void QgsSymbol::_getPolygon( QPolygonF &pts, QVector<QPolygonF> &holes, QgsRenderContext &context, const QgsPolygon &polygon, const bool clipToExtent, const bool correctRingOrientation )
|
||||
{
|
||||
holes.clear();
|
||||
|
||||
pts = _getPolygonRing( context, *polygon.exteriorRing(), clipToExtent, true, correctRingOrientation );
|
||||
for ( int idx = 0; idx < polygon.numInteriorRings(); idx++ )
|
||||
const int ringCount = polygon.numInteriorRings();
|
||||
holes.reserve( ringCount );
|
||||
for ( int idx = 0; idx < ringCount; idx++ )
|
||||
{
|
||||
const QPolygonF hole = _getPolygonRing( context, *( polygon.interiorRing( idx ) ), clipToExtent, false, correctRingOrientation );
|
||||
if ( !hole.isEmpty() ) holes.append( hole );
|
||||
if ( !hole.isEmpty() )
|
||||
holes.append( hole );
|
||||
}
|
||||
}
|
||||
|
||||
@ -560,7 +563,7 @@ void QgsSymbol::drawPreviewIcon( QPainter *painter, QSize size, QgsRenderContext
|
||||
|
||||
for ( const QList< QPolygonF > &poly : polys )
|
||||
{
|
||||
QList< QPolygonF > rings;
|
||||
QVector< QPolygonF > rings;
|
||||
for ( int i = 1; i < poly.size(); ++i )
|
||||
rings << poly.at( i );
|
||||
lsl->renderPolygonStroke( poly.value( 0 ), &rings, symbolContext );
|
||||
@ -878,8 +881,13 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
|
||||
|
||||
QgsGeometry renderedBoundsGeom;
|
||||
|
||||
startFeatureRender( feature, context, layer );
|
||||
|
||||
// Step 1 - collect the set of painter coordinate geometries to render.
|
||||
// We do this upfront, because we only want to ever do this once, regardless how many symbol layers we need to render.
|
||||
QVector< QPointF > pointsToRender;
|
||||
QVector< QPolygonF > linesToRender;
|
||||
QVector< QPolygonF > polygonsToRender;
|
||||
QVector< QVector< QPolygonF > > polygonRingsToRender;
|
||||
std::map<double, QList<unsigned int> > mapAreaToPartNum;
|
||||
switch ( QgsWkbTypes::flatType( segmentizedGeometry.constGet()->wkbType() ) )
|
||||
{
|
||||
case QgsWkbTypes::Point:
|
||||
@ -892,7 +900,8 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
|
||||
|
||||
const QgsPoint *point = static_cast< const QgsPoint * >( segmentizedGeometry.constGet() );
|
||||
const QPointF pt = _getPoint( context, *point );
|
||||
static_cast<QgsMarkerSymbol *>( this )->renderPoint( pt, &feature, context, layer, selected );
|
||||
|
||||
pointsToRender << pt;
|
||||
|
||||
if ( context.hasRenderedFeatureHandlers() || context.testFlag( QgsRenderContext::DrawSymbolBounds ) )
|
||||
{
|
||||
@ -914,8 +923,9 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
|
||||
{
|
||||
markers << pt;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsWkbTypes::LineString:
|
||||
{
|
||||
if ( mType != QgsSymbol::Line )
|
||||
@ -925,7 +935,7 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
|
||||
}
|
||||
const QgsCurve &curve = dynamic_cast<const QgsCurve &>( *segmentizedGeometry.constGet() );
|
||||
const QPolygonF pts = _getLineString( context, curve, !tileMapRendering && clipFeaturesToExtent() );
|
||||
static_cast<QgsLineSymbol *>( this )->renderPolyline( pts, &feature, context, layer, selected );
|
||||
linesToRender << pts;
|
||||
|
||||
if ( context.hasRenderedFeatureHandlers() )
|
||||
renderedBoundsGeom = QgsGeometry::fromQPolygonF( pts );
|
||||
@ -934,13 +944,14 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
|
||||
{
|
||||
markers = pts;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsWkbTypes::Polygon:
|
||||
case QgsWkbTypes::Triangle:
|
||||
{
|
||||
QPolygonF pts;
|
||||
QList<QPolygonF> holes;
|
||||
QVector<QPolygonF> holes;
|
||||
if ( mType != QgsSymbol::Fill )
|
||||
{
|
||||
QgsDebugMsg( QStringLiteral( "polygon can be drawn only with fill symbol!" ) );
|
||||
@ -953,7 +964,8 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
|
||||
break;
|
||||
}
|
||||
_getPolygon( pts, holes, context, polygon, !tileMapRendering && clipFeaturesToExtent(), mForceRHR );
|
||||
static_cast<QgsFillSymbol *>( this )->renderPolygon( pts, ( !holes.isEmpty() ? &holes : nullptr ), &feature, context, layer, selected );
|
||||
polygonsToRender << pts;
|
||||
polygonRingsToRender << holes;
|
||||
|
||||
if ( context.hasRenderedFeatureHandlers() )
|
||||
renderedBoundsGeom = QgsGeometry::fromQPolygonF( pts ); // TODO - consider holes?
|
||||
@ -968,8 +980,8 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
|
||||
markers << hole;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsWkbTypes::MultiPoint:
|
||||
{
|
||||
@ -980,24 +992,13 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
|
||||
}
|
||||
|
||||
const QgsMultiPoint &mp = static_cast< const QgsMultiPoint & >( *segmentizedGeometry.constGet() );
|
||||
|
||||
if ( drawVertexMarker && !usingSegmentizedGeometry )
|
||||
{
|
||||
markers.reserve( mp.numGeometries() );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < mp.numGeometries(); ++i )
|
||||
{
|
||||
if ( context.renderingStopped() )
|
||||
break;
|
||||
|
||||
mSymbolRenderContext->setGeometryPartNum( i + 1 );
|
||||
if ( needsExpressionContext )
|
||||
mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1, true ) );
|
||||
|
||||
const QgsPoint &point = static_cast< const QgsPoint & >( *mp.geometryN( i ) );
|
||||
const QPointF pt = _getPoint( context, point );
|
||||
static_cast<QgsMarkerSymbol *>( this )->renderPoint( pt, &feature, context, layer, selected );
|
||||
pointsToRender << pt;
|
||||
|
||||
if ( context.hasRenderedFeatureHandlers() )
|
||||
{
|
||||
@ -1010,8 +1011,8 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
|
||||
markers.append( pt );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsWkbTypes::MultiCurve:
|
||||
case QgsWkbTypes::MultiLineString:
|
||||
@ -1030,14 +1031,9 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
|
||||
if ( context.renderingStopped() )
|
||||
break;
|
||||
|
||||
mSymbolRenderContext->setGeometryPartNum( i + 1 );
|
||||
if ( needsExpressionContext )
|
||||
mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1, true ) );
|
||||
|
||||
context.setGeometry( geomCollection.geometryN( i ) );
|
||||
const QgsCurve &curve = dynamic_cast<const QgsCurve &>( *geomCollection.geometryN( i ) );
|
||||
const QPolygonF pts = _getLineString( context, curve, !tileMapRendering && clipFeaturesToExtent() );
|
||||
static_cast<QgsLineSymbol *>( this )->renderPolyline( pts, &feature, context, layer, selected );
|
||||
linesToRender << pts;
|
||||
|
||||
if ( context.hasRenderedFeatureHandlers() )
|
||||
{
|
||||
@ -1049,8 +1045,8 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
|
||||
markers << pts;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsWkbTypes::MultiSurface:
|
||||
case QgsWkbTypes::MultiPolygon:
|
||||
@ -1062,14 +1058,13 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
|
||||
}
|
||||
|
||||
QPolygonF pts;
|
||||
QList<QPolygonF> holes;
|
||||
QVector<QPolygonF> holes;
|
||||
|
||||
const QgsGeometryCollection &geomCollection = dynamic_cast<const QgsGeometryCollection &>( *segmentizedGeometry.constGet() );
|
||||
const unsigned int num = geomCollection.numGeometries();
|
||||
|
||||
// Sort components by approximate area (probably a bit faster than using
|
||||
// area() )
|
||||
std::map<double, QList<unsigned int> > mapAreaToPartNum;
|
||||
for ( unsigned int i = 0; i < num; ++i )
|
||||
{
|
||||
const QgsPolygon &polygon = dynamic_cast<const QgsPolygon &>( *geomCollection.geometryN( i ) );
|
||||
@ -1086,21 +1081,14 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
|
||||
const QList<unsigned int> &listPartIndex = iter->second;
|
||||
for ( int idx = 0; idx < listPartIndex.size(); ++idx )
|
||||
{
|
||||
if ( context.renderingStopped() )
|
||||
break;
|
||||
|
||||
const unsigned i = listPartIndex[idx];
|
||||
mSymbolRenderContext->setGeometryPartNum( i + 1 );
|
||||
if ( needsExpressionContext )
|
||||
mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1, true ) );
|
||||
|
||||
context.setGeometry( geomCollection.geometryN( i ) );
|
||||
const QgsPolygon &polygon = dynamic_cast<const QgsPolygon &>( *geomCollection.geometryN( i ) );
|
||||
if ( !polygon.exteriorRing() )
|
||||
break;
|
||||
|
||||
_getPolygon( pts, holes, context, polygon, !tileMapRendering && clipFeaturesToExtent(), mForceRHR );
|
||||
static_cast<QgsFillSymbol *>( this )->renderPolygon( pts, ( !holes.isEmpty() ? &holes : nullptr ), &feature, context, layer, selected );
|
||||
polygonsToRender << pts;
|
||||
polygonRingsToRender << holes;
|
||||
|
||||
if ( context.hasRenderedFeatureHandlers() )
|
||||
{
|
||||
@ -1121,6 +1109,7 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsWkbTypes::GeometryCollection:
|
||||
{
|
||||
const QgsGeometryCollection &geomCollection = dynamic_cast<const QgsGeometryCollection &>( *segmentizedGeometry.constGet() );
|
||||
@ -1132,6 +1121,7 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
|
||||
|
||||
FALLTHROUGH
|
||||
}
|
||||
|
||||
default:
|
||||
QgsDebugMsg( QStringLiteral( "feature %1: unsupported wkb type %2/%3 for rendering" )
|
||||
.arg( feature.id() )
|
||||
@ -1139,7 +1129,175 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
|
||||
.arg( geom.wkbType(), 0, 16 ) );
|
||||
}
|
||||
|
||||
stopFeatureRender( feature, context, layer );
|
||||
// step 2 - determine which layers to render
|
||||
std::vector< int > layers;
|
||||
if ( layer == -1 )
|
||||
{
|
||||
layers.reserve( mLayers.count() );
|
||||
for ( int i = 0; i < mLayers.count(); ++i )
|
||||
layers.emplace_back( i );
|
||||
}
|
||||
else
|
||||
{
|
||||
layers.emplace_back( layer );
|
||||
}
|
||||
|
||||
// step 3 - render these geometries using the desired symbol layers.
|
||||
|
||||
if ( needsExpressionContext )
|
||||
mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "symbol_layer_count" ), mLayers.count(), true ) );
|
||||
|
||||
for ( const int symbolLayerIndex : layers )
|
||||
{
|
||||
QgsSymbolLayer *symbolLayer = mLayers.value( symbolLayerIndex );
|
||||
if ( !symbolLayer || !symbolLayer->enabled() )
|
||||
continue;
|
||||
|
||||
if ( needsExpressionContext )
|
||||
mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "symbol_layer_index" ), symbolLayerIndex + 1, true ) );
|
||||
|
||||
symbolLayer->startFeatureRender( feature, context );
|
||||
switch ( QgsWkbTypes::flatType( segmentizedGeometry.constGet()->wkbType() ) )
|
||||
{
|
||||
case QgsWkbTypes::Point:
|
||||
{
|
||||
if ( pointsToRender.empty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
static_cast<QgsMarkerSymbol *>( this )->renderPoint( pointsToRender.at( 0 ), &feature, context, symbolLayerIndex, selected );
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsWkbTypes::LineString:
|
||||
{
|
||||
if ( linesToRender.empty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
static_cast<QgsLineSymbol *>( this )->renderPolyline( linesToRender.at( 0 ), &feature, context, symbolLayerIndex, selected );
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsWkbTypes::Polygon:
|
||||
case QgsWkbTypes::Triangle:
|
||||
{
|
||||
if ( polygonsToRender.empty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
static_cast<QgsFillSymbol *>( this )->renderPolygon( polygonsToRender.at( 0 ), ( !polygonRingsToRender.at( 0 ).isEmpty() ? &polygonRingsToRender.at( 0 ) : nullptr ), &feature, context, symbolLayerIndex, selected );
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsWkbTypes::MultiPoint:
|
||||
{
|
||||
if ( pointsToRender.empty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
const QgsMultiPoint &mp = static_cast< const QgsMultiPoint & >( *segmentizedGeometry.constGet() );
|
||||
for ( int i = 0; i < mp.numGeometries(); ++i )
|
||||
{
|
||||
if ( context.renderingStopped() )
|
||||
break;
|
||||
|
||||
mSymbolRenderContext->setGeometryPartNum( i + 1 );
|
||||
if ( needsExpressionContext )
|
||||
mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1, true ) );
|
||||
|
||||
static_cast<QgsMarkerSymbol *>( this )->renderPoint( pointsToRender.at( i ), &feature, context, symbolLayerIndex, selected );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsWkbTypes::MultiCurve:
|
||||
case QgsWkbTypes::MultiLineString:
|
||||
{
|
||||
if ( linesToRender.empty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
const QgsGeometryCollection &geomCollection = dynamic_cast<const QgsGeometryCollection &>( *segmentizedGeometry.constGet() );
|
||||
|
||||
const unsigned int num = geomCollection.numGeometries();
|
||||
for ( unsigned int i = 0; i < num; ++i )
|
||||
{
|
||||
if ( context.renderingStopped() )
|
||||
break;
|
||||
|
||||
mSymbolRenderContext->setGeometryPartNum( i + 1 );
|
||||
if ( needsExpressionContext )
|
||||
mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1, true ) );
|
||||
|
||||
context.setGeometry( geomCollection.geometryN( i ) );
|
||||
static_cast<QgsLineSymbol *>( this )->renderPolyline( linesToRender.at( 0 ), &feature, context, symbolLayerIndex, selected );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsWkbTypes::MultiSurface:
|
||||
case QgsWkbTypes::MultiPolygon:
|
||||
{
|
||||
if ( polygonsToRender.empty() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// 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<double, QList<unsigned int> >::const_reverse_iterator iter = mapAreaToPartNum.rbegin();
|
||||
int polyIndex = 0;
|
||||
for ( ; iter != mapAreaToPartNum.rend(); ++iter )
|
||||
{
|
||||
const QList<unsigned int> &listPartIndex = iter->second;
|
||||
for ( int idx = 0; idx < listPartIndex.size(); ++idx )
|
||||
{
|
||||
if ( context.renderingStopped() )
|
||||
break;
|
||||
|
||||
const unsigned i = listPartIndex[idx];
|
||||
mSymbolRenderContext->setGeometryPartNum( i + 1 );
|
||||
if ( needsExpressionContext )
|
||||
mSymbolRenderContext->expressionContextScope()->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, i + 1, true ) );
|
||||
|
||||
const QgsGeometryCollection &geomCollection = dynamic_cast<const QgsGeometryCollection &>( *segmentizedGeometry.constGet() );
|
||||
context.setGeometry( geomCollection.geometryN( i ) );
|
||||
|
||||
static_cast<QgsFillSymbol *>( this )->renderPolygon( polygonsToRender.at( polyIndex ), ( !polygonRingsToRender.at( polyIndex ).isEmpty() ? &polygonRingsToRender.at( polyIndex ) : nullptr ), &feature, context, symbolLayerIndex, selected );
|
||||
polyIndex++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsWkbTypes::GeometryCollection:
|
||||
{
|
||||
const QgsGeometryCollection &geomCollection = dynamic_cast<const QgsGeometryCollection &>( *segmentizedGeometry.constGet() );
|
||||
if ( geomCollection.numGeometries() == 0 )
|
||||
{
|
||||
// skip noise from empty geometry collections from simplification
|
||||
break;
|
||||
}
|
||||
|
||||
FALLTHROUGH
|
||||
}
|
||||
|
||||
default:
|
||||
QgsDebugMsg( QStringLiteral( "feature %1: unsupported wkb type %2/%3 for rendering" )
|
||||
.arg( feature.id() )
|
||||
.arg( QgsWkbTypes::displayString( geom.constGet()->wkbType() ) )
|
||||
.arg( geom.wkbType(), 0, 16 ) );
|
||||
}
|
||||
|
||||
symbolLayer->stopFeatureRender( feature, context );
|
||||
}
|
||||
|
||||
if ( context.hasRenderedFeatureHandlers() )
|
||||
{
|
||||
@ -2055,7 +2213,7 @@ QgsFillSymbol::QgsFillSymbol( const QgsSymbolLayerList &layers )
|
||||
mLayers.append( new QgsSimpleFillSymbolLayer() );
|
||||
}
|
||||
|
||||
void QgsFillSymbol::renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, const QgsFeature *f, QgsRenderContext &context, int layerIdx, bool selected )
|
||||
void QgsFillSymbol::renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, const QgsFeature *f, QgsRenderContext &context, int layerIdx, bool selected )
|
||||
{
|
||||
QgsSymbolRenderContext symbolContext( context, QgsUnitTypes::RenderUnknownUnit, mOpacity, selected, mRenderHints, f );
|
||||
symbolContext.setOriginalGeometryType( QgsWkbTypes::PolygonGeometry );
|
||||
@ -2091,7 +2249,7 @@ void QgsFillSymbol::renderPolygon( const QPolygonF &points, QList<QPolygonF> *ri
|
||||
}
|
||||
}
|
||||
|
||||
void QgsFillSymbol::renderPolygonUsingLayer( QgsSymbolLayer *layer, const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
void QgsFillSymbol::renderPolygonUsingLayer( QgsSymbolLayer *layer, const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
{
|
||||
if ( layer->dataDefinedProperties().hasActiveProperties() && !layer->dataDefinedProperties().valueAsBool( QgsSymbolLayer::PropertyLayerEnabled, context.renderContext().expressionContext(), true ) )
|
||||
return;
|
||||
@ -2102,7 +2260,7 @@ void QgsFillSymbol::renderPolygonUsingLayer( QgsSymbolLayer *layer, const QPolyg
|
||||
if ( effect && effect->enabled() )
|
||||
{
|
||||
QRectF bounds = polygonBounds( points, rings );
|
||||
QList<QPolygonF> *translatedRings = translateRings( rings, -bounds.left(), -bounds.top() );
|
||||
QVector<QPolygonF> *translatedRings = translateRings( rings, -bounds.left(), -bounds.top() );
|
||||
|
||||
QgsEffectPainter p( context.renderContext() );
|
||||
p->translate( bounds.topLeft() );
|
||||
@ -2130,13 +2288,12 @@ void QgsFillSymbol::renderPolygonUsingLayer( QgsSymbolLayer *layer, const QPolyg
|
||||
}
|
||||
}
|
||||
|
||||
QRectF QgsFillSymbol::polygonBounds( const QPolygonF &points, const QList<QPolygonF> *rings ) const
|
||||
QRectF QgsFillSymbol::polygonBounds( const QPolygonF &points, const QVector<QPolygonF> *rings ) const
|
||||
{
|
||||
QRectF bounds = points.boundingRect();
|
||||
if ( rings )
|
||||
{
|
||||
QList<QPolygonF>::const_iterator it = rings->constBegin();
|
||||
for ( ; it != rings->constEnd(); ++it )
|
||||
for ( auto it = rings->constBegin(); it != rings->constEnd(); ++it )
|
||||
{
|
||||
bounds = bounds.united( ( *it ).boundingRect() );
|
||||
}
|
||||
@ -2144,14 +2301,14 @@ QRectF QgsFillSymbol::polygonBounds( const QPolygonF &points, const QList<QPolyg
|
||||
return bounds;
|
||||
}
|
||||
|
||||
QList<QPolygonF> *QgsFillSymbol::translateRings( const QList<QPolygonF> *rings, double dx, double dy ) const
|
||||
QVector<QPolygonF> *QgsFillSymbol::translateRings( const QVector<QPolygonF> *rings, double dx, double dy ) const
|
||||
{
|
||||
if ( !rings )
|
||||
return nullptr;
|
||||
|
||||
QList<QPolygonF> *translatedRings = new QList<QPolygonF>;
|
||||
QList<QPolygonF>::const_iterator it = rings->constBegin();
|
||||
for ( ; it != rings->constEnd(); ++it )
|
||||
QVector<QPolygonF> *translatedRings = new QVector<QPolygonF>;
|
||||
translatedRings->reserve( rings->size() );
|
||||
for ( auto it = rings->constBegin(); it != rings->constEnd(); ++it )
|
||||
{
|
||||
translatedRings->append( ( *it ).translated( dx, dy ) );
|
||||
}
|
||||
|
@ -589,7 +589,7 @@ class CORE_EXPORT QgsSymbol
|
||||
* clockwise for exterior rings and counter-clockwise for interior rings.
|
||||
*
|
||||
*/
|
||||
static void _getPolygon( QPolygonF &pts, QList<QPolygonF> &holes, QgsRenderContext &context, const QgsPolygon &polygon, bool clipToExtent = true, bool correctRingOrientation = false );
|
||||
static void _getPolygon( QPolygonF &pts, QVector<QPolygonF> &holes, QgsRenderContext &context, const QgsPolygon &polygon, bool clipToExtent = true, bool correctRingOrientation = false );
|
||||
|
||||
/**
|
||||
* Retrieve a cloned list of all layers that make up this symbol.
|
||||
@ -1242,17 +1242,17 @@ class CORE_EXPORT QgsFillSymbol : public QgsSymbol
|
||||
* If \a selected is true then the symbol will be drawn using the "selected feature"
|
||||
* style and colors instead of the symbol's normal style.
|
||||
*/
|
||||
void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, const QgsFeature *f, QgsRenderContext &context, int layer = -1, bool selected = false );
|
||||
void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, const QgsFeature *f, QgsRenderContext &context, int layer = -1, bool selected = false );
|
||||
|
||||
QgsFillSymbol *clone() const override SIP_FACTORY;
|
||||
|
||||
private:
|
||||
|
||||
void renderPolygonUsingLayer( QgsSymbolLayer *layer, const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
void renderPolygonUsingLayer( QgsSymbolLayer *layer, const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
//! Calculates the bounds of a polygon including rings
|
||||
QRectF polygonBounds( const QPolygonF &points, const QList<QPolygonF> *rings ) const;
|
||||
QRectF polygonBounds( const QPolygonF &points, const QVector<QPolygonF> *rings ) const;
|
||||
//! Translates the rings in a polygon by a set distance
|
||||
QList<QPolygonF> *translateRings( const QList<QPolygonF> *rings, double dx, double dy ) const;
|
||||
QVector<QPolygonF> *translateRings( const QVector<QPolygonF> *rings, double dx, double dy ) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -657,7 +657,7 @@ void QgsLineSymbolLayer::drawPreviewIcon( QgsSymbolRenderContext &context, QSize
|
||||
stopRender( context );
|
||||
}
|
||||
|
||||
void QgsLineSymbolLayer::renderPolygonStroke( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
void QgsLineSymbolLayer::renderPolygonStroke( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
{
|
||||
switch ( mRingFilter )
|
||||
{
|
||||
@ -712,7 +712,7 @@ void QgsFillSymbolLayer::drawPreviewIcon( QgsSymbolRenderContext &context, QSize
|
||||
|
||||
for ( const QList< QPolygonF > &poly : polys )
|
||||
{
|
||||
QList< QPolygonF > rings;
|
||||
QVector< QPolygonF > rings;
|
||||
for ( int i = 1; i < poly.size(); ++i )
|
||||
rings << poly.at( i );
|
||||
renderPolygon( poly.value( 0 ), &rings, context );
|
||||
@ -723,7 +723,7 @@ void QgsFillSymbolLayer::drawPreviewIcon( QgsSymbolRenderContext &context, QSize
|
||||
stopRender( context );
|
||||
}
|
||||
|
||||
void QgsFillSymbolLayer::_renderPolygon( QPainter *p, const QPolygonF &points, const QList<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
void QgsFillSymbolLayer::_renderPolygon( QPainter *p, const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
|
||||
{
|
||||
if ( !p )
|
||||
{
|
||||
@ -757,8 +757,7 @@ void QgsFillSymbolLayer::_renderPolygon( QPainter *p, const QPolygonF &points, c
|
||||
|
||||
if ( rings )
|
||||
{
|
||||
QList<QPolygonF>::const_iterator it = rings->constBegin();
|
||||
for ( ; it != rings->constEnd(); ++it )
|
||||
for ( auto it = rings->constBegin(); it != rings->constEnd(); ++it )
|
||||
{
|
||||
QPolygonF ring = *it;
|
||||
path.addPolygon( ring );
|
||||
|
@ -929,7 +929,7 @@ class CORE_EXPORT QgsLineSymbolLayer : public QgsSymbolLayer
|
||||
*
|
||||
* \see renderPolyline()
|
||||
*/
|
||||
virtual void renderPolygonStroke( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
virtual void renderPolygonStroke( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
|
||||
/**
|
||||
* Sets the \a width of the line symbol layer.
|
||||
@ -1098,7 +1098,12 @@ class CORE_EXPORT QgsFillSymbolLayer : public QgsSymbolLayer
|
||||
//! QgsFillSymbolLayer cannot be copied
|
||||
QgsFillSymbolLayer &operator=( const QgsFillSymbolLayer &other ) = delete;
|
||||
|
||||
virtual void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) = 0;
|
||||
/**
|
||||
* Renders the fill symbol layer for the polygon whose outer ring is defined by \a points, using the given render \a context.
|
||||
*
|
||||
* The \a rings argument optionally specifies a list of polygon rings to render as holes.
|
||||
*/
|
||||
virtual void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context ) = 0;
|
||||
|
||||
void drawPreviewIcon( QgsSymbolRenderContext &context, QSize size ) override;
|
||||
|
||||
@ -1108,7 +1113,7 @@ class CORE_EXPORT QgsFillSymbolLayer : public QgsSymbolLayer
|
||||
protected:
|
||||
QgsFillSymbolLayer( bool locked = false );
|
||||
//! Default method to render polygon
|
||||
void _renderPolygon( QPainter *p, const QPolygonF &points, const QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
void _renderPolygon( QPainter *p, const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
|
||||
double mAngle = 0.0;
|
||||
|
||||
|
@ -4008,7 +4008,7 @@ QPointF QgsSymbolLayerUtils::polygonCentroid( const QPolygonF &points )
|
||||
return QPointF( cx, cy );
|
||||
}
|
||||
|
||||
QPointF QgsSymbolLayerUtils::polygonPointOnSurface( const QPolygonF &points, QList<QPolygonF> *rings )
|
||||
QPointF QgsSymbolLayerUtils::polygonPointOnSurface( const QPolygonF &points, const QVector<QPolygonF> *rings )
|
||||
{
|
||||
QPointF centroid = QgsSymbolLayerUtils::polygonCentroid( points );
|
||||
|
||||
@ -4022,8 +4022,7 @@ QPointF QgsSymbolLayerUtils::polygonPointOnSurface( const QPolygonF &points, QLi
|
||||
{
|
||||
if ( rings )
|
||||
{
|
||||
QList<QPolygonF>::const_iterator ringIt = rings->constBegin();
|
||||
for ( ; ringIt != rings->constEnd(); ++ringIt )
|
||||
for ( auto ringIt = rings->constBegin(); ringIt != rings->constEnd(); ++ringIt )
|
||||
{
|
||||
pointCount = ( *ringIt ).count();
|
||||
QgsPolylineXY polyline( pointCount );
|
||||
|
@ -643,7 +643,7 @@ class CORE_EXPORT QgsSymbolLayerUtils
|
||||
static QPointF polygonCentroid( const QPolygonF &points );
|
||||
|
||||
//! Calculate a point on the surface of a QPolygonF
|
||||
static QPointF polygonPointOnSurface( const QPolygonF &points, QList<QPolygonF> *rings = nullptr );
|
||||
static QPointF polygonPointOnSurface( const QPolygonF &points, const QVector<QPolygonF> *rings = nullptr );
|
||||
|
||||
//! Calculate whether a point is within of a QPolygonF
|
||||
static bool pointInPolygon( const QPolygonF &points, QPointF point );
|
||||
|
Loading…
x
Reference in New Issue
Block a user