Merge pull request #9103 from m-kuhn/constFeatureInLabeling

Const correctnes for QgsFeature in labeling
This commit is contained in:
Matthias Kuhn 2019-02-06 08:35:11 +01:00 committed by GitHub
commit 7f0ab8b9ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 36 additions and 32 deletions

View File

@ -386,9 +386,13 @@ Returns the QgsExpression for this label settings. May be None if isExpression i
double zIndex; double zIndex;
void calculateLabelSize( const QFontMetricsF *fm, QString text, double &labelX, double &labelY, QgsFeature *f = 0, QgsRenderContext *context = 0 ); void calculateLabelSize( const QFontMetricsF *fm, const QString &text, double &labelX, double &labelY, const QgsFeature *f = 0, QgsRenderContext *context = 0 );
%Docstring
Calculates the space required to render the provided ``text`` in map units.
Results will be written to ``labelX`` and ``labelY``.
%End
void registerFeature( QgsFeature &f, QgsRenderContext &context ); void registerFeature( const QgsFeature &f, QgsRenderContext &context );
%Docstring %Docstring
Register a feature for labeling. Register a feature for labeling.
@ -457,7 +461,7 @@ Sets the label text formatting settings, e.g., font settings, buffer settings, e
.. versionadded:: 3.0 .. versionadded:: 3.0
%End %End
QgsFeature *mCurFeat; const QgsFeature *mCurFeat;
QgsFields mCurFields; QgsFields mCurFields;
int fieldIndex; int fieldIndex;
const QgsMapToPixel *xform; const QgsMapToPixel *xform;
@ -469,7 +473,6 @@ Sets the label text formatting settings, e.g., font settings, buffer settings, e
int mFeaturesToLabel; int mFeaturesToLabel;
int mFeatsSendingToPal; int mFeatsSendingToPal;
int mFeatsRegPal; int mFeatsRegPal;
}; };
class QgsLabelCandidate class QgsLabelCandidate

View File

@ -34,7 +34,7 @@ void QgsDxfLabelProvider::drawLabel( QgsRenderContext &context, pal::LabelPositi
mDxfExport->drawLabel( layerId(), context, label, mSettings ); mDxfExport->drawLabel( layerId(), context, label, mSettings );
} }
void QgsDxfLabelProvider::registerDxfFeature( QgsFeature &feature, QgsRenderContext &context, const QString &dxfLayerName ) void QgsDxfLabelProvider::registerDxfFeature( const QgsFeature &feature, QgsRenderContext &context, const QString &dxfLayerName )
{ {
registerFeature( feature, context ); registerFeature( feature, context );
mDxfExport->registerDxfLayer( layerId(), feature.id(), dxfLayerName ); mDxfExport->registerDxfLayer( layerId(), feature.id(), dxfLayerName );

View File

@ -54,7 +54,7 @@ class QgsDxfLabelProvider : public QgsVectorLayerLabelProvider
* \param context render context * \param context render context
* \param dxfLayerName name of dxf layer * \param dxfLayerName name of dxf layer
*/ */
void registerDxfFeature( QgsFeature &feature, QgsRenderContext &context, const QString &dxfLayerName ); void registerDxfFeature( const QgsFeature &feature, QgsRenderContext &context, const QString &dxfLayerName );
protected: protected:
//! pointer to parent DXF export where this instance is used //! pointer to parent DXF export where this instance is used

View File

@ -1038,13 +1038,15 @@ bool QgsPalLayerSettings::checkMinimumSizeMM( const QgsRenderContext &ct, const
return QgsPalLabeling::checkMinimumSizeMM( ct, geom, minSize ); return QgsPalLabeling::checkMinimumSizeMM( ct, geom, minSize );
} }
void QgsPalLayerSettings::calculateLabelSize( const QFontMetricsF *fm, QString text, double &labelX, double &labelY, QgsFeature *f, QgsRenderContext *context ) void QgsPalLayerSettings::calculateLabelSize( const QFontMetricsF *fm, const QString &text, double &labelX, double &labelY, const QgsFeature *f, QgsRenderContext *context )
{ {
if ( !fm || !f ) if ( !fm || !f )
{ {
return; return;
} }
QString textCopy( text );
//try to keep < 2.12 API - handle no passed render context //try to keep < 2.12 API - handle no passed render context
std::unique_ptr< QgsRenderContext > scopedRc; std::unique_ptr< QgsRenderContext > scopedRc;
if ( !context ) if ( !context )
@ -1150,29 +1152,25 @@ void QgsPalLayerSettings::calculateLabelSize( const QFontMetricsF *fm, QString t
if ( placeDirSymb == QgsPalLayerSettings::SymbolLeftRight ) if ( placeDirSymb == QgsPalLayerSettings::SymbolLeftRight )
{ {
text.append( dirSym ); textCopy.append( dirSym );
} }
else else
{ {
text.prepend( dirSym + QStringLiteral( "\n" ) ); // SymbolAbove or SymbolBelow textCopy.prepend( dirSym + QStringLiteral( "\n" ) ); // SymbolAbove or SymbolBelow
} }
} }
double w = 0.0, h = 0.0; double w = 0.0, h = 0.0;
QStringList multiLineSplit = QgsPalLabeling::splitToLines( text, wrapchr, evalAutoWrapLength, useMaxLineLengthForAutoWrap ); const QStringList multiLineSplit = QgsPalLabeling::splitToLines( textCopy, wrapchr, evalAutoWrapLength, useMaxLineLengthForAutoWrap );
int lines = multiLineSplit.size(); int lines = multiLineSplit.size();
double labelHeight = fm->ascent() + fm->descent(); // ignore +1 for baseline double labelHeight = fm->ascent() + fm->descent(); // ignore +1 for baseline
h += fm->height() + static_cast< double >( ( lines - 1 ) * labelHeight * multilineH ); h += fm->height() + static_cast< double >( ( lines - 1 ) * labelHeight * multilineH );
for ( int i = 0; i < lines; ++i ) for ( const QString &line : multiLineSplit )
{ {
double width = fm->width( multiLineSplit.at( i ) ); w = std::max( w, fm->width( line ) );
if ( width > w )
{
w = width;
}
} }
#if 0 // XXX strk #if 0 // XXX strk
@ -1186,7 +1184,7 @@ void QgsPalLayerSettings::calculateLabelSize( const QFontMetricsF *fm, QString t
#endif #endif
} }
void QgsPalLayerSettings::registerFeature( QgsFeature &f, QgsRenderContext &context, QgsLabelFeature **labelFeature, QgsGeometry obstacleGeometry ) void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext &context, QgsLabelFeature **labelFeature, QgsGeometry obstacleGeometry )
{ {
// either used in QgsPalLabeling (palLayer is set) or in QgsLabelingEngine (labelFeature is set) // either used in QgsPalLabeling (palLayer is set) or in QgsLabelingEngine (labelFeature is set)
Q_ASSERT( labelFeature ); Q_ASSERT( labelFeature );
@ -1995,7 +1993,7 @@ void QgsPalLayerSettings::registerFeature( QgsFeature &f, QgsRenderContext &cont
lf->setDataDefinedValues( dataDefinedValues ); lf->setDataDefinedValues( dataDefinedValues );
} }
void QgsPalLayerSettings::registerObstacleFeature( QgsFeature &f, QgsRenderContext &context, QgsLabelFeature **obstacleFeature, const QgsGeometry &obstacleGeometry ) void QgsPalLayerSettings::registerObstacleFeature( const QgsFeature &f, QgsRenderContext &context, QgsLabelFeature **obstacleFeature, const QgsGeometry &obstacleGeometry )
{ {
mCurFeat = &f; mCurFeat = &f;

View File

@ -750,8 +750,11 @@ class CORE_EXPORT QgsPalLayerSettings
//! Z-Index of label, where labels with a higher z-index are rendered on top of labels with a lower z-index //! Z-Index of label, where labels with a higher z-index are rendered on top of labels with a lower z-index
double zIndex; double zIndex;
// called from register feature hook /**
void calculateLabelSize( const QFontMetricsF *fm, QString text, double &labelX, double &labelY, QgsFeature *f = nullptr, QgsRenderContext *context = nullptr ); * Calculates the space required to render the provided \a text in map units.
* Results will be written to \a labelX and \a labelY.
*/
void calculateLabelSize( const QFontMetricsF *fm, const QString &text, double &labelX, double &labelY, const QgsFeature *f = nullptr, QgsRenderContext *context = nullptr );
/** /**
* Register a feature for labeling. * Register a feature for labeling.
@ -766,7 +769,7 @@ class CORE_EXPORT QgsPalLayerSettings
* the feature's original geometry will be used as an obstacle for labels. Not available * the feature's original geometry will be used as an obstacle for labels. Not available
* in Python bindings. * in Python bindings.
*/ */
void registerFeature( QgsFeature &f, QgsRenderContext &context, void registerFeature( const QgsFeature &f, QgsRenderContext &context,
QgsLabelFeature **labelFeature SIP_PYARGREMOVE = nullptr, QgsLabelFeature **labelFeature SIP_PYARGREMOVE = nullptr,
QgsGeometry obstacleGeometry SIP_PYARGREMOVE = QgsGeometry() ); QgsGeometry obstacleGeometry SIP_PYARGREMOVE = QgsGeometry() );
@ -823,7 +826,7 @@ class CORE_EXPORT QgsPalLayerSettings
void setFormat( const QgsTextFormat &format ) { mFormat = format; } void setFormat( const QgsTextFormat &format ) { mFormat = format; }
// temporary stuff: set when layer gets prepared or labeled // temporary stuff: set when layer gets prepared or labeled
QgsFeature *mCurFeat = nullptr; const QgsFeature *mCurFeat = nullptr;
QgsFields mCurFields; QgsFields mCurFields;
int fieldIndex; int fieldIndex;
const QgsMapToPixel *xform = nullptr; const QgsMapToPixel *xform = nullptr;
@ -835,7 +838,6 @@ class CORE_EXPORT QgsPalLayerSettings
int mFeaturesToLabel = 0; // total features that will probably be labeled, may be less (figured before PAL) int mFeaturesToLabel = 0; // total features that will probably be labeled, may be less (figured before PAL)
int mFeatsSendingToPal = 0; // total features tested for sending into PAL (relative to maxNumLabels) int mFeatsSendingToPal = 0; // total features tested for sending into PAL (relative to maxNumLabels)
int mFeatsRegPal = 0; // number of features registered in PAL, when using limitNumLabels int mFeatsRegPal = 0; // number of features registered in PAL, when using limitNumLabels
private: private:
friend class QgsVectorLayer; // to allow calling readFromLayerCustomProperties() friend class QgsVectorLayer; // to allow calling readFromLayerCustomProperties()
@ -899,7 +901,7 @@ class CORE_EXPORT QgsPalLayerSettings
/** /**
* Registers a feature as an obstacle only (no label rendered) * Registers a feature as an obstacle only (no label rendered)
*/ */
void registerObstacleFeature( QgsFeature &f, QgsRenderContext &context, QgsLabelFeature **obstacleFeature, const QgsGeometry &obstacleGeometry = QgsGeometry() ); void registerObstacleFeature( const QgsFeature &f, QgsRenderContext &context, QgsLabelFeature **obstacleFeature, const QgsGeometry &obstacleGeometry = QgsGeometry() );
QMap<Property, QVariant> dataDefinedValues; QMap<Property, QVariant> dataDefinedValues;

View File

@ -37,7 +37,7 @@ bool QgsRuleBasedLabelProvider::prepare( const QgsRenderContext &context, QSet<Q
return true; return true;
} }
void QgsRuleBasedLabelProvider::registerFeature( QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry ) void QgsRuleBasedLabelProvider::registerFeature( const QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry )
{ {
// will register the feature to relevant sub-providers // will register the feature to relevant sub-providers
mRules->rootRule()->registerFeature( feature, context, mSubProviders, obstacleGeometry ); mRules->rootRule()->registerFeature( feature, context, mSubProviders, obstacleGeometry );
@ -316,7 +316,7 @@ void QgsRuleBasedLabeling::Rule::prepare( const QgsRenderContext &context, QSet<
} }
} }
QgsRuleBasedLabeling::Rule::RegisterResult QgsRuleBasedLabeling::Rule::registerFeature( QgsFeature &feature, QgsRenderContext &context, QgsRuleBasedLabeling::RuleToProviderMap &subProviders, const QgsGeometry &obstacleGeometry ) QgsRuleBasedLabeling::Rule::RegisterResult QgsRuleBasedLabeling::Rule::registerFeature( const QgsFeature &feature, QgsRenderContext &context, QgsRuleBasedLabeling::RuleToProviderMap &subProviders, const QgsGeometry &obstacleGeometry )
{ {
if ( !isFilterOK( feature, context ) if ( !isFilterOK( feature, context )
|| !isScaleOK( context.rendererScale() ) ) || !isScaleOK( context.rendererScale() ) )
@ -363,7 +363,7 @@ QgsRuleBasedLabeling::Rule::RegisterResult QgsRuleBasedLabeling::Rule::registerF
return Filtered; return Filtered;
} }
bool QgsRuleBasedLabeling::Rule::isFilterOK( QgsFeature &f, QgsRenderContext &context ) const bool QgsRuleBasedLabeling::Rule::isFilterOK( const QgsFeature &f, QgsRenderContext &context ) const
{ {
if ( ! mFilter || mElseRule ) if ( ! mFilter || mElseRule )
return true; return true;

View File

@ -282,7 +282,7 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
* register individual features * register individual features
* \note not available in Python bindings * \note not available in Python bindings
*/ */
RegisterResult registerFeature( QgsFeature &feature, QgsRenderContext &context, RuleToProviderMap &subProviders, const QgsGeometry &obstacleGeometry = QgsGeometry() ) SIP_SKIP; RegisterResult registerFeature( const QgsFeature &feature, QgsRenderContext &context, RuleToProviderMap &subProviders, const QgsGeometry &obstacleGeometry = QgsGeometry() ) SIP_SKIP;
/** /**
* Returns true if this rule or any of its children requires advanced composition effects * Returns true if this rule or any of its children requires advanced composition effects
@ -302,7 +302,7 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
* \param context The context in which the rendering happens * \param context The context in which the rendering happens
* \returns True if the feature shall be rendered * \returns True if the feature shall be rendered
*/ */
bool isFilterOK( QgsFeature &f, QgsRenderContext &context ) const; bool isFilterOK( const QgsFeature &f, QgsRenderContext &context ) const;
/** /**
* Check if this rule applies for a given \a scale. * Check if this rule applies for a given \a scale.
@ -395,7 +395,7 @@ class CORE_EXPORT QgsRuleBasedLabelProvider : public QgsVectorLayerLabelProvider
bool prepare( const QgsRenderContext &context, QSet<QString> &attributeNames ) override; bool prepare( const QgsRenderContext &context, QSet<QString> &attributeNames ) override;
void registerFeature( QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry = QgsGeometry() ) override; void registerFeature( const QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry = QgsGeometry() ) override;
//! create a label provider //! create a label provider
virtual QgsVectorLayerLabelProvider *createProvider( QgsVectorLayer *layer, const QString &providerId, bool withFeatureLoop, const QgsPalLayerSettings *settings ); virtual QgsVectorLayerLabelProvider *createProvider( QgsVectorLayer *layer, const QString &providerId, bool withFeatureLoop, const QgsPalLayerSettings *settings );

View File

@ -258,9 +258,10 @@ QList<QgsLabelFeature *> QgsVectorLayerLabelProvider::labelFeatures( QgsRenderCo
return mLabels; return mLabels;
} }
void QgsVectorLayerLabelProvider::registerFeature( QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry ) void QgsVectorLayerLabelProvider::registerFeature( const QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry )
{ {
QgsLabelFeature *label = nullptr; QgsLabelFeature *label = nullptr;
mSettings.registerFeature( feature, context, &label, obstacleGeometry ); mSettings.registerFeature( feature, context, &label, obstacleGeometry );
if ( label ) if ( label )
mLabels << label; mLabels << label;

View File

@ -74,7 +74,7 @@ class CORE_EXPORT QgsVectorLayerLabelProvider : public QgsAbstractLabelProvider
* symbol, the obstacle geometry should represent the bounds of the offset symbol). If not set, * symbol, the obstacle geometry should represent the bounds of the offset symbol). If not set,
* the feature's original geometry will be used as an obstacle for labels. * the feature's original geometry will be used as an obstacle for labels.
*/ */
virtual void registerFeature( QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry = QgsGeometry() ); virtual void registerFeature( const QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry = QgsGeometry() );
/** /**
* Returns the geometry for a point feature which should be used as an obstacle for labels. This * Returns the geometry for a point feature which should be used as an obstacle for labels. This