mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Fix crash in displacement/distance renderers
Individual symbol instances were being rendered multiple times concurrently
This commit is contained in:
parent
b95d432a8c
commit
99bf32bafb
@ -29,34 +29,36 @@ class QgsPointDistanceRenderer: QgsFeatureRenderer
|
||||
struct GroupedFeature
|
||||
{
|
||||
|
||||
GroupedFeature( const QgsFeature &feature, QgsMarkerSymbol *symbol, bool isSelected, const QString &label = QString() );
|
||||
GroupedFeature( const QgsFeature &feature, QgsMarkerSymbol *symbol /Transfer/, bool isSelected, const QString &label = QString() );
|
||||
%Docstring
|
||||
Constructor for GroupedFeature.
|
||||
\param feature feature
|
||||
\param symbol base symbol for rendering feature
|
||||
\param symbol base symbol for rendering feature (owned by GroupedFeature)
|
||||
\param isSelected set to true if feature is selected and should be rendered in a selected state
|
||||
\param label optional label text, or empty string for no label
|
||||
%End
|
||||
|
||||
QgsFeature feature;
|
||||
QgsFeature feature;
|
||||
%Docstring
|
||||
Feature
|
||||
%End
|
||||
|
||||
QgsMarkerSymbol *symbol;
|
||||
QgsMarkerSymbol *symbol() const;
|
||||
%Docstring
|
||||
Base symbol for rendering feature
|
||||
:rtype: QgsMarkerSymbol
|
||||
%End
|
||||
|
||||
bool isSelected;
|
||||
bool isSelected;
|
||||
%Docstring
|
||||
True if feature is selected and should be rendered in a selected state
|
||||
%End
|
||||
|
||||
QString label;
|
||||
QString label;
|
||||
%Docstring
|
||||
Optional label text
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
typedef QList< QgsPointDistanceRenderer::GroupedFeature > ClusteredGroup;
|
||||
|
@ -72,8 +72,10 @@ void QgsPointClusterRenderer::drawGroup( QPointF centerPoint, QgsRenderContext &
|
||||
else
|
||||
{
|
||||
//single isolated symbol, draw it untouched
|
||||
QgsMarkerSymbol *symbol = group.at( 0 ).symbol;
|
||||
QgsMarkerSymbol *symbol = group.at( 0 ).symbol();
|
||||
symbol->startRender( context );
|
||||
symbol->renderPoint( centerPoint, &( group.at( 0 ).feature ), context, -1, group.at( 0 ).isSelected );
|
||||
symbol->stopRender( context );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ void QgsPointDisplacementRenderer::drawGroup( QPointF centerPoint, QgsRenderCont
|
||||
|
||||
Q_FOREACH ( const GroupedFeature &feature, group )
|
||||
{
|
||||
if ( QgsMarkerSymbol *symbol = feature.symbol )
|
||||
if ( QgsMarkerSymbol *symbol = feature.symbol() )
|
||||
{
|
||||
diagonal = qMax( diagonal, context.convertToPainterUnits( M_SQRT2 * symbol->size(),
|
||||
symbol->sizeUnit(), symbol->sizeMapUnitScale() ) );
|
||||
@ -327,9 +327,9 @@ void QgsPointDisplacementRenderer::drawSymbols( const ClusteredGroup &group, Qgs
|
||||
++symbolPosIt, ++groupIt )
|
||||
{
|
||||
context.expressionContext().setFeature( groupIt->feature );
|
||||
groupIt->symbol->startRender( context );
|
||||
groupIt->symbol->renderPoint( *symbolPosIt, &( groupIt->feature ), context, -1, groupIt->isSelected );
|
||||
groupIt->symbol->stopRender( context );
|
||||
groupIt->symbol()->startRender( context );
|
||||
groupIt->symbol()->renderPoint( *symbolPosIt, &( groupIt->feature ), context, -1, groupIt->isSelected );
|
||||
groupIt->symbol()->stopRender( context );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ bool QgsPointDistanceRenderer::renderFeature( QgsFeature &feature, QgsRenderCont
|
||||
mSpatialIndex->insertFeature( transformedFeature );
|
||||
// create new group
|
||||
ClusteredGroup newGroup;
|
||||
newGroup << GroupedFeature( transformedFeature, symbol, selected, label );
|
||||
newGroup << GroupedFeature( transformedFeature, symbol->clone(), selected, label );
|
||||
mClusteredGroups.push_back( newGroup );
|
||||
// add to group index
|
||||
mGroupIndex.insert( transformedFeature.id(), mClusteredGroups.count() - 1 );
|
||||
@ -127,7 +127,7 @@ bool QgsPointDistanceRenderer::renderFeature( QgsFeature &feature, QgsRenderCont
|
||||
( oldCenter.y() * group.size() + point.y() ) / ( group.size() + 1.0 ) );
|
||||
|
||||
// add to a group
|
||||
group << GroupedFeature( transformedFeature, symbol, selected, label );
|
||||
group << GroupedFeature( transformedFeature, symbol->clone(), selected, label );
|
||||
// add to group index
|
||||
mGroupIndex.insert( transformedFeature.id(), groupIdx );
|
||||
}
|
||||
@ -425,16 +425,16 @@ QgsExpressionContextScope *QgsPointDistanceRenderer::createGroupScope( const Clu
|
||||
ClusteredGroup::const_iterator groupIt = group.constBegin();
|
||||
for ( ; groupIt != group.constEnd(); ++groupIt )
|
||||
{
|
||||
if ( !groupIt->symbol )
|
||||
if ( !groupIt->symbol() )
|
||||
continue;
|
||||
|
||||
if ( !groupColor.isValid() )
|
||||
{
|
||||
groupColor = groupIt->symbol->color();
|
||||
groupColor = groupIt->symbol()->color();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( groupColor != groupIt->symbol->color() )
|
||||
if ( groupColor != groupIt->symbol()->color() )
|
||||
{
|
||||
groupColor = QColor();
|
||||
break;
|
||||
|
@ -42,30 +42,33 @@ class CORE_EXPORT QgsPointDistanceRenderer: public QgsFeatureRenderer
|
||||
struct GroupedFeature
|
||||
{
|
||||
|
||||
/** Constructor for GroupedFeature.
|
||||
* \param feature feature
|
||||
* \param symbol base symbol for rendering feature
|
||||
* \param isSelected set to true if feature is selected and should be rendered in a selected state
|
||||
* \param label optional label text, or empty string for no label
|
||||
*/
|
||||
GroupedFeature( const QgsFeature &feature, QgsMarkerSymbol *symbol, bool isSelected, const QString &label = QString() )
|
||||
: feature( feature )
|
||||
, symbol( symbol )
|
||||
, isSelected( isSelected )
|
||||
, label( label )
|
||||
{}
|
||||
/** Constructor for GroupedFeature.
|
||||
* \param feature feature
|
||||
* \param symbol base symbol for rendering feature (owned by GroupedFeature)
|
||||
* \param isSelected set to true if feature is selected and should be rendered in a selected state
|
||||
* \param label optional label text, or empty string for no label
|
||||
*/
|
||||
GroupedFeature( const QgsFeature &feature, QgsMarkerSymbol *symbol SIP_TRANSFER, bool isSelected, const QString &label = QString() )
|
||||
: feature( feature )
|
||||
, isSelected( isSelected )
|
||||
, label( label )
|
||||
, mSymbol( symbol )
|
||||
{}
|
||||
|
||||
//! Feature
|
||||
QgsFeature feature;
|
||||
//! Feature
|
||||
QgsFeature feature;
|
||||
|
||||
//! Base symbol for rendering feature
|
||||
QgsMarkerSymbol *symbol = nullptr;
|
||||
//! Base symbol for rendering feature
|
||||
QgsMarkerSymbol *symbol() const { return mSymbol.get(); }
|
||||
|
||||
//! True if feature is selected and should be rendered in a selected state
|
||||
bool isSelected;
|
||||
//! True if feature is selected and should be rendered in a selected state
|
||||
bool isSelected;
|
||||
|
||||
//! Optional label text
|
||||
QString label;
|
||||
//! Optional label text
|
||||
QString label;
|
||||
|
||||
private:
|
||||
std::shared_ptr< QgsMarkerSymbol > mSymbol;
|
||||
};
|
||||
|
||||
//! A group of clustered points (ie features within the distance tolerance).
|
||||
|
Loading…
x
Reference in New Issue
Block a user