Skip to content

Commit

Permalink
Change QgsVectorLayer::featureCount( QgsSymbol* symbol ) to instead
Browse files Browse the repository at this point in the history
use a legend key string

Avoids crashes due to symbol pointer lifetime issues
  • Loading branch information
nyalldawson committed Dec 2, 2016
1 parent 42d3f4b commit 6d0203d
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 18 deletions.
1 change: 1 addition & 0 deletions doc/api_break.dox
Original file line number Diff line number Diff line change
Expand Up @@ -1572,6 +1572,7 @@ displayExpression instead. For the map tip use mapTipTemplate() instead.
- getStyleFromDatabase(): msgError argument is correctly declared as output argument
- loadNamedStyle(): theResultFlag argument is correctly declared as output argument
- The duplicate selectionChanged() signal was removed. Use selectionChanged( const QgsFeatureIds&, const QgsFeatureIds&, const bool ) instead.
- featureCount() now requires a legend key string instead of a QgsSymbol pointer argument.

QgsVectorLayerEditBuffer {#qgis_api_break_3_0_QgsVectorLayerEditBuffer}
------------------------
Expand Down
7 changes: 3 additions & 4 deletions python/core/qgsvectorlayer.sip
Original file line number Diff line number Diff line change
Expand Up @@ -732,12 +732,11 @@ class QgsVectorLayer : QgsMapLayer, QgsExpressionContextGenerator
bool readSld( const QDomNode& node, QString& errorMessage );

/**
* Number of features rendered with specified symbol. Features must be first
* Number of features rendered with specified legend key. Features must be first
* calculated by countSymbolFeatures()
* @param symbol the symbol
* @return number of features rendered by symbol or -1 if failed or counts are not available
*/
long featureCount( QgsSymbol* symbol ) const;
long featureCount( const QString& legendKey ) const;

/**
* Update the data source of the layer. The layer's renderer and legend will be preserved only
Expand All @@ -752,7 +751,7 @@ class QgsVectorLayer : QgsMapLayer, QgsExpressionContextGenerator
void setDataSource( const QString& dataSource, const QString& baseName, const QString& provider, bool loadDefaultStyleFlag = false );

/**
* Count features for symbols. Feature counts may be get by featureCount( QgsSymbol*).
* Count features for symbols. Feature counts may be get by featureCount().
* @param showProgress show progress dialog
* @return true if calculated, false if failed or was canceled by user
*/
Expand Down
4 changes: 2 additions & 2 deletions src/core/layertree/qgslayertreemodellegendnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,8 @@ void QgsSymbolLegendNode::updateLabel()
else
{
mLabel = mUserLabel.isEmpty() ? mItem.label() : mUserLabel;
if ( showFeatureCount && vl && mItem.legacyRuleKey() )
mLabel += QStringLiteral( " [%1]" ).arg( vl->featureCount( mItem.legacyRuleKey() ) );
if ( showFeatureCount && vl )
mLabel += QStringLiteral( " [%1]" ).arg( vl->featureCount( mItem.ruleKey() ) );
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/core/qgsvectorlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -622,12 +622,12 @@ bool QgsVectorLayer::diagramsEnabled() const
return false;
}

long QgsVectorLayer::featureCount( QgsSymbol* symbol ) const
long QgsVectorLayer::featureCount( const QString& legendKey ) const
{
if ( !mSymbolFeatureCounted )
return -1;

return mSymbolFeatureCountMap.value( symbol );
return mSymbolFeatureCountMap.value( legendKey );
}

/** \ingroup core
Expand Down Expand Up @@ -697,7 +697,7 @@ bool QgsVectorLayer::countSymbolFeatures( bool showProgress )

for ( ; symbolIt != symbolList.constEnd(); ++symbolIt )
{
mSymbolFeatureCountMap.insert( symbolIt->second, 0 );
mSymbolFeatureCountMap.insert( symbolIt->first, 0 );
}

long nFeatures = featureCount();
Expand Down Expand Up @@ -749,10 +749,10 @@ bool QgsVectorLayer::countSymbolFeatures( bool showProgress )
while ( fit.nextFeature( f ) )
{
renderContext.expressionContext().setFeature( f );
QgsSymbolList featureSymbolList = mRenderer->originalSymbolsForFeature( f, renderContext );
for ( QgsSymbolList::iterator symbolIt = featureSymbolList.begin(); symbolIt != featureSymbolList.end(); ++symbolIt )
QSet<QString> featureKeyList = mRenderer->legendKeysForFeature( f, renderContext );
Q_FOREACH ( const QString& key, featureKeyList )
{
mSymbolFeatureCountMap[*symbolIt] += 1;
mSymbolFeatureCountMap[key] += 1;
}
++featuresCounted;

Expand Down
11 changes: 5 additions & 6 deletions src/core/qgsvectorlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -837,12 +837,11 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
bool readSld( const QDomNode& node, QString& errorMessage ) override;

/**
* Number of features rendered with specified symbol. Features must be first
* Number of features rendered with specified legend key. Features must be first
* calculated by countSymbolFeatures()
* @param symbol the symbol
* @return number of features rendered by symbol or -1 if failed or counts are not available
*/
long featureCount( QgsSymbol* symbol ) const;
long featureCount( const QString& legendKey ) const;

/**
* Update the data source of the layer. The layer's renderer and legend will be preserved only
Expand All @@ -857,7 +856,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
void setDataSource( const QString& dataSource, const QString& baseName, const QString& provider, bool loadDefaultStyleFlag = false );

/**
* Count features for symbols. Feature counts may be get by featureCount( QgsSymbol*).
* Count features for symbols. Feature counts may be get by featureCount().
* @param showProgress show progress dialog
* @return true if calculated, false if failed or was canceled by user
*/
Expand Down Expand Up @@ -2080,8 +2079,8 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
// Features in renderer classes counted
bool mSymbolFeatureCounted;

// Feature counts for each renderer symbol
QMap<QgsSymbol*, long> mSymbolFeatureCountMap;
// Feature counts for each renderer legend key
QHash<QString, long> mSymbolFeatureCountMap;

//! True while an undo command is active
bool mEditCommandActive;
Expand Down

0 comments on commit 6d0203d

Please sign in to comment.