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