Skip to content
Permalink
Browse files

Unify scale API in rule based labeling, fix GUI issues

  • Loading branch information
nyalldawson committed Jun 9, 2017
1 parent 9805782 commit b0c35ab4b8c8bdd6ae0d77d25fda79a8ddcbcfb4
@@ -33,7 +33,7 @@ class QgsRuleBasedLabeling : QgsAbstractVectorLayerLabeling
#include "qgsrulebasedlabeling.h"
%End
public:
Rule( QgsPalLayerSettings *settings /Transfer/, int scaleMinDenom = 0, int scaleMaxDenom = 0, const QString &filterExp = QString(), const QString &description = QString(), bool elseRule = false );
Rule( QgsPalLayerSettings *settings /Transfer/, int maximumScale = 0, int minimumScale = 0, const QString &filterExp = QString(), const QString &description = QString(), bool elseRule = false );
%Docstring
takes ownership of settings
%End
@@ -61,26 +61,26 @@ takes ownership of settings
:rtype: bool
%End

int scaleMinDenom() const;
double maximumScale() const;
%Docstring
The minimum scale at which this label rule should be applied

E.g. Denominator 1000 is a scale of 1:1000, where a rule with minimum denominator
of 900 will not be applied while a rule with 2000 will be applied.

:return: The minimum scale denominator
:rtype: int
Returns the maximum map scale (i.e. most "zoomed in" scale) at which the label rule will be active.
The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
A scale of 0 indicates no maximum scale visibility.
.. seealso:: minimumScale()
.. seealso:: setMaximumScale()
.. versionadded:: 3.0
:rtype: float
%End

int scaleMaxDenom() const;
double minimumScale() const;
%Docstring
The maximum scale denominator at which this label rule should be applied

E.g. Denominator 1000 is a scale of 1:1000, where a rule with maximum denominator
of 900 will be applied while a rule with 2000 will not be applied.

:return: The maximum scale denominator
:rtype: int
Returns the minimum map scale (i.e. most "zoomed out" scale) at which the label rule will be active.
The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
A scale of 0 indicates no minimum scale visibility.
.. seealso:: maximumScale()
.. seealso:: setMinimumScale()
.. versionadded:: 3.0
:rtype: float
%End

QString filterExpression() const;
@@ -125,20 +125,22 @@ Unique rule identifier (for identification of rule within labeling, used as prov
set new settings (or NULL). Deletes old settings if any.
%End

void setScaleMinDenom( int scaleMinDenom );
void setMinimumScale( double scale );
%Docstring
Set the minimum denominator for which this rule shall apply.
E.g. 1000 if it shall be evaluated between 1:1000 and 1:100'000
Set to 0 to disable the minimum check
\param scaleMinDenom The minimum scale denominator for this rule
Sets the minimum map ``scale`` (i.e. most "zoomed out" scale) at which the label rule will be active.
The ``scale`` value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
A ``scale`` of 0 indicates no minimum scale visibility.
.. seealso:: minimumScale()
.. seealso:: setMaximumScale()
%End

void setScaleMaxDenom( int scaleMaxDenom );
void setMaximumScale( double scale );
%Docstring
Set the maximum denominator for which this rule shall apply.
E.g. 100'000 if it shall be evaluated between 1:1000 and 1:100'000
Set to 0 to disable the maximum check
\param scaleMaxDenom maximum scale denominator for this rule
Sets the maximum map ``scale`` (i.e. most "zoomed in" scale) at which the rule will be active.
The ``scale`` value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
A ``scale`` of 0 indicates no maximum scale visibility.
.. seealso:: maximumScale()
.. seealso:: setMinimumScale()
%End

void setFilterExpression( const QString &filterExp );
@@ -209,20 +209,6 @@ QgsRuleBasedLabeling::Rule *QgsRuleBasedLabelingWidget::currentRule()
return mModel->ruleForIndex( idx );
}


////

static QString _formatScale( int denom )
{
if ( denom != 0 )
{
QString txt = QStringLiteral( "1:%L1" ).arg( denom );
return txt;
}
else
return QString();
}

////

QgsRuleBasedLabelingModel::QgsRuleBasedLabelingModel( QgsRuleBasedLabeling::Rule *rootRule, QObject *parent )
@@ -269,9 +255,9 @@ QVariant QgsRuleBasedLabelingModel::data( const QModelIndex &index, int role ) c
return rule->filterExpression().isEmpty() ? tr( "(no filter)" ) : rule->filterExpression();
}
case 2:
return rule->dependsOnScale() ? _formatScale( rule->scaleMaxDenom() ) : QVariant();
return rule->dependsOnScale() ? QgsScaleComboBox::toString( rule->minimumScale() ) : QVariant();
case 3:
return rule->dependsOnScale() ? _formatScale( rule->scaleMinDenom() ) : QVariant();
return rule->dependsOnScale() ? QgsScaleComboBox::toString( rule->maximumScale() ) : QVariant();
case 4:
return rule->settings() ? rule->settings()->fieldName : QVariant();
default:
@@ -306,9 +292,9 @@ QVariant QgsRuleBasedLabelingModel::data( const QModelIndex &index, int role ) c
case 1:
return rule->filterExpression();
case 2:
return rule->scaleMaxDenom();
return rule->minimumScale();
case 3:
return rule->scaleMinDenom();
return rule->maximumScale();
case 4:
return rule->settings() ? rule->settings()->fieldName : QVariant();
default:
@@ -406,10 +392,10 @@ bool QgsRuleBasedLabelingModel::setData( const QModelIndex &index, const QVarian
rule->setFilterExpression( value.toString() );
break;
case 2: // scale min
rule->setScaleMaxDenom( value.toInt() );
rule->setMinimumScale( value.toDouble() );
break;
case 3: // scale max
rule->setScaleMinDenom( value.toInt() );
rule->setMaximumScale( value.toDouble() );
break;
case 4: // label text
if ( !rule->settings() )
@@ -601,10 +587,8 @@ QgsLabelingRulePropsWidget::QgsLabelingRulePropsWidget( QgsRuleBasedLabeling::Ru
{
groupScale->setChecked( true );
// caution: rule uses scale denom, scale widget uses true scales
if ( rule->scaleMinDenom() > 0 )
mScaleRangeWidget->setMaximumScale( rule->scaleMinDenom() );
if ( rule->scaleMaxDenom() > 0 )
mScaleRangeWidget->setMinimumScale( rule->scaleMaxDenom() );
mScaleRangeWidget->setMaximumScale( qMax( rule->maximumScale(), 0.0 ) );
mScaleRangeWidget->setMinimumScale( qMax( rule->minimumScale(), 0.0 ) );
}
mScaleRangeWidget->setMapCanvas( mMapCanvas );

@@ -703,8 +687,7 @@ void QgsLabelingRulePropsWidget::apply()
{
mRule->setFilterExpression( editFilter->text() );
mRule->setDescription( editDescription->text() );
// caution: rule uses scale denom, scale widget uses true scales
mRule->setScaleMinDenom( groupScale->isChecked() ? mScaleRangeWidget->minimumScale() : 0 );
mRule->setScaleMaxDenom( groupScale->isChecked() ? mScaleRangeWidget->maximumScale() : 0 );
mRule->setMinimumScale( groupScale->isChecked() ? mScaleRangeWidget->minimumScale() : 0 );
mRule->setMaximumScale( groupScale->isChecked() ? mScaleRangeWidget->maximumScale() : 0 );
mRule->setSettings( groupSettings->isChecked() ? new QgsPalLayerSettings( mLabelingGui->layerSettings() ) : nullptr );
}
@@ -62,8 +62,8 @@ QList<QgsAbstractLabelProvider *> QgsRuleBasedLabelProvider::subProviders()
QgsRuleBasedLabeling::Rule::Rule( QgsPalLayerSettings *settings, int scaleMinDenom, int scaleMaxDenom, const QString &filterExp, const QString &description, bool elseRule )
: mParent( nullptr )
, mSettings( settings )
, mScaleMinDenom( scaleMinDenom )
, mScaleMaxDenom( scaleMaxDenom )
, mMaximumScale( scaleMinDenom )
, mMinimumScale( scaleMaxDenom )
, mFilterExp( filterExp )
, mDescription( description )
, mElseRule( elseRule )
@@ -185,7 +185,7 @@ const QgsRuleBasedLabeling::Rule *QgsRuleBasedLabeling::Rule::findRuleByKey( con
QgsRuleBasedLabeling::Rule *QgsRuleBasedLabeling::Rule::clone() const
{
QgsPalLayerSettings *s = mSettings ? new QgsPalLayerSettings( *mSettings ) : nullptr;
Rule *newrule = new Rule( s, mScaleMinDenom, mScaleMaxDenom, mFilterExp, mDescription );
Rule *newrule = new Rule( s, mMaximumScale, mMinimumScale, mFilterExp, mDescription );
newrule->setActive( mIsActive );
// clone children
Q_FOREACH ( Rule *rule, mChildren )
@@ -243,10 +243,10 @@ QDomElement QgsRuleBasedLabeling::Rule::save( QDomDocument &doc, const QgsReadWr
}
if ( !mFilterExp.isEmpty() )
ruleElem.setAttribute( QStringLiteral( "filter" ), mFilterExp );
if ( mScaleMinDenom != 0 )
ruleElem.setAttribute( QStringLiteral( "scalemindenom" ), mScaleMinDenom );
if ( mScaleMaxDenom != 0 )
ruleElem.setAttribute( QStringLiteral( "scalemaxdenom" ), mScaleMaxDenom );
if ( mMaximumScale != 0 )
ruleElem.setAttribute( QStringLiteral( "scalemindenom" ), mMaximumScale );
if ( mMinimumScale != 0 )
ruleElem.setAttribute( QStringLiteral( "scalemaxdenom" ), mMinimumScale );
if ( !mDescription.isEmpty() )
ruleElem.setAttribute( QStringLiteral( "description" ), mDescription );
if ( !mIsActive )
@@ -364,11 +364,11 @@ bool QgsRuleBasedLabeling::Rule::isScaleOK( double scale ) const
{
if ( qgsDoubleNear( scale, 0.0 ) ) // so that we can count features in classes without scale context
return true;
if ( mScaleMinDenom == 0 && mScaleMaxDenom == 0 )
if ( qgsDoubleNear( mMaximumScale, 0.0 ) && qgsDoubleNear( mMinimumScale, 0.0 ) )
return true;
if ( mScaleMinDenom != 0 && mScaleMinDenom > scale )
if ( !qgsDoubleNear( mMaximumScale, 0.0 ) && mMaximumScale > scale )
return false;
if ( mScaleMaxDenom != 0 && mScaleMaxDenom < scale )
if ( !qgsDoubleNear( mMinimumScale, 0.0 ) && mMinimumScale < scale )
return false;
return true;
}
@@ -52,7 +52,7 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
{
public:
//! takes ownership of settings
Rule( QgsPalLayerSettings *settings SIP_TRANSFER, int scaleMinDenom = 0, int scaleMaxDenom = 0, const QString &filterExp = QString(), const QString &description = QString(), bool elseRule = false );
Rule( QgsPalLayerSettings *settings SIP_TRANSFER, int maximumScale = 0, int minimumScale = 0, const QString &filterExp = QString(), const QString &description = QString(), bool elseRule = false );
~Rule();

//! Rules cannot be copied.
@@ -78,27 +78,27 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
*
* \returns True if scale based labeling is active
*/
bool dependsOnScale() const { return mScaleMinDenom != 0 || mScaleMaxDenom != 0; }
bool dependsOnScale() const { return mMinimumScale != 0 || mMaximumScale != 0; }

/**
* The minimum scale at which this label rule should be applied
*
* E.g. Denominator 1000 is a scale of 1:1000, where a rule with minimum denominator
* of 900 will not be applied while a rule with 2000 will be applied.
*
* \returns The minimum scale denominator
* Returns the maximum map scale (i.e. most "zoomed in" scale) at which the label rule will be active.
* The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* A scale of 0 indicates no maximum scale visibility.
* \see minimumScale()
* \see setMaximumScale()
* \since QGIS 3.0
*/
int scaleMinDenom() const { return mScaleMinDenom; }
double maximumScale() const { return mMaximumScale; }

/**
* The maximum scale denominator at which this label rule should be applied
*
* E.g. Denominator 1000 is a scale of 1:1000, where a rule with maximum denominator
* of 900 will be applied while a rule with 2000 will not be applied.
*
* \returns The maximum scale denominator
* Returns the minimum map scale (i.e. most "zoomed out" scale) at which the label rule will be active.
* The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* A scale of 0 indicates no minimum scale visibility.
* \see maximumScale()
* \see setMinimumScale()
* \since QGIS 3.0
*/
int scaleMaxDenom() const { return mScaleMaxDenom; }
double minimumScale() const { return mMinimumScale; }

/**
* A filter that will check if this rule applies
@@ -134,20 +134,22 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
void setSettings( QgsPalLayerSettings *settings SIP_TRANSFER );

/**
* Set the minimum denominator for which this rule shall apply.
* E.g. 1000 if it shall be evaluated between 1:1000 and 1:100'000
* Set to 0 to disable the minimum check
* \param scaleMinDenom The minimum scale denominator for this rule
* Sets the minimum map \a scale (i.e. most "zoomed out" scale) at which the label rule will be active.
* The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* A \a scale of 0 indicates no minimum scale visibility.
* \see minimumScale()
* \see setMaximumScale()
*/
void setScaleMinDenom( int scaleMinDenom ) { mScaleMinDenom = scaleMinDenom; }
void setMinimumScale( double scale ) { mMinimumScale = scale; }

/**
* Set the maximum denominator for which this rule shall apply.
* E.g. 100'000 if it shall be evaluated between 1:1000 and 1:100'000
* Set to 0 to disable the maximum check
* \param scaleMaxDenom maximum scale denominator for this rule
* Sets the maximum map \a scale (i.e. most "zoomed in" scale) at which the rule will be active.
* The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* A \a scale of 0 indicates no maximum scale visibility.
* \see maximumScale()
* \see setMinimumScale()
*/
void setScaleMaxDenom( int scaleMaxDenom ) { mScaleMaxDenom = scaleMaxDenom; }
void setMaximumScale( double scale ) { mMaximumScale = scale; }

/**
* Set the expression used to check if a given feature shall be rendered with this rule
@@ -283,8 +285,9 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
bool isFilterOK( QgsFeature &f, QgsRenderContext &context ) const;

/**
* Check if this rule applies for a given scale
* \param scale The scale to check. If set to 0, it will always return true.
* Check if this rule applies for a given \a scale.
* The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
* If set to 0, it will always return true.
*
* \returns If the rule will be evaluated at this scale
*/
@@ -303,7 +306,8 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
private:
Rule *mParent; // parent rule (NULL only for root rule)
QgsPalLayerSettings *mSettings = nullptr;
int mScaleMinDenom, mScaleMaxDenom;
double mMaximumScale = 0;
double mMinimumScale = 0;
QString mFilterExp, mDescription;
bool mElseRule;
RuleList mChildren;
@@ -283,11 +283,11 @@ bool QgsRuleBasedRenderer::Rule::isScaleOK( double scale ) const
{
if ( qgsDoubleNear( scale, 0.0 ) ) // so that we can count features in classes without scale context
return true;
if ( mMaximumScale == 0 && mMinimumScale == 0 )
if ( qgsDoubleNear( mMaximumScale, 0.0 ) && qgsDoubleNear( mMinimumScale, 0.0 ) )
return true;
if ( mMaximumScale != 0 && mMaximumScale > scale )
if ( !qgsDoubleNear( mMaximumScale, 0.0 ) && mMaximumScale > scale )
return false;
if ( mMinimumScale != 0 && mMinimumScale < scale )
if ( !qgsDoubleNear( mMinimumScale, 0.0 ) && mMinimumScale < scale )
return false;
return true;
}

0 comments on commit b0c35ab

Please sign in to comment.
You can’t perform that action at this time.