Skip to content

Commit

Permalink
Modularize distance and area formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Mar 8, 2017
1 parent 2c82db5 commit 56163e2
Show file tree
Hide file tree
Showing 8 changed files with 530 additions and 233 deletions.
1 change: 1 addition & 0 deletions python/core/qgsdistancearea.sip
Expand Up @@ -6,6 +6,7 @@ class QgsDistanceArea
%End

public:

//! Constructor
QgsDistanceArea();

Expand Down
19 changes: 19 additions & 0 deletions python/core/qgsunittypes.sip
Expand Up @@ -11,6 +11,17 @@ class QgsUnitTypes
%End

public:
struct DistanceValue
{
double value;
QgsUnitTypes::DistanceUnit unit;
};

struct AreaValue
{
double value;
QgsUnitTypes::AreaUnit unit;
};

//! Units of distance
enum DistanceUnit
Expand Down Expand Up @@ -191,6 +202,14 @@ class QgsUnitTypes
*/
static QString formatAngle( double angle, int decimals, AngleUnit unit );

static QgsUnitTypes::DistanceValue scaledDistance( double distance, QgsUnitTypes::DistanceUnit unit, int decimals, bool keepBaseUnit = false );

static QgsUnitTypes::AreaValue scaledArea( double area, QgsUnitTypes::AreaUnit unit, int decimals, bool keepBaseUnit = false );

static QString formatDistance( double distance, int decimals, QgsUnitTypes::DistanceUnit unit, bool keepBaseUnit = false );

static QString formatArea( double area, int decimals, QgsUnitTypes::AreaUnit unit, bool keepBaseUnit = false );

// RENDER UNITS

/** Encodes a render unit to a string.
Expand Down
11 changes: 11 additions & 0 deletions src/core/qgis.h
Expand Up @@ -233,6 +233,17 @@ inline double qgsRound( double x )
return x < 0.0 ? std::ceil( x - 0.5 ) : std::floor( x + 0.5 );
}

/**
* Returns a double \a number, rounded (as close as possible) to the specified number of \a places.
*
* @note Added in QGIS 3.0
*/
inline double qgsRound( double number, double places )
{
int scaleFactor = pow( 10, places );
return static_cast<double>( static_cast<qlonglong>( number * scaleFactor + 0.5 ) ) / scaleFactor;
}

/** Converts a string to a double in a permissive way, e.g., allowing for incorrect
* numbers of digits between thousand separators
* @param string string to convert
Expand Down
232 changes: 2 additions & 230 deletions src/core/qgsdistancearea.cpp
Expand Up @@ -981,240 +981,12 @@ double QgsDistanceArea::computePolygonFlatArea( const QList<QgsPoint> &points )

QString QgsDistanceArea::formatDistance( double distance, int decimals, QgsUnitTypes::DistanceUnit unit, bool keepBaseUnit )
{
QString unitLabel;

switch ( unit )
{
case QgsUnitTypes::DistanceMeters:
if ( keepBaseUnit || qAbs( distance ) == 0.0 )
{
unitLabel = QObject::tr( " m" );
}
else if ( qAbs( distance ) > 1000.0 )
{
unitLabel = QObject::tr( " km" );
distance = distance / 1000;
}
else if ( qAbs( distance ) < 0.01 )
{
unitLabel = QObject::tr( " mm" );
distance = distance * 1000;
}
else if ( qAbs( distance ) < 0.1 )
{
unitLabel = QObject::tr( " cm" );
distance = distance * 100;
}
else
{
unitLabel = QObject::tr( " m" );
}
break;

case QgsUnitTypes::DistanceKilometers:
if ( keepBaseUnit || qAbs( distance ) >= 1.0 )
{
unitLabel = QObject::tr( " km" );
}
else
{
unitLabel = QObject::tr( " m" );
distance = distance * 1000;
}
break;

case QgsUnitTypes::DistanceFeet:
if ( qAbs( distance ) <= 5280.0 || keepBaseUnit )
{
unitLabel = QObject::tr( " ft" );
}
else
{
unitLabel = QObject::tr( " mi" );
distance /= 5280.0;
}
break;

case QgsUnitTypes::DistanceYards:
if ( qAbs( distance ) <= 1760.0 || keepBaseUnit )
{
unitLabel = QObject::tr( " yd" );
}
else
{
unitLabel = QObject::tr( " mi" );
distance /= 1760.0;
}
break;

case QgsUnitTypes::DistanceMiles:
if ( qAbs( distance ) >= 1.0 || keepBaseUnit )
{
unitLabel = QObject::tr( " mi" );
}
else
{
unitLabel = QObject::tr( " ft" );
distance *= 5280.0;
}
break;

case QgsUnitTypes::DistanceNauticalMiles:
unitLabel = QObject::tr( " NM" );
break;

case QgsUnitTypes::DistanceDegrees:

if ( qAbs( distance ) == 1.0 )
unitLabel = QObject::tr( " degree" );
else
unitLabel = QObject::tr( " degrees" );
break;

case QgsUnitTypes::DistanceUnknownUnit:
unitLabel.clear();
break;
default:
QgsDebugMsg( QString( "Error: not picked up map units - actual value = %1" ).arg( unit ) );
break;
}

return QStringLiteral( "%L1%2" ).arg( distance, 0, 'f', decimals ).arg( unitLabel );
return QgsUnitTypes::formatDistance( distance, decimals, unit, keepBaseUnit );
}

QString QgsDistanceArea::formatArea( double area, int decimals, QgsUnitTypes::AreaUnit unit, bool keepBaseUnit )
{
QString unitLabel;

switch ( unit )
{
case QgsUnitTypes::AreaSquareMeters:
{
if ( keepBaseUnit )
{
unitLabel = QObject::trUtf8( "" );
}
else if ( qAbs( area ) > QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareKilometers, QgsUnitTypes::AreaSquareMeters ) )
{
unitLabel = QObject::trUtf8( " km²" );
area = area * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareMeters, QgsUnitTypes::AreaSquareKilometers );
}
else if ( qAbs( area ) > QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaHectares, QgsUnitTypes::AreaSquareMeters ) )
{
unitLabel = QObject::tr( " ha" );
area = area * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareMeters, QgsUnitTypes::AreaHectares );
}
else
{
unitLabel = QObject::trUtf8( "" );
}
break;
}

case QgsUnitTypes::AreaSquareKilometers:
{
unitLabel = QObject::trUtf8( " km²" );
break;
}

case QgsUnitTypes::AreaSquareFeet:
{
if ( keepBaseUnit )
{
unitLabel = QObject::trUtf8( " ft²" );
}
else if ( qAbs( area ) > QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareMiles, QgsUnitTypes::AreaSquareFeet ) )
{
unitLabel = QObject::trUtf8( " mi²" );
area = area * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareFeet, QgsUnitTypes::AreaSquareMiles );
}
else
{
unitLabel = QObject::trUtf8( " ft²" );
}
break;
}

case QgsUnitTypes::AreaSquareYards:
{
if ( keepBaseUnit )
{
unitLabel = QObject::trUtf8( " yd²" );
}
else if ( qAbs( area ) > QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareMiles, QgsUnitTypes::AreaSquareYards ) )
{
unitLabel = QObject::trUtf8( " mi²" );
area = area * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareYards, QgsUnitTypes::AreaSquareMiles );
}
else
{
unitLabel = QObject::trUtf8( " yd²" );
}
break;
}

case QgsUnitTypes::AreaSquareMiles:
{
unitLabel = QObject::trUtf8( " mi²" );
break;
}

case QgsUnitTypes::AreaHectares:
{
if ( keepBaseUnit )
{
unitLabel = QObject::trUtf8( " ha" );
}
else if ( qAbs( area ) > QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareKilometers, QgsUnitTypes::AreaHectares ) )
{
unitLabel = QObject::trUtf8( " km²" );
area = area * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaHectares, QgsUnitTypes::AreaSquareKilometers );
}
else
{
unitLabel = QObject::trUtf8( " ha" );
}
break;
}

case QgsUnitTypes::AreaAcres:
{
if ( keepBaseUnit )
{
unitLabel = QObject::trUtf8( " ac" );
}
else if ( qAbs( area ) > QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareMiles, QgsUnitTypes::AreaAcres ) )
{
unitLabel = QObject::trUtf8( " mi²" );
area = area * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaAcres, QgsUnitTypes::AreaSquareMiles );
}
else
{
unitLabel = QObject::trUtf8( " ac" );
}
break;
}

case QgsUnitTypes::AreaSquareNauticalMiles:
{
unitLabel = QObject::trUtf8( " nm²" );
break;
}

case QgsUnitTypes::AreaSquareDegrees:
{
unitLabel = QObject::tr( " sq.deg." );
break;
}

case QgsUnitTypes::AreaUnknownUnit:
{
unitLabel.clear();
break;
}
}

return QStringLiteral( "%L1%2" ).arg( area, 0, 'f', decimals ).arg( unitLabel );
return QgsUnitTypes::formatArea( area, decimals, unit, keepBaseUnit );
}

double QgsDistanceArea::convertLengthMeasurement( double length, QgsUnitTypes::DistanceUnit toUnits ) const
Expand Down
1 change: 1 addition & 0 deletions src/core/qgsdistancearea.h
Expand Up @@ -39,6 +39,7 @@ General purpose distance and area calculator.
class CORE_EXPORT QgsDistanceArea
{
public:

//! Constructor
QgsDistanceArea();

Expand Down

0 comments on commit 56163e2

Please sign in to comment.