Skip to content

Commit

Permalink
Changing decimal places to precision, allowing negative precision, im…
Browse files Browse the repository at this point in the history
…proving rounding for locales with , instead of . for decimal point
  • Loading branch information
ccrook committed Sep 30, 2014
1 parent 465219a commit 21ddf12
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 43 deletions.
4 changes: 2 additions & 2 deletions python/core/symbology-ng/qgsgraduatedsymbolrendererv2.sip
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ class QgsRendererRangeV2LabelFormat
QString format() const;
void setFormat( QString format );

int decimalPlaces() const;
void setDecimalPlaces( int decimalPlaces );
int precision();
void setPrecision( int precision );

bool trimTrailingZeroes() const;
void setTrimTrailingZeroes( bool trimTrailingZeroes );
Expand Down
64 changes: 43 additions & 21 deletions src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,19 +169,24 @@ void QgsRendererRangeV2::toSld( QDomDocument &doc, QDomElement &element, QgsStri

///////////

int QgsRendererRangeV2LabelFormat::MaxPrecision=15;
int QgsRendererRangeV2LabelFormat::MinPrecision=-6;

QgsRendererRangeV2LabelFormat::QgsRendererRangeV2LabelFormat():
mFormat( " %1 - %2 " ),
mDecimalPlaces( 4 ),
mPrecision( 4 ),
mTrimTrailingZeroes( false ),
mReTrailingZeroes( "\\.?0*$" )
mNumberScale( 1.0 ),
mNumberSuffix( "" ),
mReTrailingZeroes( "[.,]?0*$" )
{
}

QgsRendererRangeV2LabelFormat::QgsRendererRangeV2LabelFormat( QString format, int decimalPlaces, bool trimTrailingZeroes ):
mReTrailingZeroes( "\\.?0*$" )
QgsRendererRangeV2LabelFormat::QgsRendererRangeV2LabelFormat( QString format, int precision, bool trimTrailingZeroes ):
mReTrailingZeroes( "[.,]?0*$" )
{
setFormat( format );
setDecimalPlaces( decimalPlaces );
setPrecision( precision );
setTrimTrailingZeroes( trimTrailingZeroes );
}

Expand All @@ -190,7 +195,7 @@ bool QgsRendererRangeV2LabelFormat::operator==( const QgsRendererRangeV2LabelFor
{
return
format() == other.format() &&
decimalPlaces() == other.decimalPlaces() &&
precision() == other.precision() &&
trimTrailingZeroes() == other.trimTrailingZeroes();
}

Expand All @@ -199,32 +204,49 @@ bool QgsRendererRangeV2LabelFormat::operator!=( const QgsRendererRangeV2LabelFor
return !( *this == other );
}

void QgsRendererRangeV2LabelFormat::setDecimalPlaces( int decimalPlaces )
void QgsRendererRangeV2LabelFormat::setPrecision( int precision )
{
// Limit the range of decimal places to a reasonable range
if ( decimalPlaces < 0 ) decimalPlaces = 0;
if ( decimalPlaces > 15 ) decimalPlaces = 15;
mDecimalPlaces = decimalPlaces;
if ( precision < MinPrecision ) precision = MinPrecision;
if ( precision > MaxPrecision ) precision = MaxPrecision;
mPrecision = precision;
mNumberScale=1.0;
mNumberSuffix="";
while( precision < 0 )
{
precision++;
mNumberScale /= 10.0;
mNumberSuffix.append('0');
}
}

QString QgsRendererRangeV2LabelFormat::labelForRange( const QgsRendererRangeV2 &range ) const
{
return labelForRange( range.lowerValue(), range.upperValue() );
}

QString QgsRendererRangeV2LabelFormat::labelForRange( double lower, double upper ) const
QString QgsRendererRangeV2LabelFormat::formatNumber( double value ) const
{
QString lowerStr = QString::number( lower, 'f', mDecimalPlaces );
QString upperStr = QString::number( upper, 'f', mDecimalPlaces );

if ( mTrimTrailingZeroes )
if( mPrecision > 0 )
{
if ( lowerStr.contains( '.' ) ) lowerStr = lowerStr.replace( mReTrailingZeroes, "" );
if ( upperStr.contains( '.' ) ) upperStr = upperStr.replace( mReTrailingZeroes, "" );
QString valueStr=QString::number( value, 'f', mPrecision );
if( mTrimTrailingZeroes ) valueStr=valueStr.replace(mReTrailingZeroes,"");
return valueStr;
}
else
{
QString valueStr=QString::number( value*mNumberScale, 'f', 0 );
if( valueStr != "0" ) valueStr=valueStr+mNumberSuffix;
return valueStr;
}
}

QString legend(mFormat);
QString QgsRendererRangeV2LabelFormat::labelForRange( double lower, double upper ) const
{
QString lowerStr=formatNumber(lower);
QString upperStr=formatNumber(upper);

QString legend(mFormat);
return legend.replace( "%1",lowerStr).replace("%2",upperStr );
}

Expand All @@ -235,14 +257,14 @@ void QgsRendererRangeV2LabelFormat::setFromDomElement( QDomElement &element )
element.attribute( "separator", " - " ) + "%2" +
element.attribute( "suffix", " " )
);
mDecimalPlaces = element.attribute( "decimalplaces", "4" ).toInt();
setPrecision( element.attribute( "decimalplaces", "4" ).toInt());
mTrimTrailingZeroes = element.attribute( "trimtrailingzeroes", "false" ) == "true";
}

void QgsRendererRangeV2LabelFormat::saveToDomElement( QDomElement &element )
{
element.setAttribute( "format", mFormat );
element.setAttribute( "decimalplaces", mDecimalPlaces );
element.setAttribute( "decimalplaces", mPrecision );
element.setAttribute( "trimtrailingzeroes", mTrimTrailingZeroes ? "true" : "false" );
}

Expand Down Expand Up @@ -1454,7 +1476,7 @@ void QgsGraduatedSymbolRendererV2::calculateLabelDecimalPlaces( bool updateRange
ndp--;
nextDpMinRange *= 10.0;
}
mLabelFormat.setDecimalPlaces( ndp );
mLabelFormat.setPrecision( ndp );
if ( updateRanges ) setLabelFormat( mLabelFormat, true );
}

Expand Down
15 changes: 11 additions & 4 deletions src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,31 +71,38 @@ class CORE_EXPORT QgsRendererRangeV2LabelFormat
{
public:
QgsRendererRangeV2LabelFormat();
QgsRendererRangeV2LabelFormat( QString format, int decimalPlaces = 4, bool trimTrailingZeroes = false );
QgsRendererRangeV2LabelFormat( QString format, int precision = 4, bool trimTrailingZeroes = false );

bool operator==( const QgsRendererRangeV2LabelFormat & other ) const;
bool operator!=( const QgsRendererRangeV2LabelFormat & other ) const;

QString format() const { return mFormat; }
void setFormat( QString format ) { mFormat = format; }

int decimalPlaces() const { return mDecimalPlaces; }
void setDecimalPlaces( int decimalPlaces );
int precision() const { return mPrecision; }
void setPrecision( int precision );

bool trimTrailingZeroes() const { return mTrimTrailingZeroes; }
void setTrimTrailingZeroes( bool trimTrailingZeroes ) { mTrimTrailingZeroes = trimTrailingZeroes; }

//! @note labelForLowerUpper in python bindings
QString labelForRange( double lower, double upper ) const;
QString labelForRange( const QgsRendererRangeV2 &range ) const;
QString formatNumber( double value ) const;

void setFromDomElement( QDomElement &element );
void saveToDomElement( QDomElement &element );

static int MaxPrecision;
static int MinPrecision;

protected:
QString mFormat;
int mDecimalPlaces;
int mPrecision;
bool mTrimTrailingZeroes;
// values used to manage number formatting - precision and trailing zeroes
double mNumberScale;
QString mNumberSuffix;
QRegExp mReTrailingZeroes;
};

Expand Down
32 changes: 20 additions & 12 deletions src/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ QVariant QgsGraduatedSymbolRendererV2Model::data( const QModelIndex &index, int
if ( !index.isValid() || !mRenderer ) return QVariant();

const QgsRendererRangeV2 range = mRenderer->ranges().value( index.row() );
QString rangeStr = QString::number( range.lowerValue(), 'f', 4 ) + " - " + QString::number( range.upperValue(), 'f', 4 );

if ( role == Qt::CheckStateRole && index.column() == 0 )
{
Expand All @@ -128,7 +127,12 @@ QVariant QgsGraduatedSymbolRendererV2Model::data( const QModelIndex &index, int
{
switch ( index.column() )
{
case 1: return rangeStr;
case 1:
{
int decimalPlaces=mRenderer->labelFormat().precision()+2;
if( decimalPlaces < 0 ) decimalPlaces=0;
return QString::number( range.lowerValue(), 'f', decimalPlaces ) + " - " + QString::number( range.upperValue(), 'f', decimalPlaces );
}
case 2: return range.label();
default: return QVariant();
}
Expand All @@ -145,7 +149,7 @@ QVariant QgsGraduatedSymbolRendererV2Model::data( const QModelIndex &index, int
{
switch ( index.column() )
{
case 1: return rangeStr;
// case 1: return rangeStr;
case 2: return range.label();
default: return QVariant();
}
Expand Down Expand Up @@ -393,6 +397,9 @@ QgsGraduatedSymbolRendererV2Widget::QgsGraduatedSymbolRendererV2Widget( QgsVecto

cboGraduatedColorRamp->populate( mStyle );

spinPrecision->setMinimum( QgsRendererRangeV2LabelFormat::MinPrecision);
spinPrecision->setMaximum( QgsRendererRangeV2LabelFormat::MaxPrecision);

// set project default color ramp
QString defaultColorRamp = QgsProject::instance()->readEntry( "DefaultStyles", "/ColorRamp", "" );
if ( defaultColorRamp != "" )
Expand Down Expand Up @@ -456,7 +463,7 @@ void QgsGraduatedSymbolRendererV2Widget::connectUpdateHandlers()
connect( cboGraduatedMode, SIGNAL( currentIndexChanged( int ) ) , this, SLOT( classifyGraduated() ) );
connect( cboGraduatedColorRamp, SIGNAL( currentIndexChanged( int ) ) , this, SLOT( reapplyColorRamp() ) );
connect( cbxInvertedColorRamp, SIGNAL( toggled( bool ) ) , this, SLOT( reapplyColorRamp() ) );
connect( spinDecimalPlaces, SIGNAL( valueChanged( int ) ), this, SLOT( labelFormatChanged() ) );
connect( spinPrecision, SIGNAL( valueChanged( int ) ), this, SLOT( labelFormatChanged() ) );
connect( cbxTrimTrailingZeroes, SIGNAL( toggled( bool ) ), this, SLOT( labelFormatChanged() ) );
connect( txtFormat, SIGNAL( textChanged( QString ) ), this, SLOT( labelFormatChanged() ) );

Expand All @@ -472,7 +479,7 @@ void QgsGraduatedSymbolRendererV2Widget::disconnectUpdateHandlers()
disconnect( cboGraduatedMode, SIGNAL( currentIndexChanged( int ) ) , this, SLOT( classifyGraduated() ) );
disconnect( cboGraduatedColorRamp, SIGNAL( currentIndexChanged( int ) ) , this, SLOT( reapplyColorRamp() ) );
disconnect( cbxInvertedColorRamp, SIGNAL( toggled( bool ) ) , this, SLOT( reapplyColorRamp() ) );
disconnect( spinDecimalPlaces, SIGNAL( valueChanged( int ) ), this, SLOT( labelFormatChanged() ) );
disconnect( spinPrecision, SIGNAL( valueChanged( int ) ), this, SLOT( labelFormatChanged() ) );
disconnect( cbxTrimTrailingZeroes, SIGNAL( toggled( bool ) ), this, SLOT( labelFormatChanged() ) );
disconnect( txtFormat, SIGNAL( textChanged( QString ) ), this, SLOT( labelFormatChanged() ) );

Expand Down Expand Up @@ -516,7 +523,7 @@ void QgsGraduatedSymbolRendererV2Widget::updateUiFromRenderer( bool updateCount

QgsRendererRangeV2LabelFormat labelFormat = mRenderer->labelFormat();
txtFormat->setText( labelFormat.format() );
spinDecimalPlaces->setValue( labelFormat.decimalPlaces() );
spinPrecision->setValue( labelFormat.precision() );
cbxTrimTrailingZeroes->setChecked( labelFormat.trimTrailingZeroes() );

mModel = new QgsGraduatedSymbolRendererV2Model( this );
Expand Down Expand Up @@ -733,11 +740,12 @@ void QgsGraduatedSymbolRendererV2Widget::changeRange( int rangeIdx )
QgsLUDialog dialog( this );

const QgsRendererRangeV2& range = mRenderer->ranges()[rangeIdx];
// Add arbitrary 3 to number of decimal places to retain a bit extra accuracy in
// case we want to??
int decimalPlaces = mRenderer->labelFormat().decimalPlaces();
dialog.setLowerValue( QString::number( range.lowerValue(), 'f', decimalPlaces + 3 ) );
dialog.setUpperValue( QString::number( range.upperValue(), 'f', decimalPlaces + 3 ) );
// Add arbitrary 2 to number of decimal places to retain a bit extra.
// Ensures users can see if legend is not completely honest!
int decimalPlaces = mRenderer->labelFormat().precision()+2;
if( decimalPlaces < 0 ) decimalPlaces=0;
dialog.setLowerValue( QString::number( range.lowerValue(), 'f', decimalPlaces ) );
dialog.setUpperValue( QString::number( range.upperValue(), 'f', decimalPlaces ) );

if ( dialog.exec() == QDialog::Accepted )
{
Expand Down Expand Up @@ -852,7 +860,7 @@ void QgsGraduatedSymbolRendererV2Widget::labelFormatChanged()
{
QgsRendererRangeV2LabelFormat labelFormat = QgsRendererRangeV2LabelFormat(
txtFormat->text(),
spinDecimalPlaces->value(),
spinPrecision->value(),
cbxTrimTrailingZeroes->isChecked() );
mRenderer->setLabelFormat( labelFormat, true );
mModel->updateLabels();
Expand Down
16 changes: 12 additions & 4 deletions src/ui/qgsgraduatedsymbolrendererv2widget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,18 @@
<item row="6" column="3">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QSpinBox" name="spinDecimalPlaces">
<widget class="QSpinBox" name="spinPrecision">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Precision of upper and lower values in label text.
Positive is number of decimal places
Negative rounds to powers of 10</string>
</property>
<property name="minimum">
<number>0</number>
</property>
Expand All @@ -42,6 +47,9 @@
</item>
<item>
<widget class="QCheckBox" name="cbxTrimTrailingZeroes">
<property name="toolTip">
<string>Check to remove trailing zeroes after the decimal point from the upper and lower values in the legend.</string>
</property>
<property name="text">
<string>Trim</string>
</property>
Expand Down Expand Up @@ -240,13 +248,13 @@ Use &quot;%1&quot; for the lower bound of the classification, and &quot;%2&quot;
<item row="6" column="2">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Decimal places</string>
<string>Precision</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>spinDecimalPlaces</cstring>
<cstring>spinPrecision</cstring>
</property>
</widget>
</item>
Expand Down Expand Up @@ -361,7 +369,7 @@ Use &quot;%1&quot; for the lower bound of the classification, and &quot;%2&quot;
<tabstop>cbxInvertedColorRamp</tabstop>
<tabstop>cboGraduatedMode</tabstop>
<tabstop>txtFormat</tabstop>
<tabstop>spinDecimalPlaces</tabstop>
<tabstop>spinPrecision</tabstop>
<tabstop>cbxTrimTrailingZeroes</tabstop>
<tabstop>viewGraduated</tabstop>
<tabstop>btnGraduatedClassify</tabstop>
Expand Down

0 comments on commit 21ddf12

Please sign in to comment.