Skip to content

Commit 99bf32b

Browse files
committedJul 23, 2017
Fix crash in displacement/distance renderers
Individual symbol instances were being rendered multiple times concurrently
1 parent b95d432 commit 99bf32b

File tree

5 files changed

+47
-40
lines changed

5 files changed

+47
-40
lines changed
 

‎python/core/symbology-ng/qgspointdistancerenderer.sip

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,34 +29,36 @@ class QgsPointDistanceRenderer: QgsFeatureRenderer
2929
struct GroupedFeature
3030
{
3131

32-
GroupedFeature( const QgsFeature &feature, QgsMarkerSymbol *symbol, bool isSelected, const QString &label = QString() );
32+
GroupedFeature( const QgsFeature &feature, QgsMarkerSymbol *symbol /Transfer/, bool isSelected, const QString &label = QString() );
3333
%Docstring
3434
Constructor for GroupedFeature.
3535
\param feature feature
36-
\param symbol base symbol for rendering feature
36+
\param symbol base symbol for rendering feature (owned by GroupedFeature)
3737
\param isSelected set to true if feature is selected and should be rendered in a selected state
3838
\param label optional label text, or empty string for no label
3939
%End
4040

41-
QgsFeature feature;
41+
QgsFeature feature;
4242
%Docstring
4343
Feature
4444
%End
4545

46-
QgsMarkerSymbol *symbol;
46+
QgsMarkerSymbol *symbol() const;
4747
%Docstring
4848
Base symbol for rendering feature
49+
:rtype: QgsMarkerSymbol
4950
%End
5051

51-
bool isSelected;
52+
bool isSelected;
5253
%Docstring
5354
True if feature is selected and should be rendered in a selected state
5455
%End
5556

56-
QString label;
57+
QString label;
5758
%Docstring
5859
Optional label text
5960
%End
61+
6062
};
6163

6264
typedef QList< QgsPointDistanceRenderer::GroupedFeature > ClusteredGroup;

‎src/core/symbology-ng/qgspointclusterrenderer.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,10 @@ void QgsPointClusterRenderer::drawGroup( QPointF centerPoint, QgsRenderContext &
7272
else
7373
{
7474
//single isolated symbol, draw it untouched
75-
QgsMarkerSymbol *symbol = group.at( 0 ).symbol;
75+
QgsMarkerSymbol *symbol = group.at( 0 ).symbol();
76+
symbol->startRender( context );
7677
symbol->renderPoint( centerPoint, &( group.at( 0 ).feature ), context, -1, group.at( 0 ).isSelected );
78+
symbol->stopRender( context );
7779
}
7880
}
7981

‎src/core/symbology-ng/qgspointdisplacementrenderer.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ void QgsPointDisplacementRenderer::drawGroup( QPointF centerPoint, QgsRenderCont
7070

7171
Q_FOREACH ( const GroupedFeature &feature, group )
7272
{
73-
if ( QgsMarkerSymbol *symbol = feature.symbol )
73+
if ( QgsMarkerSymbol *symbol = feature.symbol() )
7474
{
7575
diagonal = qMax( diagonal, context.convertToPainterUnits( M_SQRT2 * symbol->size(),
7676
symbol->sizeUnit(), symbol->sizeMapUnitScale() ) );
@@ -327,9 +327,9 @@ void QgsPointDisplacementRenderer::drawSymbols( const ClusteredGroup &group, Qgs
327327
++symbolPosIt, ++groupIt )
328328
{
329329
context.expressionContext().setFeature( groupIt->feature );
330-
groupIt->symbol->startRender( context );
331-
groupIt->symbol->renderPoint( *symbolPosIt, &( groupIt->feature ), context, -1, groupIt->isSelected );
332-
groupIt->symbol->stopRender( context );
330+
groupIt->symbol()->startRender( context );
331+
groupIt->symbol()->renderPoint( *symbolPosIt, &( groupIt->feature ), context, -1, groupIt->isSelected );
332+
groupIt->symbol()->stopRender( context );
333333
}
334334
}
335335

‎src/core/symbology-ng/qgspointdistancerenderer.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ bool QgsPointDistanceRenderer::renderFeature( QgsFeature &feature, QgsRenderCont
9696
mSpatialIndex->insertFeature( transformedFeature );
9797
// create new group
9898
ClusteredGroup newGroup;
99-
newGroup << GroupedFeature( transformedFeature, symbol, selected, label );
99+
newGroup << GroupedFeature( transformedFeature, symbol->clone(), selected, label );
100100
mClusteredGroups.push_back( newGroup );
101101
// add to group index
102102
mGroupIndex.insert( transformedFeature.id(), mClusteredGroups.count() - 1 );
@@ -127,7 +127,7 @@ bool QgsPointDistanceRenderer::renderFeature( QgsFeature &feature, QgsRenderCont
127127
( oldCenter.y() * group.size() + point.y() ) / ( group.size() + 1.0 ) );
128128

129129
// add to a group
130-
group << GroupedFeature( transformedFeature, symbol, selected, label );
130+
group << GroupedFeature( transformedFeature, symbol->clone(), selected, label );
131131
// add to group index
132132
mGroupIndex.insert( transformedFeature.id(), groupIdx );
133133
}
@@ -425,16 +425,16 @@ QgsExpressionContextScope *QgsPointDistanceRenderer::createGroupScope( const Clu
425425
ClusteredGroup::const_iterator groupIt = group.constBegin();
426426
for ( ; groupIt != group.constEnd(); ++groupIt )
427427
{
428-
if ( !groupIt->symbol )
428+
if ( !groupIt->symbol() )
429429
continue;
430430

431431
if ( !groupColor.isValid() )
432432
{
433-
groupColor = groupIt->symbol->color();
433+
groupColor = groupIt->symbol()->color();
434434
}
435435
else
436436
{
437-
if ( groupColor != groupIt->symbol->color() )
437+
if ( groupColor != groupIt->symbol()->color() )
438438
{
439439
groupColor = QColor();
440440
break;

‎src/core/symbology-ng/qgspointdistancerenderer.h

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,33 @@ class CORE_EXPORT QgsPointDistanceRenderer: public QgsFeatureRenderer
4242
struct GroupedFeature
4343
{
4444

45-
/** Constructor for GroupedFeature.
46-
* \param feature feature
47-
* \param symbol base symbol for rendering feature
48-
* \param isSelected set to true if feature is selected and should be rendered in a selected state
49-
* \param label optional label text, or empty string for no label
50-
*/
51-
GroupedFeature( const QgsFeature &feature, QgsMarkerSymbol *symbol, bool isSelected, const QString &label = QString() )
52-
: feature( feature )
53-
, symbol( symbol )
54-
, isSelected( isSelected )
55-
, label( label )
56-
{}
57-
58-
//! Feature
59-
QgsFeature feature;
60-
61-
//! Base symbol for rendering feature
62-
QgsMarkerSymbol *symbol = nullptr;
63-
64-
//! True if feature is selected and should be rendered in a selected state
65-
bool isSelected;
66-
67-
//! Optional label text
68-
QString label;
45+
/** Constructor for GroupedFeature.
46+
* \param feature feature
47+
* \param symbol base symbol for rendering feature (owned by GroupedFeature)
48+
* \param isSelected set to true if feature is selected and should be rendered in a selected state
49+
* \param label optional label text, or empty string for no label
50+
*/
51+
GroupedFeature( const QgsFeature &feature, QgsMarkerSymbol *symbol SIP_TRANSFER, bool isSelected, const QString &label = QString() )
52+
: feature( feature )
53+
, isSelected( isSelected )
54+
, label( label )
55+
, mSymbol( symbol )
56+
{}
57+
58+
//! Feature
59+
QgsFeature feature;
60+
61+
//! Base symbol for rendering feature
62+
QgsMarkerSymbol *symbol() const { return mSymbol.get(); }
63+
64+
//! True if feature is selected and should be rendered in a selected state
65+
bool isSelected;
66+
67+
//! Optional label text
68+
QString label;
69+
70+
private:
71+
std::shared_ptr< QgsMarkerSymbol > mSymbol;
6972
};
7073

7174
//! A group of clustered points (ie features within the distance tolerance).

0 commit comments

Comments
 (0)
Please sign in to comment.