Skip to content

Commit

Permalink
Add area units to QgsUnitTypes (refs #13209)
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Feb 14, 2016
1 parent 85b51fd commit 17a29f9
Show file tree
Hide file tree
Showing 4 changed files with 470 additions and 3 deletions.
54 changes: 53 additions & 1 deletion python/core/qgsunittypes.sip
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@ class QgsUnitTypes
UnknownType, /*!< unknown unit type */
};

//! Units of area
enum AreaUnit
{
SquareMeters, /*!< square meters */
SquareKilometers, /*!< square kilometers */
SquareFeet, /*!< square feet */
SquareYards, /*!< square yards */
SquareMiles, /*!< square miles */
Hectares, /*!< hectares */
Acres, /*!< acres */
SquareDegrees, /*!< square degrees, for planar geographic CRS area measurements */
UnknownAreaUnit, /*!< unknown areal unit */
};

/** Returns the type for a distance unit.
*/
static DistanceUnitType unitType( QGis::UnitType unit );
Expand All @@ -42,7 +56,7 @@ class QgsUnitTypes

/** Returns a translated string representing a distance unit.
* @param unit unit to convert to string
* @see fromString()
* @see stringToDistanceUnit()
*/
static QString toString( QGis::UnitType unit );

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

/** Returns the type for an areal unit.
*/
static DistanceUnitType unitType( AreaUnit unit );

/** Encodes an areal unit to a string.
* @param unit unit to encode
* @returns encoded string
* @see decodeAreaUnit()
*/
static QString encodeUnit( AreaUnit unit );

/** Decodes an areal unit from a string.
* @param string string to decode
* @param ok optional boolean, will be set to true if string was converted successfully
* @returns decoded units
* @see encodeUnit()
*/
static AreaUnit decodeAreaUnit( const QString& string, bool *ok = 0 );

/** Returns a translated string representing an areal unit.
* @param unit unit to convert to string
* @see stringToAreaUnit()
*/
static QString toString( AreaUnit unit );

/** Converts a translated string to an areal unit.
* @param string string representing an areal unit
* @param ok optional boolean, will be set to true if string was converted successfully
* @see toString()
*/
static AreaUnit stringToAreaUnit( const QString& string, bool *ok = 0 );

/** Returns the conversion factor between the specified areal units.
* @param fromUnit area unit to convert from
* @param toUnit area unit to convert to
* @returns multiplication factor to convert between units
*/
static double fromUnitToUnitFactor( AreaUnit fromUnit, AreaUnit toUnit );

/** Encodes a symbol unit to a string.
* @param unit unit to encode
Expand Down
259 changes: 259 additions & 0 deletions src/core/qgsunittypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,29 @@ QgsUnitTypes::DistanceUnitType QgsUnitTypes::unitType( QGis::UnitType unit )
return UnknownType;
}

QgsUnitTypes::DistanceUnitType QgsUnitTypes::unitType( QgsUnitTypes::AreaUnit unit )
{
switch ( unit )
{
case SquareMeters:
case SquareKilometers:
case SquareFeet:
case SquareYards:
case SquareMiles:
case Hectares:
case Acres:
return Standard;

case SquareDegrees:
return Geographic;

case UnknownAreaUnit:
return UnknownType;
}

return UnknownType;
}

QString QgsUnitTypes::encodeUnit( QGis::UnitType unit )
{
switch ( unit )
Expand Down Expand Up @@ -203,6 +226,242 @@ double QgsUnitTypes::fromUnitToUnitFactor( QGis::UnitType fromUnit, QGis::UnitTy
return 1.0;
}

QString QgsUnitTypes::encodeUnit( QgsUnitTypes::AreaUnit unit )
{
switch ( unit )
{
case SquareMeters:
return "m2";
case SquareKilometers:
return "km2";
case SquareFeet:
return "ft2";
case SquareYards:
return "y2";
case SquareMiles:
return "mi2";
case Hectares:
return "ha";
case Acres:
return "ac";
case SquareDegrees:
return "deg2";
case UnknownAreaUnit:
return "<unknown>";
}
return QString();
}

QgsUnitTypes::AreaUnit QgsUnitTypes::decodeAreaUnit( const QString& string, bool* ok )
{
QString normalized = string.trimmed().toLower();

if ( ok )
*ok = true;

if ( normalized == encodeUnit( SquareMeters ) )
return SquareMeters;
if ( normalized == encodeUnit( SquareKilometers ) )
return SquareKilometers;
if ( normalized == encodeUnit( SquareFeet ) )
return SquareFeet;
if ( normalized == encodeUnit( SquareYards ) )
return SquareYards;
if ( normalized == encodeUnit( SquareMiles ) )
return SquareMiles;
if ( normalized == encodeUnit( Hectares ) )
return Hectares;
if ( normalized == encodeUnit( Acres ) )
return Acres;
if ( normalized == encodeUnit( SquareMiles ) )
return SquareMiles;
if ( normalized == encodeUnit( SquareDegrees ) )
return SquareDegrees;
if ( normalized == encodeUnit( UnknownAreaUnit ) )
return UnknownAreaUnit;

if ( ok )
*ok = false;

return UnknownAreaUnit;
}

QString QgsUnitTypes::toString( QgsUnitTypes::AreaUnit unit )
{
switch ( unit )
{
case SquareMeters:
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "square meters" );
case SquareKilometers:
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "square kilometers" );
case SquareFeet:
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "square feet" );
case SquareYards:
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "square yards" );
case SquareMiles:
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "square miles" );
case Hectares:
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "hectares" );
case Acres:
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "acres" );
case SquareDegrees:
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "square degrees" );
case UnknownAreaUnit:
return QCoreApplication::translate( "QgsUnitTypes::AreaUnit", "<unknown>" );
}
return QString();
}

QgsUnitTypes::AreaUnit QgsUnitTypes::stringToAreaUnit( const QString& string, bool* ok )
{
QString normalized = string.trimmed().toLower();

if ( ok )
*ok = true;

if ( normalized == toString( SquareMeters ) )
return SquareMeters;
if ( normalized == toString( SquareKilometers ) )
return SquareKilometers;
if ( normalized == toString( SquareFeet ) )
return SquareFeet;
if ( normalized == toString( SquareYards ) )
return SquareYards;
if ( normalized == toString( SquareMiles ) )
return SquareMiles;
if ( normalized == toString( Hectares ) )
return Hectares;
if ( normalized == toString( Acres ) )
return Acres;
if ( normalized == toString( SquareDegrees ) )
return SquareDegrees;
if ( normalized == toString( UnknownAreaUnit ) )
return UnknownAreaUnit;
if ( ok )
*ok = false;

return UnknownAreaUnit;
}

double QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::AreaUnit fromUnit, QgsUnitTypes::AreaUnit toUnit )
{
#define KM2_TO_M2 1000000.0
#define FT2_TO_M2 0.09290304
#define YD2_TO_M2 0.83612736
#define MI2_TO_M2 2589988.110336
#define HA_TO_M2 10000.0
#define AC_TO_FT2 43560.0
#define DEG2_TO_M2 12392029030.5

// Calculate the conversion factor between the specified units
if ( fromUnit != toUnit )
{
switch ( fromUnit )
{
case SquareMeters:
{
if ( toUnit == SquareKilometers ) return 1.0 / KM2_TO_M2;
if ( toUnit == SquareFeet ) return 1.0 / FT2_TO_M2;
if ( toUnit == SquareYards ) return 1.0 / YD2_TO_M2;
if ( toUnit == SquareMiles ) return 1.0 / MI2_TO_M2;
if ( toUnit == Hectares ) return 1.0 / HA_TO_M2;
if ( toUnit == Acres ) return 1.0 / AC_TO_FT2 / FT2_TO_M2;
if ( toUnit == SquareDegrees ) return 1.0 / DEG2_TO_M2;

break;
}
case SquareKilometers:
{
if ( toUnit == SquareMeters ) return KM2_TO_M2;
if ( toUnit == SquareFeet ) return KM2_TO_M2 / FT2_TO_M2 ;
if ( toUnit == SquareYards ) return KM2_TO_M2 / YD2_TO_M2;
if ( toUnit == SquareMiles ) return KM2_TO_M2 / MI2_TO_M2;
if ( toUnit == Hectares ) return KM2_TO_M2 / HA_TO_M2;
if ( toUnit == Acres ) return KM2_TO_M2 / AC_TO_FT2 / FT2_TO_M2 ;
if ( toUnit == SquareDegrees ) return KM2_TO_M2 / DEG2_TO_M2;

break;
}
case SquareFeet:
{
if ( toUnit == SquareMeters ) return FT2_TO_M2;
if ( toUnit == SquareKilometers ) return FT2_TO_M2 / KM2_TO_M2;
if ( toUnit == SquareYards ) return FT2_TO_M2 / YD2_TO_M2;
if ( toUnit == SquareMiles ) return FT2_TO_M2 / MI2_TO_M2;
if ( toUnit == Hectares ) return FT2_TO_M2 / HA_TO_M2;
if ( toUnit == Acres ) return 1.0 / AC_TO_FT2;
if ( toUnit == SquareDegrees ) return FT2_TO_M2 / DEG2_TO_M2;

break;
}

case SquareYards:
{
if ( toUnit == SquareMeters ) return YD2_TO_M2;
if ( toUnit == SquareKilometers ) return YD2_TO_M2 / KM2_TO_M2;
if ( toUnit == SquareFeet ) return YD2_TO_M2 / FT2_TO_M2;
if ( toUnit == SquareMiles ) return YD2_TO_M2 / MI2_TO_M2;
if ( toUnit == Hectares ) return YD2_TO_M2 / HA_TO_M2;
if ( toUnit == Acres ) return YD2_TO_M2 / FT2_TO_M2 / AC_TO_FT2;
if ( toUnit == SquareDegrees ) return YD2_TO_M2 / DEG2_TO_M2;
break;
}

case SquareMiles:
{
if ( toUnit == SquareMeters ) return MI2_TO_M2;
if ( toUnit == SquareKilometers ) return MI2_TO_M2 / KM2_TO_M2;
if ( toUnit == SquareFeet ) return MI2_TO_M2 / FT2_TO_M2;
if ( toUnit == SquareYards ) return MI2_TO_M2 / YD2_TO_M2;
if ( toUnit == Hectares ) return MI2_TO_M2 / HA_TO_M2;
if ( toUnit == Acres ) return MI2_TO_M2 / FT2_TO_M2 / AC_TO_FT2;
if ( toUnit == SquareDegrees ) return MI2_TO_M2 / DEG2_TO_M2;
break;
}

case Hectares:
{
if ( toUnit == SquareMeters ) return HA_TO_M2;
if ( toUnit == SquareKilometers ) return HA_TO_M2 / KM2_TO_M2;
if ( toUnit == SquareFeet ) return HA_TO_M2 / FT2_TO_M2;
if ( toUnit == SquareYards ) return HA_TO_M2 / YD2_TO_M2;
if ( toUnit == SquareMiles ) return HA_TO_M2 / MI2_TO_M2;
if ( toUnit == Acres ) return HA_TO_M2 / FT2_TO_M2 / AC_TO_FT2;
if ( toUnit == SquareDegrees ) return HA_TO_M2 / DEG2_TO_M2;
break;
}

case Acres:
{
if ( toUnit == SquareMeters ) return AC_TO_FT2 * FT2_TO_M2;
if ( toUnit == SquareKilometers ) return AC_TO_FT2 * FT2_TO_M2 / KM2_TO_M2;
if ( toUnit == SquareFeet ) return AC_TO_FT2;
if ( toUnit == SquareYards ) return AC_TO_FT2 * FT2_TO_M2 / YD2_TO_M2;
if ( toUnit == SquareMiles ) return AC_TO_FT2 * FT2_TO_M2 / MI2_TO_M2;
if ( toUnit == Hectares ) return AC_TO_FT2 * FT2_TO_M2 / HA_TO_M2;
if ( toUnit == SquareDegrees ) return AC_TO_FT2 * FT2_TO_M2 / DEG2_TO_M2;
break;
}

case SquareDegrees:
{
if ( toUnit == SquareMeters ) return DEG2_TO_M2;
if ( toUnit == SquareKilometers ) return DEG2_TO_M2 / KM2_TO_M2;
if ( toUnit == SquareFeet ) return DEG2_TO_M2 / FT2_TO_M2;
if ( toUnit == SquareYards ) return DEG2_TO_M2 / YD2_TO_M2;
if ( toUnit == SquareMiles ) return DEG2_TO_M2 / MI2_TO_M2;
if ( toUnit == Hectares ) return DEG2_TO_M2 / HA_TO_M2;
if ( toUnit == Acres ) return DEG2_TO_M2 / FT2_TO_M2 / AC_TO_FT2;
break;
}

case UnknownAreaUnit:
break;
}
}
return 1.0;
}

QString QgsUnitTypes::encodeUnit( QgsSymbolV2::OutputUnit unit )
{
switch ( unit )
Expand Down
Loading

0 comments on commit 17a29f9

Please sign in to comment.