Skip to content

Commit 17a29f9

Browse files
committed
Add area units to QgsUnitTypes (refs #13209)
1 parent 85b51fd commit 17a29f9

File tree

4 files changed

+470
-3
lines changed

4 files changed

+470
-3
lines changed

python/core/qgsunittypes.sip

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,20 @@ class QgsUnitTypes
2121
UnknownType, /*!< unknown unit type */
2222
};
2323

24+
//! Units of area
25+
enum AreaUnit
26+
{
27+
SquareMeters, /*!< square meters */
28+
SquareKilometers, /*!< square kilometers */
29+
SquareFeet, /*!< square feet */
30+
SquareYards, /*!< square yards */
31+
SquareMiles, /*!< square miles */
32+
Hectares, /*!< hectares */
33+
Acres, /*!< acres */
34+
SquareDegrees, /*!< square degrees, for planar geographic CRS area measurements */
35+
UnknownAreaUnit, /*!< unknown areal unit */
36+
};
37+
2438
/** Returns the type for a distance unit.
2539
*/
2640
static DistanceUnitType unitType( QGis::UnitType unit );
@@ -42,7 +56,7 @@ class QgsUnitTypes
4256

4357
/** Returns a translated string representing a distance unit.
4458
* @param unit unit to convert to string
45-
* @see fromString()
59+
* @see stringToDistanceUnit()
4660
*/
4761
static QString toString( QGis::UnitType unit );
4862

@@ -60,6 +74,44 @@ class QgsUnitTypes
6074
*/
6175
static double fromUnitToUnitFactor( QGis::UnitType fromUnit, QGis::UnitType toUnit );
6276

77+
/** Returns the type for an areal unit.
78+
*/
79+
static DistanceUnitType unitType( AreaUnit unit );
80+
81+
/** Encodes an areal unit to a string.
82+
* @param unit unit to encode
83+
* @returns encoded string
84+
* @see decodeAreaUnit()
85+
*/
86+
static QString encodeUnit( AreaUnit unit );
87+
88+
/** Decodes an areal unit from a string.
89+
* @param string string to decode
90+
* @param ok optional boolean, will be set to true if string was converted successfully
91+
* @returns decoded units
92+
* @see encodeUnit()
93+
*/
94+
static AreaUnit decodeAreaUnit( const QString& string, bool *ok = 0 );
95+
96+
/** Returns a translated string representing an areal unit.
97+
* @param unit unit to convert to string
98+
* @see stringToAreaUnit()
99+
*/
100+
static QString toString( AreaUnit unit );
101+
102+
/** Converts a translated string to an areal unit.
103+
* @param string string representing an areal unit
104+
* @param ok optional boolean, will be set to true if string was converted successfully
105+
* @see toString()
106+
*/
107+
static AreaUnit stringToAreaUnit( const QString& string, bool *ok = 0 );
108+
109+
/** Returns the conversion factor between the specified areal units.
110+
* @param fromUnit area unit to convert from
111+
* @param toUnit area unit to convert to
112+
* @returns multiplication factor to convert between units
113+
*/
114+
static double fromUnitToUnitFactor( AreaUnit fromUnit, AreaUnit toUnit );
63115

64116
/** Encodes a symbol unit to a string.
65117
* @param unit unit to encode

src/core/qgsunittypes.cpp

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,29 @@ QgsUnitTypes::DistanceUnitType QgsUnitTypes::unitType( QGis::UnitType unit )
4141
return UnknownType;
4242
}
4343

44+
QgsUnitTypes::DistanceUnitType QgsUnitTypes::unitType( QgsUnitTypes::AreaUnit unit )
45+
{
46+
switch ( unit )
47+
{
48+
case SquareMeters:
49+
case SquareKilometers:
50+
case SquareFeet:
51+
case SquareYards:
52+
case SquareMiles:
53+
case Hectares:
54+
case Acres:
55+
return Standard;
56+
57+
case SquareDegrees:
58+
return Geographic;
59+
60+
case UnknownAreaUnit:
61+
return UnknownType;
62+
}
63+
64+
return UnknownType;
65+
}
66+
4467
QString QgsUnitTypes::encodeUnit( QGis::UnitType unit )
4568
{
4669
switch ( unit )
@@ -203,6 +226,242 @@ double QgsUnitTypes::fromUnitToUnitFactor( QGis::UnitType fromUnit, QGis::UnitTy
203226
return 1.0;
204227
}
205228

229+
QString QgsUnitTypes::encodeUnit( QgsUnitTypes::AreaUnit unit )
230+
{
231+
switch ( unit )
232+
{
233+
case SquareMeters:
234+
return "m2";
235+
case SquareKilometers:
236+
return "km2";
237+
case SquareFeet:
238+
return "ft2";
239+
case SquareYards:
240+
return "y2";
241+
case SquareMiles:
242+
return "mi2";
243+
case Hectares:
244+
return "ha";
245+
case Acres:
246+
return "ac";
247+
case SquareDegrees:
248+
return "deg2";
249+
case UnknownAreaUnit:
250+
return "<unknown>";
251+
}
252+
return QString();
253+
}
254+
255+
QgsUnitTypes::AreaUnit QgsUnitTypes::decodeAreaUnit( const QString& string, bool* ok )
256+
{
257+
QString normalized = string.trimmed().toLower();
258+
259+
if ( ok )
260+
*ok = true;
261+
262+
if ( normalized == encodeUnit( SquareMeters ) )
263+
return SquareMeters;
264+
if ( normalized == encodeUnit( SquareKilometers ) )
265+
return SquareKilometers;
266+
if ( normalized == encodeUnit( SquareFeet ) )
267+
return SquareFeet;
268+
if ( normalized == encodeUnit( SquareYards ) )
269+
return SquareYards;
270+
if ( normalized == encodeUnit( SquareMiles ) )
271+
return SquareMiles;
272+
if ( normalized == encodeUnit( Hectares ) )
273+
return Hectares;
274+
if ( normalized == encodeUnit( Acres ) )
275+
return Acres;
276+
if ( normalized == encodeUnit( SquareMiles ) )
277+
return SquareMiles;
278+
if ( normalized == encodeUnit( SquareDegrees ) )
279+
return SquareDegrees;
280+
if ( normalized == encodeUnit( UnknownAreaUnit ) )
281+
return UnknownAreaUnit;
282+
283+
if ( ok )
284+
*ok = false;
285+
286+
return UnknownAreaUnit;
287+
}
288+
289+
QString QgsUnitTypes::toString( QgsUnitTypes::AreaUnit unit )
290+
{
291+
switch ( unit )
292+
{
293+
case SquareMeters:
294+
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "square meters" );
295+
case SquareKilometers:
296+
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "square kilometers" );
297+
case SquareFeet:
298+
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "square feet" );
299+
case SquareYards:
300+
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "square yards" );
301+
case SquareMiles:
302+
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "square miles" );
303+
case Hectares:
304+
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "hectares" );
305+
case Acres:
306+
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "acres" );
307+
case SquareDegrees:
308+
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "square degrees" );
309+
case UnknownAreaUnit:
310+
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "<unknown>" );
311+
}
312+
return QString();
313+
}
314+
315+
QgsUnitTypes::AreaUnit QgsUnitTypes::stringToAreaUnit( const QString& string, bool* ok )
316+
{
317+
QString normalized = string.trimmed().toLower();
318+
319+
if ( ok )
320+
*ok = true;
321+
322+
if ( normalized == toString( SquareMeters ) )
323+
return SquareMeters;
324+
if ( normalized == toString( SquareKilometers ) )
325+
return SquareKilometers;
326+
if ( normalized == toString( SquareFeet ) )
327+
return SquareFeet;
328+
if ( normalized == toString( SquareYards ) )
329+
return SquareYards;
330+
if ( normalized == toString( SquareMiles ) )
331+
return SquareMiles;
332+
if ( normalized == toString( Hectares ) )
333+
return Hectares;
334+
if ( normalized == toString( Acres ) )
335+
return Acres;
336+
if ( normalized == toString( SquareDegrees ) )
337+
return SquareDegrees;
338+
if ( normalized == toString( UnknownAreaUnit ) )
339+
return UnknownAreaUnit;
340+
if ( ok )
341+
*ok = false;
342+
343+
return UnknownAreaUnit;
344+
}
345+
346+
double QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaUnit fromUnit, QgsUnitTypes::AreaUnit toUnit )
347+
{
348+
#define KM2_TO_M2 1000000.0
349+
#define FT2_TO_M2 0.09290304
350+
#define YD2_TO_M2 0.83612736
351+
#define MI2_TO_M2 2589988.110336
352+
#define HA_TO_M2 10000.0
353+
#define AC_TO_FT2 43560.0
354+
#define DEG2_TO_M2 12392029030.5
355+
356+
// Calculate the conversion factor between the specified units
357+
if ( fromUnit != toUnit )
358+
{
359+
switch ( fromUnit )
360+
{
361+
case SquareMeters:
362+
{
363+
if ( toUnit == SquareKilometers ) return 1.0 / KM2_TO_M2;
364+
if ( toUnit == SquareFeet ) return 1.0 / FT2_TO_M2;
365+
if ( toUnit == SquareYards ) return 1.0 / YD2_TO_M2;
366+
if ( toUnit == SquareMiles ) return 1.0 / MI2_TO_M2;
367+
if ( toUnit == Hectares ) return 1.0 / HA_TO_M2;
368+
if ( toUnit == Acres ) return 1.0 / AC_TO_FT2 / FT2_TO_M2;
369+
if ( toUnit == SquareDegrees ) return 1.0 / DEG2_TO_M2;
370+
371+
break;
372+
}
373+
case SquareKilometers:
374+
{
375+
if ( toUnit == SquareMeters ) return KM2_TO_M2;
376+
if ( toUnit == SquareFeet ) return KM2_TO_M2 / FT2_TO_M2 ;
377+
if ( toUnit == SquareYards ) return KM2_TO_M2 / YD2_TO_M2;
378+
if ( toUnit == SquareMiles ) return KM2_TO_M2 / MI2_TO_M2;
379+
if ( toUnit == Hectares ) return KM2_TO_M2 / HA_TO_M2;
380+
if ( toUnit == Acres ) return KM2_TO_M2 / AC_TO_FT2 / FT2_TO_M2 ;
381+
if ( toUnit == SquareDegrees ) return KM2_TO_M2 / DEG2_TO_M2;
382+
383+
break;
384+
}
385+
case SquareFeet:
386+
{
387+
if ( toUnit == SquareMeters ) return FT2_TO_M2;
388+
if ( toUnit == SquareKilometers ) return FT2_TO_M2 / KM2_TO_M2;
389+
if ( toUnit == SquareYards ) return FT2_TO_M2 / YD2_TO_M2;
390+
if ( toUnit == SquareMiles ) return FT2_TO_M2 / MI2_TO_M2;
391+
if ( toUnit == Hectares ) return FT2_TO_M2 / HA_TO_M2;
392+
if ( toUnit == Acres ) return 1.0 / AC_TO_FT2;
393+
if ( toUnit == SquareDegrees ) return FT2_TO_M2 / DEG2_TO_M2;
394+
395+
break;
396+
}
397+
398+
case SquareYards:
399+
{
400+
if ( toUnit == SquareMeters ) return YD2_TO_M2;
401+
if ( toUnit == SquareKilometers ) return YD2_TO_M2 / KM2_TO_M2;
402+
if ( toUnit == SquareFeet ) return YD2_TO_M2 / FT2_TO_M2;
403+
if ( toUnit == SquareMiles ) return YD2_TO_M2 / MI2_TO_M2;
404+
if ( toUnit == Hectares ) return YD2_TO_M2 / HA_TO_M2;
405+
if ( toUnit == Acres ) return YD2_TO_M2 / FT2_TO_M2 / AC_TO_FT2;
406+
if ( toUnit == SquareDegrees ) return YD2_TO_M2 / DEG2_TO_M2;
407+
break;
408+
}
409+
410+
case SquareMiles:
411+
{
412+
if ( toUnit == SquareMeters ) return MI2_TO_M2;
413+
if ( toUnit == SquareKilometers ) return MI2_TO_M2 / KM2_TO_M2;
414+
if ( toUnit == SquareFeet ) return MI2_TO_M2 / FT2_TO_M2;
415+
if ( toUnit == SquareYards ) return MI2_TO_M2 / YD2_TO_M2;
416+
if ( toUnit == Hectares ) return MI2_TO_M2 / HA_TO_M2;
417+
if ( toUnit == Acres ) return MI2_TO_M2 / FT2_TO_M2 / AC_TO_FT2;
418+
if ( toUnit == SquareDegrees ) return MI2_TO_M2 / DEG2_TO_M2;
419+
break;
420+
}
421+
422+
case Hectares:
423+
{
424+
if ( toUnit == SquareMeters ) return HA_TO_M2;
425+
if ( toUnit == SquareKilometers ) return HA_TO_M2 / KM2_TO_M2;
426+
if ( toUnit == SquareFeet ) return HA_TO_M2 / FT2_TO_M2;
427+
if ( toUnit == SquareYards ) return HA_TO_M2 / YD2_TO_M2;
428+
if ( toUnit == SquareMiles ) return HA_TO_M2 / MI2_TO_M2;
429+
if ( toUnit == Acres ) return HA_TO_M2 / FT2_TO_M2 / AC_TO_FT2;
430+
if ( toUnit == SquareDegrees ) return HA_TO_M2 / DEG2_TO_M2;
431+
break;
432+
}
433+
434+
case Acres:
435+
{
436+
if ( toUnit == SquareMeters ) return AC_TO_FT2 * FT2_TO_M2;
437+
if ( toUnit == SquareKilometers ) return AC_TO_FT2 * FT2_TO_M2 / KM2_TO_M2;
438+
if ( toUnit == SquareFeet ) return AC_TO_FT2;
439+
if ( toUnit == SquareYards ) return AC_TO_FT2 * FT2_TO_M2 / YD2_TO_M2;
440+
if ( toUnit == SquareMiles ) return AC_TO_FT2 * FT2_TO_M2 / MI2_TO_M2;
441+
if ( toUnit == Hectares ) return AC_TO_FT2 * FT2_TO_M2 / HA_TO_M2;
442+
if ( toUnit == SquareDegrees ) return AC_TO_FT2 * FT2_TO_M2 / DEG2_TO_M2;
443+
break;
444+
}
445+
446+
case SquareDegrees:
447+
{
448+
if ( toUnit == SquareMeters ) return DEG2_TO_M2;
449+
if ( toUnit == SquareKilometers ) return DEG2_TO_M2 / KM2_TO_M2;
450+
if ( toUnit == SquareFeet ) return DEG2_TO_M2 / FT2_TO_M2;
451+
if ( toUnit == SquareYards ) return DEG2_TO_M2 / YD2_TO_M2;
452+
if ( toUnit == SquareMiles ) return DEG2_TO_M2 / MI2_TO_M2;
453+
if ( toUnit == Hectares ) return DEG2_TO_M2 / HA_TO_M2;
454+
if ( toUnit == Acres ) return DEG2_TO_M2 / FT2_TO_M2 / AC_TO_FT2;
455+
break;
456+
}
457+
458+
case UnknownAreaUnit:
459+
break;
460+
}
461+
}
462+
return 1.0;
463+
}
464+
206465
QString QgsUnitTypes::encodeUnit( QgsSymbolV2::OutputUnit unit )
207466
{
208467
switch ( unit )

0 commit comments

Comments
 (0)