Skip to content

Commit 56163e2

Browse files
committed
Modularize distance and area formatting
1 parent 2c82db5 commit 56163e2

File tree

8 files changed

+530
-233
lines changed

8 files changed

+530
-233
lines changed

python/core/qgsdistancearea.sip

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class QgsDistanceArea
66
%End
77

88
public:
9+
910
//! Constructor
1011
QgsDistanceArea();
1112

python/core/qgsunittypes.sip

+19
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@ class QgsUnitTypes
1111
%End
1212

1313
public:
14+
struct DistanceValue
15+
{
16+
double value;
17+
QgsUnitTypes::DistanceUnit unit;
18+
};
19+
20+
struct AreaValue
21+
{
22+
double value;
23+
QgsUnitTypes::AreaUnit unit;
24+
};
1425

1526
//! Units of distance
1627
enum DistanceUnit
@@ -191,6 +202,14 @@ class QgsUnitTypes
191202
*/
192203
static QString formatAngle( double angle, int decimals, AngleUnit unit );
193204

205+
static QgsUnitTypes::DistanceValue scaledDistance( double distance, QgsUnitTypes::DistanceUnit unit, int decimals, bool keepBaseUnit = false );
206+
207+
static QgsUnitTypes::AreaValue scaledArea( double area, QgsUnitTypes::AreaUnit unit, int decimals, bool keepBaseUnit = false );
208+
209+
static QString formatDistance( double distance, int decimals, QgsUnitTypes::DistanceUnit unit, bool keepBaseUnit = false );
210+
211+
static QString formatArea( double area, int decimals, QgsUnitTypes::AreaUnit unit, bool keepBaseUnit = false );
212+
194213
// RENDER UNITS
195214

196215
/** Encodes a render unit to a string.

src/core/qgis.h

+11
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,17 @@ inline double qgsRound( double x )
233233
return x < 0.0 ? std::ceil( x - 0.5 ) : std::floor( x + 0.5 );
234234
}
235235

236+
/**
237+
* Returns a double \a number, rounded (as close as possible) to the specified number of \a places.
238+
*
239+
* @note Added in QGIS 3.0
240+
*/
241+
inline double qgsRound( double number, double places )
242+
{
243+
int scaleFactor = pow( 10, places );
244+
return static_cast<double>( static_cast<qlonglong>( number * scaleFactor + 0.5 ) ) / scaleFactor;
245+
}
246+
236247
/** Converts a string to a double in a permissive way, e.g., allowing for incorrect
237248
* numbers of digits between thousand separators
238249
* @param string string to convert

src/core/qgsdistancearea.cpp

+2-230
Original file line numberDiff line numberDiff line change
@@ -981,240 +981,12 @@ double QgsDistanceArea::computePolygonFlatArea( const QList<QgsPoint> &points )
981981

982982
QString QgsDistanceArea::formatDistance( double distance, int decimals, QgsUnitTypes::DistanceUnit unit, bool keepBaseUnit )
983983
{
984-
QString unitLabel;
985-
986-
switch ( unit )
987-
{
988-
case QgsUnitTypes::DistanceMeters:
989-
if ( keepBaseUnit || qAbs( distance ) == 0.0 )
990-
{
991-
unitLabel = QObject::tr( " m" );
992-
}
993-
else if ( qAbs( distance ) > 1000.0 )
994-
{
995-
unitLabel = QObject::tr( " km" );
996-
distance = distance / 1000;
997-
}
998-
else if ( qAbs( distance ) < 0.01 )
999-
{
1000-
unitLabel = QObject::tr( " mm" );
1001-
distance = distance * 1000;
1002-
}
1003-
else if ( qAbs( distance ) < 0.1 )
1004-
{
1005-
unitLabel = QObject::tr( " cm" );
1006-
distance = distance * 100;
1007-
}
1008-
else
1009-
{
1010-
unitLabel = QObject::tr( " m" );
1011-
}
1012-
break;
1013-
1014-
case QgsUnitTypes::DistanceKilometers:
1015-
if ( keepBaseUnit || qAbs( distance ) >= 1.0 )
1016-
{
1017-
unitLabel = QObject::tr( " km" );
1018-
}
1019-
else
1020-
{
1021-
unitLabel = QObject::tr( " m" );
1022-
distance = distance * 1000;
1023-
}
1024-
break;
1025-
1026-
case QgsUnitTypes::DistanceFeet:
1027-
if ( qAbs( distance ) <= 5280.0 || keepBaseUnit )
1028-
{
1029-
unitLabel = QObject::tr( " ft" );
1030-
}
1031-
else
1032-
{
1033-
unitLabel = QObject::tr( " mi" );
1034-
distance /= 5280.0;
1035-
}
1036-
break;
1037-
1038-
case QgsUnitTypes::DistanceYards:
1039-
if ( qAbs( distance ) <= 1760.0 || keepBaseUnit )
1040-
{
1041-
unitLabel = QObject::tr( " yd" );
1042-
}
1043-
else
1044-
{
1045-
unitLabel = QObject::tr( " mi" );
1046-
distance /= 1760.0;
1047-
}
1048-
break;
1049-
1050-
case QgsUnitTypes::DistanceMiles:
1051-
if ( qAbs( distance ) >= 1.0 || keepBaseUnit )
1052-
{
1053-
unitLabel = QObject::tr( " mi" );
1054-
}
1055-
else
1056-
{
1057-
unitLabel = QObject::tr( " ft" );
1058-
distance *= 5280.0;
1059-
}
1060-
break;
1061-
1062-
case QgsUnitTypes::DistanceNauticalMiles:
1063-
unitLabel = QObject::tr( " NM" );
1064-
break;
1065-
1066-
case QgsUnitTypes::DistanceDegrees:
1067-
1068-
if ( qAbs( distance ) == 1.0 )
1069-
unitLabel = QObject::tr( " degree" );
1070-
else
1071-
unitLabel = QObject::tr( " degrees" );
1072-
break;
1073-
1074-
case QgsUnitTypes::DistanceUnknownUnit:
1075-
unitLabel.clear();
1076-
break;
1077-
default:
1078-
QgsDebugMsg( QString( "Error: not picked up map units - actual value = %1" ).arg( unit ) );
1079-
break;
1080-
}
1081-
1082-
return QStringLiteral( "%L1%2" ).arg( distance, 0, 'f', decimals ).arg( unitLabel );
984+
return QgsUnitTypes::formatDistance( distance, decimals, unit, keepBaseUnit );
1083985
}
1084986

1085987
QString QgsDistanceArea::formatArea( double area, int decimals, QgsUnitTypes::AreaUnit unit, bool keepBaseUnit )
1086988
{
1087-
QString unitLabel;
1088-
1089-
switch ( unit )
1090-
{
1091-
case QgsUnitTypes::AreaSquareMeters:
1092-
{
1093-
if ( keepBaseUnit )
1094-
{
1095-
unitLabel = QObject::trUtf8( "" );
1096-
}
1097-
else if ( qAbs( area ) > QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareKilometers, QgsUnitTypes::AreaSquareMeters ) )
1098-
{
1099-
unitLabel = QObject::trUtf8( " km²" );
1100-
area = area * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareMeters, QgsUnitTypes::AreaSquareKilometers );
1101-
}
1102-
else if ( qAbs( area ) > QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaHectares, QgsUnitTypes::AreaSquareMeters ) )
1103-
{
1104-
unitLabel = QObject::tr( " ha" );
1105-
area = area * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareMeters, QgsUnitTypes::AreaHectares );
1106-
}
1107-
else
1108-
{
1109-
unitLabel = QObject::trUtf8( "" );
1110-
}
1111-
break;
1112-
}
1113-
1114-
case QgsUnitTypes::AreaSquareKilometers:
1115-
{
1116-
unitLabel = QObject::trUtf8( " km²" );
1117-
break;
1118-
}
1119-
1120-
case QgsUnitTypes::AreaSquareFeet:
1121-
{
1122-
if ( keepBaseUnit )
1123-
{
1124-
unitLabel = QObject::trUtf8( " ft²" );
1125-
}
1126-
else if ( qAbs( area ) > QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareMiles, QgsUnitTypes::AreaSquareFeet ) )
1127-
{
1128-
unitLabel = QObject::trUtf8( " mi²" );
1129-
area = area * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareFeet, QgsUnitTypes::AreaSquareMiles );
1130-
}
1131-
else
1132-
{
1133-
unitLabel = QObject::trUtf8( " ft²" );
1134-
}
1135-
break;
1136-
}
1137-
1138-
case QgsUnitTypes::AreaSquareYards:
1139-
{
1140-
if ( keepBaseUnit )
1141-
{
1142-
unitLabel = QObject::trUtf8( " yd²" );
1143-
}
1144-
else if ( qAbs( area ) > QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareMiles, QgsUnitTypes::AreaSquareYards ) )
1145-
{
1146-
unitLabel = QObject::trUtf8( " mi²" );
1147-
area = area * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareYards, QgsUnitTypes::AreaSquareMiles );
1148-
}
1149-
else
1150-
{
1151-
unitLabel = QObject::trUtf8( " yd²" );
1152-
}
1153-
break;
1154-
}
1155-
1156-
case QgsUnitTypes::AreaSquareMiles:
1157-
{
1158-
unitLabel = QObject::trUtf8( " mi²" );
1159-
break;
1160-
}
1161-
1162-
case QgsUnitTypes::AreaHectares:
1163-
{
1164-
if ( keepBaseUnit )
1165-
{
1166-
unitLabel = QObject::trUtf8( " ha" );
1167-
}
1168-
else if ( qAbs( area ) > QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareKilometers, QgsUnitTypes::AreaHectares ) )
1169-
{
1170-
unitLabel = QObject::trUtf8( " km²" );
1171-
area = area * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaHectares, QgsUnitTypes::AreaSquareKilometers );
1172-
}
1173-
else
1174-
{
1175-
unitLabel = QObject::trUtf8( " ha" );
1176-
}
1177-
break;
1178-
}
1179-
1180-
case QgsUnitTypes::AreaAcres:
1181-
{
1182-
if ( keepBaseUnit )
1183-
{
1184-
unitLabel = QObject::trUtf8( " ac" );
1185-
}
1186-
else if ( qAbs( area ) > QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaSquareMiles, QgsUnitTypes::AreaAcres ) )
1187-
{
1188-
unitLabel = QObject::trUtf8( " mi²" );
1189-
area = area * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaAcres, QgsUnitTypes::AreaSquareMiles );
1190-
}
1191-
else
1192-
{
1193-
unitLabel = QObject::trUtf8( " ac" );
1194-
}
1195-
break;
1196-
}
1197-
1198-
case QgsUnitTypes::AreaSquareNauticalMiles:
1199-
{
1200-
unitLabel = QObject::trUtf8( " nm²" );
1201-
break;
1202-
}
1203-
1204-
case QgsUnitTypes::AreaSquareDegrees:
1205-
{
1206-
unitLabel = QObject::tr( " sq.deg." );
1207-
break;
1208-
}
1209-
1210-
case QgsUnitTypes::AreaUnknownUnit:
1211-
{
1212-
unitLabel.clear();
1213-
break;
1214-
}
1215-
}
1216-
1217-
return QStringLiteral( "%L1%2" ).arg( area, 0, 'f', decimals ).arg( unitLabel );
989+
return QgsUnitTypes::formatArea( area, decimals, unit, keepBaseUnit );
1218990
}
1219991

1220992
double QgsDistanceArea::convertLengthMeasurement( double length, QgsUnitTypes::DistanceUnit toUnits ) const

src/core/qgsdistancearea.h

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ General purpose distance and area calculator.
3939
class CORE_EXPORT QgsDistanceArea
4040
{
4141
public:
42+
4243
//! Constructor
4344
QgsDistanceArea();
4445

0 commit comments

Comments
 (0)