Skip to content

Commit 3a317a0

Browse files
committed
Fix #9658 (crash with diagrams)
1 parent 3b1e192 commit 3a317a0

File tree

10 files changed

+48
-23
lines changed

10 files changed

+48
-23
lines changed

python/core/diagram/qgsdiagram.sip

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ class QgsDiagram
2424
virtual QSizeF diagramSize( const QgsFeature& feature, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is ) = 0;
2525

2626
protected:
27+
QgsDiagram();
28+
QgsDiagram( const QgsDiagram& other );
29+
2730
/** Changes the pen width to match the current settings and rendering context
2831
* @param pen The pen to modify
2932
* @param s The settings that specify the pen width

python/core/qgsmaprenderer.sip

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class QgsLabelingEngineInterface
5555
//! @note: this method was added in version 1.9
5656
virtual QgsPalLayerSettings& layer( const QString& layerName ) = 0;
5757
//! adds a diagram layer to the labeling engine
58-
virtual int addDiagramLayer( QgsVectorLayer* layer, QgsDiagramLayerSettings* s );
58+
virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings* s );
5959
//! called for every feature
6060
virtual void registerFeature( const QString& layerID, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext() ) = 0;
6161
//! called for every diagram feature

src/core/diagram/qgsdiagram.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,19 @@
2020
#include <QPainter>
2121

2222

23+
24+
QgsDiagram::QgsDiagram()
25+
{
26+
27+
}
28+
29+
QgsDiagram::QgsDiagram( const QgsDiagram& other )
30+
{
31+
Q_UNUSED( other );
32+
// do not copy the cached expression map - the expressions need to be created and prepared with getExpression(...) call
33+
}
34+
35+
2336
void QgsDiagram::clearCache()
2437
{
2538
QMapIterator<QString, QgsExpression*> i( mExpressions );

src/core/diagram/qgsdiagram.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ class CORE_EXPORT QgsDiagram
5454
virtual QSizeF diagramSize( const QgsFeature& feature, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is ) = 0;
5555

5656
protected:
57+
QgsDiagram();
58+
QgsDiagram( const QgsDiagram& other );
59+
5760
/** Changes the pen width to match the current settings and rendering context
5861
* @param pen The pen to modify
5962
* @param s The settings that specify the pen width

src/core/qgsdiagramrendererv2.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ class CORE_EXPORT QgsDiagramLayerSettings
8888
const QgsCoordinateTransform* ct;
8989
const QgsMapToPixel* xform;
9090
QList<QgsPalGeometry*> geometries;
91+
QgsFields fields;
9192

9293
int xPosColumn; //attribute index for x coordinate (or -1 if position not data defined)
9394
int yPosColumn;//attribute index for y coordinate (or -1 if position not data defined)

src/core/qgsmaprenderer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class CORE_EXPORT QgsLabelingEngineInterface
9292
//! @note: this method was added in version 1.9
9393
virtual QgsPalLayerSettings& layer( const QString& layerName ) = 0;
9494
//! adds a diagram layer to the labeling engine
95-
virtual int addDiagramLayer( QgsVectorLayer* layer, QgsDiagramLayerSettings* s )
95+
virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings* s )
9696
{ Q_UNUSED( layer ); Q_UNUSED( s ); return 0; }
9797
//! called for every feature
9898
virtual void registerFeature( const QString& layerID, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext() ) = 0;

src/core/qgspalgeometry.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,12 @@ class QgsPalGeometry : public PalGeometry
118118

119119
QFontMetricsF* getLabelFontMetrics() { return mFontMetrics; }
120120

121-
void setDiagramAttributes( const QgsAttributes& attrs, const QgsFields* fields ) { mDiagramAttributes = attrs; mDiagramFields = fields; }
121+
void setDiagramAttributes( const QgsAttributes& attrs ) { mDiagramAttributes = attrs; }
122122
const QgsAttributes& diagramAttributes() { return mDiagramAttributes; }
123123

124124
void feature( QgsFeature& feature )
125125
{
126126
feature.setFeatureId( mId );
127-
feature.setFields( mDiagramFields, false );
128127
feature.setAttributes( mDiagramAttributes );
129128
feature.setValid( true );
130129
}
@@ -147,7 +146,6 @@ class QgsPalGeometry : public PalGeometry
147146

148147
/**Stores attribute values for diagram rendering*/
149148
QgsAttributes mDiagramAttributes;
150-
const QgsFields* mDiagramFields;
151149
};
152150

153151
#endif //QGSPALGEOMETRY_H

src/core/qgspallabeling.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3342,20 +3342,25 @@ int QgsPalLabeling::prepareLayer( QgsVectorLayer* layer, QStringList& attrNames,
33423342
return 1; // init successful
33433343
}
33443344

3345-
int QgsPalLabeling::addDiagramLayer( QgsVectorLayer* layer, QgsDiagramLayerSettings *s )
3345+
int QgsPalLabeling::addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings *s )
33463346
{
33473347
Layer* l = mPal->addLayer( layer->id().append( "d" ).toUtf8().data(), -1, -1, pal::Arrangement( s->placement ), METER, s->priority, s->obstacle, true, true );
33483348
l->setArrangementFlags( s->placementFlags );
33493349

3350-
s->palLayer = l;
3351-
s->ct = 0;
3350+
mActiveDiagramLayers.insert( layer->id(), *s );
3351+
// initialize the local copy
3352+
QgsDiagramLayerSettings& s2 = mActiveDiagramLayers[layer->id()];
3353+
3354+
s2.palLayer = l;
3355+
s2.ct = 0;
33523356
if ( mMapSettings->hasCrsTransformEnabled() )
3353-
s->ct = new QgsCoordinateTransform( layer->crs(), mMapSettings->destinationCrs() );
3357+
s2.ct = new QgsCoordinateTransform( layer->crs(), mMapSettings->destinationCrs() );
33543358

3355-
s->xform = &mMapSettings->mapToPixel();
3356-
mActiveDiagramLayers.insert( layer->id(), *s );
3359+
s2.xform = &mMapSettings->mapToPixel();
3360+
3361+
s2.fields = layer->pendingFields();
33573362

3358-
mActiveDiagramLayers[ layer->id()].renderer = layer->diagramRenderer()->clone();
3363+
s2.renderer = layer->diagramRenderer()->clone();
33593364

33603365
return 1;
33613366
}
@@ -3409,7 +3414,7 @@ void QgsPalLabeling::registerDiagramFeature( const QString& layerID, QgsFeature&
34093414
}
34103415

34113416
//append the diagram attributes to lbl
3412-
lbl->setDiagramAttributes( feat.attributes(), feat.fields() );
3417+
lbl->setDiagramAttributes( feat.attributes() );
34133418
}
34143419

34153420
// feature to the layer
@@ -3934,6 +3939,7 @@ void QgsPalLabeling::drawLabeling( QgsRenderContext& context )
39343939
{
39353940
if ( QString( dit.key() + "d" ) == layerName )
39363941
{
3942+
feature.setFields( &dit.value().fields );
39373943
palGeometry->feature( feature );
39383944
QgsPoint outPt = xform.transform(( *it )->getX(), ( *it )->getY() );
39393945
dit.value().renderer->renderDiagram( feature, context, QPointF( outPt.x(), outPt.y() ) );

src/core/qgspallabeling.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
744744
//! hook called when drawing layer before issuing select()
745745
virtual int prepareLayer( QgsVectorLayer* layer, QStringList &attrNames, QgsRenderContext& ctx );
746746
//! adds a diagram layer to the labeling engine
747-
virtual int addDiagramLayer( QgsVectorLayer* layer, QgsDiagramLayerSettings *s );
747+
virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings *s );
748748
//! hook called when drawing for every feature in a layer
749749
virtual void registerFeature( const QString& layerID, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext() );
750750
virtual void registerDiagramFeature( const QString& layerID, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext() );

src/core/qgsvectorlayerrenderer.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -445,16 +445,17 @@ void QgsVectorLayerRenderer::prepareDiagrams( QgsVectorLayer* layer, QStringList
445445

446446
mDiagrams = true;
447447

448-
QgsDiagramLayerSettings diagSettings = *layer->diagramLayerSettings();
448+
const QgsDiagramRendererV2* diagRenderer = layer->diagramRenderer();
449+
const QgsDiagramLayerSettings* diagSettings = layer->diagramLayerSettings();
449450

450-
mContext.labelingEngine()->addDiagramLayer( layer, &diagSettings );
451+
mContext.labelingEngine()->addDiagramLayer( layer, diagSettings ); // will make internal copy of diagSettings + initialize it
451452

452453
//add attributes needed by the diagram renderer
453-
QList<QString> att = layer->diagramRenderer()->diagramAttributes();
454+
QList<QString> att = diagRenderer->diagramAttributes();
454455
QList<QString>::const_iterator attIt = att.constBegin();
455456
for ( ; attIt != att.constEnd(); ++attIt )
456457
{
457-
QgsExpression* expression = layer->diagramRenderer()->diagram()->getExpression( *attIt, &mFields );
458+
QgsExpression* expression = diagRenderer->diagram()->getExpression( *attIt, &mFields );
458459
QStringList columns = expression->referencedColumns();
459460
QStringList::const_iterator columnsIterator = columns.constBegin();
460461
for ( ; columnsIterator != columns.constEnd(); ++columnsIterator )
@@ -469,7 +470,7 @@ void QgsVectorLayerRenderer::prepareDiagrams( QgsVectorLayer* layer, QStringList
469470
{
470471
if ( linearlyInterpolatedDiagramRenderer->classificationAttributeIsExpression() )
471472
{
472-
QgsExpression* expression = layer->diagramRenderer()->diagram()->getExpression( linearlyInterpolatedDiagramRenderer->classificationAttributeExpression(), &mFields );
473+
QgsExpression* expression = diagRenderer->diagram()->getExpression( linearlyInterpolatedDiagramRenderer->classificationAttributeExpression(), &mFields );
473474
QStringList columns = expression->referencedColumns();
474475
QStringList::const_iterator columnsIterator = columns.constBegin();
475476
for ( ; columnsIterator != columns.constEnd(); ++columnsIterator )
@@ -487,8 +488,8 @@ void QgsVectorLayerRenderer::prepareDiagrams( QgsVectorLayer* layer, QStringList
487488
}
488489

489490
//and the ones needed for data defined diagram positions
490-
if ( diagSettings.xPosColumn != -1 )
491-
attributeNames << mFields.at( diagSettings.xPosColumn ).name();
492-
if ( diagSettings.yPosColumn != -1 )
493-
attributeNames << mFields.at( diagSettings.yPosColumn ).name();
491+
if ( diagSettings->xPosColumn != -1 )
492+
attributeNames << mFields.at( diagSettings->xPosColumn ).name();
493+
if ( diagSettings->yPosColumn != -1 )
494+
attributeNames << mFields.at( diagSettings->yPosColumn ).name();
494495
}

0 commit comments

Comments
 (0)