Add API for volume units to QgsUnitTypes

Complements the existing API for distance and area handling
This commit is contained in:
Nyall Dawson 2019-09-09 15:50:43 +10:00
parent 8e3caf39ab
commit c02686dbd0
5 changed files with 1101 additions and 0 deletions

View File

@ -2,6 +2,7 @@
QgsUnitTypes.SystemOfMeasurement.baseClass = QgsUnitTypes
QgsUnitTypes.DistanceUnit.baseClass = QgsUnitTypes
QgsUnitTypes.AreaUnit.baseClass = QgsUnitTypes
QgsUnitTypes.VolumeUnit.baseClass = QgsUnitTypes
QgsUnitTypes.AngleUnit.baseClass = QgsUnitTypes
QgsUnitTypes.RenderUnit.baseClass = QgsUnitTypes
QgsUnitTypes.LayoutUnit.baseClass = QgsUnitTypes

View File

@ -34,6 +34,14 @@ Helper functions for various unit types.
USCSSystem
};
enum UnitType
{
TypeDistance,
TypeArea,
TypeVolume,
TypeUnknown,
};
enum DistanceUnit
{
DistanceMeters,
@ -71,6 +79,21 @@ Helper functions for various unit types.
AreaUnknownUnit,
};
enum VolumeUnit
{
VolumeCubicMeters,
VolumeCubicFeet,
VolumeCubicYards,
VolumeBarrel,
VolumeCubicDecimeter,
VolumeLiters,
VolumeGallonUS,
VolumeCubicInch,
VolumeCubicCentimeter,
VolumeCubicDegrees,
VolumeUnknownUnit,
};
enum AngleUnit
{
AngleDegrees,
@ -132,6 +155,32 @@ Helper functions for various unit types.
typedef QList<QgsUnitTypes::RenderUnit> RenderUnitList;
static QString encodeUnitType( QgsUnitTypes::UnitType type );
%Docstring
Encodes a unit ``type`` to a string.
:return: encoded string
.. seealso:: :py:func:`decodeUnitType`
.. versionadded:: 3.10
%End
static QgsUnitTypes::UnitType decodeUnitType( const QString &string, bool *ok /Out/ = 0 );
%Docstring
Decodes a unit type from a ``string``.
:param string: string to decode
:return: - decoded unit type
- ok: boolean, will be set to ``True`` if string was converted successfully
.. seealso:: :py:func:`encodeUnitType`
.. versionadded:: 3.10
%End
static DistanceUnitType unitType( QgsUnitTypes::DistanceUnit unit );
%Docstring
@ -291,6 +340,105 @@ Converts an area unit to its corresponding distance unit, e.g., square meters to
:return: matching distance unit
.. versionadded:: 3.10
%End
static DistanceUnitType unitType( QgsUnitTypes::VolumeUnit unit );
%Docstring
Returns the type for an volume unit.
.. versionadded:: 3.10
%End
static QString encodeUnit( QgsUnitTypes::VolumeUnit unit );
%Docstring
Encodes a volume ``unit`` to a string.
:return: encoded string
.. seealso:: :py:func:`decodeVolumeUnit`
.. versionadded:: 3.10
%End
static VolumeUnit decodeVolumeUnit( const QString &string, bool *ok /Out/ = 0 );
%Docstring
Decodes a volume unit from a ``string``.
:param string: string to decode
:return: - decoded units
- ok: boolean, will be set to ``True`` if string was converted successfully
.. seealso:: :py:func:`encodeUnit`
.. versionadded:: 3.10
%End
static QString toString( QgsUnitTypes::VolumeUnit unit );
%Docstring
Returns a translated string representing a volume ``unit``.
.. seealso:: :py:func:`stringToVolumeUnit`
.. versionadded:: 3.10
%End
static QString toAbbreviatedString( QgsUnitTypes::VolumeUnit unit );
%Docstring
Returns a translated abbreviation representing a volume ``unit``.
.. seealso:: :py:func:`stringToVolumeUnit`
.. versionadded:: 3.10
%End
static VolumeUnit stringToVolumeUnit( const QString &string, bool *ok /Out/ = 0 );
%Docstring
Converts a translated`` ``string to a volume unit.
:param string: string representing a volume unit
:return: - the volume unit
- ok: boolean, will be set to ``True`` if string was converted successfully
.. seealso:: :py:func:`toString`
.. versionadded:: 3.10
%End
static double fromUnitToUnitFactor( QgsUnitTypes::VolumeUnit fromUnit, QgsUnitTypes::VolumeUnit toUnit );
%Docstring
Returns the conversion factor between the specified volume units.
:param fromUnit: volume unit to convert from
:param toUnit: volume unit to convert to
:return: multiplication factor to convert between units
.. versionadded:: 3.10
%End
static QgsUnitTypes::VolumeUnit distanceToVolumeUnit( QgsUnitTypes::DistanceUnit distanceUnit );
%Docstring
Converts a distance unit to its corresponding volume unit, e.g., meters to cubic meters
:param distanceUnit: distance unit to convert
:return: matching volume unit
.. versionadded:: 3.10
%End
static QgsUnitTypes::DistanceUnit volumeToDistanceUnit( QgsUnitTypes::VolumeUnit volumeUnit );
%Docstring
Converts a volume unit to its corresponding distance unit, e.g., cubic meters to meters
:param volumeUnit: volume unit to convert
:return: matching distance unit
.. versionadded:: 3.10
%End

View File

@ -23,6 +23,48 @@
* See details in QEP #17
****************************************************************************/
QString QgsUnitTypes::encodeUnitType( QgsUnitTypes::UnitType type )
{
switch ( type )
{
case TypeDistance:
return QStringLiteral( "distance" );
case TypeArea:
return QStringLiteral( "area" );
case TypeVolume:
return QStringLiteral( "volume" );
case TypeUnknown:
return QStringLiteral( "<unknown>" );
}
return QString();
}
QgsUnitTypes::UnitType QgsUnitTypes::decodeUnitType( const QString &string, bool *ok )
{
QString normalized = string.trimmed().toLower();
if ( ok )
*ok = true;
if ( normalized == encodeUnitType( TypeDistance ) )
return TypeDistance;
if ( normalized == encodeUnitType( TypeArea ) )
return TypeArea;
if ( normalized == encodeUnitType( TypeVolume ) )
return TypeVolume;
if ( normalized == encodeUnitType( TypeUnknown ) )
return TypeUnknown;
if ( ok )
*ok = false;
return TypeUnknown;
}
QgsUnitTypes::DistanceUnitType QgsUnitTypes::unitType( DistanceUnit unit )
{
switch ( unit )
@ -1204,6 +1246,506 @@ QgsUnitTypes::DistanceUnit QgsUnitTypes::areaToDistanceUnit( AreaUnit areaUnit )
return DistanceUnknownUnit;
}
QgsUnitTypes::VolumeUnit QgsUnitTypes::decodeVolumeUnit( const QString &string, bool *ok )
{
QString normalized = string.trimmed().toLower();
if ( ok )
*ok = true;
if ( normalized == encodeUnit( VolumeCubicMeters ) )
return VolumeCubicMeters;
if ( normalized == encodeUnit( VolumeCubicFeet ) )
return VolumeCubicFeet;
if ( normalized == encodeUnit( VolumeCubicYards ) )
return VolumeCubicYards;
if ( normalized == encodeUnit( VolumeBarrel ) )
return VolumeBarrel;
if ( normalized == encodeUnit( VolumeCubicDecimeter ) )
return VolumeCubicDecimeter;
if ( normalized == encodeUnit( VolumeLiters ) )
return VolumeLiters;
if ( normalized == encodeUnit( VolumeGallonUS ) )
return VolumeGallonUS;
if ( normalized == encodeUnit( VolumeCubicInch ) )
return VolumeCubicInch;
if ( normalized == encodeUnit( VolumeCubicCentimeter ) )
return VolumeCubicCentimeter;
if ( normalized == encodeUnit( VolumeCubicDegrees ) )
return VolumeCubicDegrees;
if ( normalized == encodeUnit( VolumeUnknownUnit ) )
return VolumeUnknownUnit;
if ( ok )
*ok = false;
return VolumeUnknownUnit;
}
QString QgsUnitTypes::toString( QgsUnitTypes::VolumeUnit unit )
{
switch ( unit )
{
case VolumeCubicMeters:
return QObject::tr( "cubic meters", "volume" );
case VolumeCubicFeet:
return QObject::tr( "cubic feet", "volume" );
case VolumeCubicYards:
return QObject::tr( "cubic yards", "volume" );
case VolumeBarrel:
return QObject::tr( "barrels", "volume" );
case VolumeCubicDecimeter:
return QObject::tr( "cubic decimeters", "volume" );
case VolumeLiters:
return QObject::tr( "liters", "volume" );
case VolumeGallonUS:
return QObject::tr( "gallons", "volume" );
case VolumeCubicInch:
return QObject::tr( "cubic inches", "volume" );
case VolumeCubicCentimeter:
return QObject::tr( "cubic centimeters", "volume" );
case VolumeCubicDegrees:
return QObject::tr( "cubic degrees", "volume" );
case VolumeUnknownUnit:
return QObject::tr( "<unknown>", "volume" );
}
return QString();
}
QString QgsUnitTypes::toAbbreviatedString( QgsUnitTypes::VolumeUnit unit )
{
switch ( unit )
{
case VolumeCubicMeters:
return QObject::tr( "", "volume" );
case VolumeCubicFeet:
return QObject::tr( "ft³", "volume" );
case VolumeCubicYards:
return QObject::tr( "yds³", "volume" );
case VolumeBarrel:
return QObject::tr( "bbl", "volume" );
case VolumeCubicDecimeter:
return QObject::tr( "dm³", "volume" );
case VolumeLiters:
return QObject::tr( "l", "volume" );
case VolumeGallonUS:
return QObject::tr( "gal", "volume" );
case VolumeCubicInch:
return QObject::tr( "in³", "volume" );
case VolumeCubicCentimeter:
return QObject::tr( "cm³", "volume" );
case VolumeCubicDegrees:
return QObject::tr( "deg³", "volume" );
case VolumeUnknownUnit:
return QObject::tr( "<unknown>", "volume" );
}
return QString();
}
QgsUnitTypes::VolumeUnit QgsUnitTypes::stringToVolumeUnit( const QString &string, bool *ok )
{
QString normalized = string.trimmed().toLower();
if ( ok )
*ok = true;
if ( normalized == toString( VolumeCubicMeters ) )
return VolumeCubicMeters;
if ( normalized == toString( VolumeCubicFeet ) )
return VolumeCubicFeet;
if ( normalized == toString( VolumeCubicYards ) )
return VolumeCubicYards;
if ( normalized == toString( VolumeBarrel ) )
return VolumeBarrel;
if ( normalized == toString( VolumeCubicDecimeter ) )
return VolumeCubicDecimeter;
if ( normalized == toString( VolumeLiters ) )
return VolumeLiters;
if ( normalized == toString( VolumeGallonUS ) )
return VolumeGallonUS;
if ( normalized == toString( VolumeCubicInch ) )
return VolumeCubicInch;
if ( normalized == toString( VolumeCubicCentimeter ) )
return VolumeCubicCentimeter;
if ( normalized == toString( VolumeCubicDegrees ) )
return VolumeCubicDegrees;
if ( normalized == toString( VolumeUnknownUnit ) )
return VolumeUnknownUnit;
if ( ok )
*ok = false;
return VolumeUnknownUnit;
}
#define DEG2_TO_M3 1379474361572186.2
double QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::VolumeUnit fromUnit, QgsUnitTypes::VolumeUnit toUnit )
{
switch ( fromUnit )
{
case VolumeCubicMeters:
{
switch ( toUnit )
{
case VolumeCubicMeters:
return 1.0;
case VolumeCubicFeet:
return 35.314666572222;
case VolumeCubicYards:
return 1.307950613786;
case VolumeBarrel:
return 6.2898107438466;
case VolumeCubicDecimeter:
return 1000;
case VolumeLiters:
return 1000;
case VolumeGallonUS:
return 264.17205124156;
case VolumeCubicInch:
return 61023.7438368;
case VolumeCubicCentimeter:
return 1000000;
case VolumeCubicDegrees:
return 1 / DEG2_TO_M3; // basically meaningless!
case VolumeUnknownUnit:
return 1.0;
}
break;
}
case VolumeCubicFeet:
{
switch ( toUnit )
{
case VolumeCubicMeters:
return 0.028316846592;
case VolumeCubicFeet:
return 1.0;
case VolumeCubicYards:
return 0.037037037;
case VolumeBarrel:
return 0.178107622;
case VolumeCubicDecimeter:
return 28.31685;
case VolumeLiters:
return 28.31685;
case VolumeGallonUS:
return 7.480519954;
case VolumeCubicInch:
return 1728.000629765;
case VolumeCubicCentimeter:
return 28316.85;
case VolumeCubicDegrees:
return 0.028316846592 / DEG2_TO_M3; // basically meaningless!
case VolumeUnknownUnit:
return 1.0;
}
break;
}
case VolumeCubicYards:
{
switch ( toUnit )
{
case VolumeCubicMeters:
return 0.764554900;
case VolumeCubicFeet:
return 26.999998234;
case VolumeCubicYards:
return 1.0;
case VolumeBarrel:
return 4.808905491;
case VolumeCubicDecimeter:
return 764.5549;
case VolumeLiters:
return 764.5549;
case VolumeGallonUS:
return 201.974025549;
case VolumeCubicInch:
return 46656.013952472;
case VolumeCubicCentimeter:
return 764554.9;
case VolumeCubicDegrees:
return 0.764554900 / DEG2_TO_M3; // basically meaningless!
case VolumeUnknownUnit:
return 1.0;
}
break;
}
case VolumeBarrel:
{
switch ( toUnit )
{
case VolumeCubicMeters:
return 0.158987300;
case VolumeCubicFeet:
return 5.614582837;
case VolumeCubicYards:
return 0.207947526;
case VolumeBarrel:
return 1.0;
case VolumeCubicDecimeter:
return 158.9873;
case VolumeLiters:
return 158.9873;
case VolumeGallonUS:
return 41.999998943;
case VolumeCubicInch:
return 9702.002677722;
case VolumeCubicCentimeter:
return 158987.3;
case VolumeCubicDegrees:
return 0.158987300 / DEG2_TO_M3; // basically meaningless!
case VolumeUnknownUnit:
return 1.0;
}
break;
}
case VolumeCubicDecimeter:
case VolumeLiters:
{
switch ( toUnit )
{
case VolumeCubicMeters:
return 0.001;
case VolumeCubicFeet:
return 0.035314662;
case VolumeCubicYards:
return 0.001307951;
case VolumeBarrel:
return 0.006289811;
case VolumeCubicDecimeter:
case VolumeLiters:
return 1.0;
case VolumeGallonUS:
return 0.264172037;
case VolumeCubicInch:
return 61.023758990;
case VolumeCubicCentimeter:
return 1000;
case VolumeCubicDegrees:
return 0.001 / DEG2_TO_M3; // basically meaningless!
case VolumeUnknownUnit:
return 1.0;
}
break;
}
case VolumeGallonUS:
{
switch ( toUnit )
{
case VolumeCubicMeters:
return 0.003785412;
case VolumeCubicFeet:
return 0.133680547;
case VolumeCubicYards:
return 0.004951132;
case VolumeBarrel:
return 0.023809524;
case VolumeCubicDecimeter:
case VolumeLiters:
return 3.785412000;
case VolumeGallonUS:
return 1.0;
case VolumeCubicInch:
return 231.000069567;
case VolumeCubicCentimeter:
return 3785.412;
case VolumeCubicDegrees:
return 0.003785412 / DEG2_TO_M3; // basically meaningless!
case VolumeUnknownUnit:
return 1.0;
}
break;
}
case VolumeCubicInch:
{
switch ( toUnit )
{
case VolumeCubicMeters:
return 0.000016387;
case VolumeCubicFeet:
return 0.000578703;
case VolumeCubicYards:
return 0.000021433;
case VolumeBarrel:
return 0.000103072;
case VolumeCubicDecimeter:
case VolumeLiters:
return 0.016387060;
case VolumeGallonUS:
return 0.004329003;
case VolumeCubicInch:
return 1.0;
case VolumeCubicCentimeter:
return 16.387060000;
case VolumeCubicDegrees:
return 0.000016387 / DEG2_TO_M3; // basically meaningless!
case VolumeUnknownUnit:
return 1.0;
}
break;
}
case VolumeCubicCentimeter:
{
switch ( toUnit )
{
case VolumeCubicMeters:
return 0.000001;
case VolumeCubicFeet:
return 0.000035315;
case VolumeCubicYards:
return 0.000001308;
case VolumeBarrel:
return 0.000006290;
case VolumeCubicDecimeter:
case VolumeLiters:
return 0.001;
case VolumeGallonUS:
return 0.000264172 ;
case VolumeCubicInch:
return 0.061023759;
case VolumeCubicCentimeter:
return 1.0;
case VolumeCubicDegrees:
return 0.000001 / DEG2_TO_M3; // basically meaningless!
case VolumeUnknownUnit:
return 1.0;
}
break;
}
case VolumeCubicDegrees:
if ( toUnit == VolumeUnknownUnit || toUnit == VolumeCubicDegrees )
return 1.0;
else
return fromUnitToUnitFactor( toUnit, QgsUnitTypes::VolumeCubicMeters ) * DEG2_TO_M3;
case VolumeUnknownUnit:
{
return 1.0;
}
}
}
QgsUnitTypes::VolumeUnit QgsUnitTypes::distanceToVolumeUnit( QgsUnitTypes::DistanceUnit distanceUnit )
{
switch ( distanceUnit )
{
case DistanceMeters:
return VolumeCubicMeters;
case DistanceKilometers:
return VolumeCubicMeters;
case DistanceCentimeters:
return VolumeCubicCentimeter;
case DistanceMillimeters:
return VolumeCubicCentimeter;
case DistanceFeet:
return VolumeCubicFeet;
case DistanceYards:
return VolumeCubicYards;
case DistanceMiles:
return VolumeCubicFeet;
case DistanceDegrees:
return VolumeCubicDegrees;
case DistanceUnknownUnit:
return VolumeUnknownUnit;
case DistanceNauticalMiles:
return VolumeCubicFeet;
}
return VolumeUnknownUnit;
}
QgsUnitTypes::DistanceUnit QgsUnitTypes::volumeToDistanceUnit( QgsUnitTypes::VolumeUnit volumeUnit )
{
switch ( volumeUnit )
{
case VolumeCubicMeters:
return DistanceMeters;
case VolumeCubicFeet:
return DistanceFeet;
case VolumeCubicYards:
return DistanceYards;
case VolumeBarrel:
return DistanceFeet;
case VolumeCubicDecimeter:
return DistanceCentimeters;
case VolumeLiters:
return DistanceMeters;
case VolumeGallonUS:
return DistanceFeet;
case VolumeCubicInch:
return DistanceFeet;
case VolumeCubicCentimeter:
return DistanceCentimeters;
case VolumeCubicDegrees:
return DistanceDegrees;
case VolumeUnknownUnit:
return DistanceUnknownUnit;
}
return DistanceUnknownUnit;
}
QgsUnitTypes::DistanceUnitType QgsUnitTypes::unitType( QgsUnitTypes::VolumeUnit unit )
{
switch ( unit )
{
case VolumeCubicMeters:
case VolumeCubicFeet:
case VolumeCubicYards:
case VolumeBarrel:
case VolumeCubicDecimeter:
case VolumeLiters:
case VolumeGallonUS:
case VolumeCubicInch:
case VolumeCubicCentimeter:
return Standard;
case VolumeCubicDegrees:
return Geographic;
case VolumeUnknownUnit:
return UnknownType;
}
return UnknownType;
}
QString QgsUnitTypes::encodeUnit( QgsUnitTypes::VolumeUnit unit )
{
switch ( unit )
{
case VolumeCubicMeters:
return QStringLiteral( "m3" );
case VolumeCubicFeet:
return QStringLiteral( "ft3" );
case VolumeCubicYards:
return QStringLiteral( "yd3" );
case VolumeBarrel:
return QStringLiteral( "bbl" );
case VolumeCubicDecimeter:
return QStringLiteral( "dm3" );
case VolumeLiters:
return QStringLiteral( "l" );
case VolumeGallonUS:
return QStringLiteral( "gal" );
case VolumeCubicInch:
return QStringLiteral( "in3" );
case VolumeCubicCentimeter:
return QStringLiteral( "cm3" );
case VolumeCubicDegrees:
return QStringLiteral( "deg3" );
case VolumeUnknownUnit:
return QStringLiteral( "<unknown>" );
}
return QString();
}
QString QgsUnitTypes::encodeUnit( QgsUnitTypes::AngleUnit unit )
{
switch ( unit )

View File

@ -50,6 +50,18 @@ class CORE_EXPORT QgsUnitTypes
};
Q_ENUM( SystemOfMeasurement )
/**
* Unit types.
* \since QGIS 3.10
*/
enum UnitType
{
TypeDistance = 0, //!< Distance unit
TypeArea, //!< Area unit
TypeVolume, //!< Volume unit
TypeUnknown, //!< Unknown unit type
};
//! Units of distance
enum DistanceUnit
{
@ -94,6 +106,26 @@ class CORE_EXPORT QgsUnitTypes
};
Q_ENUM( AreaUnit )
/**
* Units of volume.
* \since QGIS 3.10
*/
enum VolumeUnit
{
VolumeCubicMeters = 0, //!< Cubic meters
VolumeCubicFeet, //!< Cubic feet
VolumeCubicYards, //!< Cubic yards
VolumeBarrel, //!< Barrels
VolumeCubicDecimeter, //!< Cubic decimeters
VolumeLiters, //!< Litres
VolumeGallonUS, //!< US Gallons
VolumeCubicInch, //!< Cubic inches
VolumeCubicCentimeter, //!< Cubic Centimeters
VolumeCubicDegrees, //!< Cubic degrees, for planar geographic CRS volume measurements
VolumeUnknownUnit, //!< Unknown volume unit
};
Q_ENUM( VolumeUnit )
//! Units of angles
enum AngleUnit
{
@ -185,6 +217,25 @@ class CORE_EXPORT QgsUnitTypes
//! List of render units
typedef QList<QgsUnitTypes::RenderUnit> RenderUnitList;
/**
* Encodes a unit \a type to a string.
* \returns encoded string
* \see decodeUnitType()
* \since QGIS 3.10
*/
Q_INVOKABLE static QString encodeUnitType( QgsUnitTypes::UnitType type );
/**
* Decodes a unit type from a \a string.
* \param string string to decode
* \param ok optional boolean, will be set to TRUE if string was converted successfully
* \returns decoded unit type
* \see encodeUnitType()
* \since QGIS 3.10
*/
Q_INVOKABLE static QgsUnitTypes::UnitType decodeUnitType( const QString &string, bool *ok SIP_OUT = nullptr );
// DISTANCE UNITS
/**
@ -314,6 +365,82 @@ class CORE_EXPORT QgsUnitTypes
*/
Q_INVOKABLE static QgsUnitTypes::DistanceUnit areaToDistanceUnit( QgsUnitTypes::AreaUnit areaUnit );
// VOLUME UNITS
/**
* Returns the type for an volume unit.
* \since QGIS 3.10
*/
Q_INVOKABLE static DistanceUnitType unitType( QgsUnitTypes::VolumeUnit unit );
/**
* Encodes a volume \a unit to a string.
* \returns encoded string
* \see decodeVolumeUnit()
* \since QGIS 3.10
*/
Q_INVOKABLE static QString encodeUnit( QgsUnitTypes::VolumeUnit unit );
/**
* Decodes a volume unit from a \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()
* \since QGIS 3.10
*/
Q_INVOKABLE static VolumeUnit decodeVolumeUnit( const QString &string, bool *ok SIP_OUT = nullptr );
/**
* Returns a translated string representing a volume \a unit.
* \see stringToVolumeUnit()
* \since QGIS 3.10
*/
static QString toString( QgsUnitTypes::VolumeUnit unit );
/**
* Returns a translated abbreviation representing a volume \a unit.
* \see stringToVolumeUnit()
*
* \since QGIS 3.10
*/
static QString toAbbreviatedString( QgsUnitTypes::VolumeUnit unit );
/**
* Converts a translated\a string to a volume unit.
* \param string string representing a volume unit
* \param ok optional boolean, will be set to TRUE if string was converted successfully
* \returns the volume unit
* \see toString()
* \since QGIS 3.10
*/
Q_INVOKABLE static VolumeUnit stringToVolumeUnit( const QString &string, bool *ok SIP_OUT = nullptr );
/**
* Returns the conversion factor between the specified volume units.
* \param fromUnit volume unit to convert from
* \param toUnit volume unit to convert to
* \returns multiplication factor to convert between units
* \since QGIS 3.10
*/
Q_INVOKABLE static double fromUnitToUnitFactor( QgsUnitTypes::VolumeUnit fromUnit, QgsUnitTypes::VolumeUnit toUnit );
/**
* Converts a distance unit to its corresponding volume unit, e.g., meters to cubic meters
* \param distanceUnit distance unit to convert
* \returns matching volume unit
* \since QGIS 3.10
*/
Q_INVOKABLE static QgsUnitTypes::VolumeUnit distanceToVolumeUnit( QgsUnitTypes::DistanceUnit distanceUnit );
/**
* Converts a volume unit to its corresponding distance unit, e.g., cubic meters to meters
* \param volumeUnit volume unit to convert
* \returns matching distance unit
* \since QGIS 3.10
*/
Q_INVOKABLE static QgsUnitTypes::DistanceUnit volumeToDistanceUnit( QgsUnitTypes::VolumeUnit volumeUnit );
// ANGULAR UNITS
/**

View File

@ -23,6 +23,28 @@ QLocale.setDefault(QLocale.c())
class TestQgsUnitTypes(unittest.TestCase):
def testEncodeDecodeUnitType(self):
"""Test encoding and decoding unit type"""
units = [QgsUnitTypes.TypeDistance,
QgsUnitTypes.TypeArea,
QgsUnitTypes.TypeVolume,
QgsUnitTypes.TypeUnknown]
for u in units:
res, ok = QgsUnitTypes.decodeUnitType(QgsUnitTypes.encodeUnitType(u))
assert ok
self.assertEqual(res, u)
# Test decoding bad units
res, ok = QgsUnitTypes.decodeUnitType('bad')
self.assertFalse(ok)
self.assertEqual(res, QgsUnitTypes.TypeUnknown)
# Test that string is cleaned before decoding
res, ok = QgsUnitTypes.decodeUnitType(' volUme ')
assert ok
self.assertEqual(res, QgsUnitTypes.TypeVolume)
def testDistanceUnitType(self):
"""Test QgsUnitTypes::unitType() """
expected = {QgsUnitTypes.DistanceMeters: QgsUnitTypes.Standard,
@ -176,6 +198,82 @@ class TestQgsUnitTypes(unittest.TestCase):
assert ok
self.assertEqual(res, QgsUnitTypes.AreaSquareMiles)
def testVolumeUnitType(self):
"""Test QgsUnitTypes::unitType() for volume units """
expected = {QgsUnitTypes.VolumeCubicMeters: QgsUnitTypes.Standard,
QgsUnitTypes.VolumeCubicFeet: QgsUnitTypes.Standard,
QgsUnitTypes.VolumeCubicYards: QgsUnitTypes.Standard,
QgsUnitTypes.VolumeBarrel: QgsUnitTypes.Standard,
QgsUnitTypes.VolumeCubicDecimeter: QgsUnitTypes.Standard,
QgsUnitTypes.VolumeLiters: QgsUnitTypes.Standard,
QgsUnitTypes.VolumeGallonUS: QgsUnitTypes.Standard,
QgsUnitTypes.VolumeCubicInch: QgsUnitTypes.Standard,
QgsUnitTypes.VolumeCubicCentimeter: QgsUnitTypes.Standard,
QgsUnitTypes.VolumeCubicDegrees: QgsUnitTypes.Geographic,
QgsUnitTypes.VolumeUnknownUnit: QgsUnitTypes.UnknownType,
}
for t in list(expected.keys()):
self.assertEqual(QgsUnitTypes.unitType(t), expected[t])
def testEncodeDecodeVolumeUnits(self):
"""Test encoding and decoding volume units"""
units = [QgsUnitTypes.VolumeCubicMeters,
QgsUnitTypes.VolumeCubicFeet,
QgsUnitTypes.VolumeCubicYards,
QgsUnitTypes.VolumeBarrel,
QgsUnitTypes.VolumeCubicDecimeter,
QgsUnitTypes.VolumeLiters,
QgsUnitTypes.VolumeGallonUS,
QgsUnitTypes.VolumeCubicInch,
QgsUnitTypes.VolumeCubicCentimeter,
QgsUnitTypes.VolumeCubicDegrees,
QgsUnitTypes.VolumeUnknownUnit]
for u in units:
res, ok = QgsUnitTypes.decodeVolumeUnit(QgsUnitTypes.encodeUnit(u))
assert ok
self.assertEqual(res, u)
# Test decoding bad units
res, ok = QgsUnitTypes.decodeVolumeUnit('bad')
self.assertFalse(ok)
self.assertEqual(res, QgsUnitTypes.VolumeUnknownUnit)
# Test that string is cleaned before decoding
res, ok = QgsUnitTypes.decodeVolumeUnit(' bbl ')
assert ok
self.assertEqual(res, QgsUnitTypes.VolumeBarrel)
def testVolumeUnitsToFromString(self):
"""Test converting volume units to and from translated strings"""
units = [QgsUnitTypes.VolumeCubicMeters,
QgsUnitTypes.VolumeCubicFeet,
QgsUnitTypes.VolumeCubicYards,
QgsUnitTypes.VolumeBarrel,
QgsUnitTypes.VolumeCubicDecimeter,
QgsUnitTypes.VolumeLiters,
QgsUnitTypes.VolumeGallonUS,
QgsUnitTypes.VolumeCubicInch,
QgsUnitTypes.VolumeCubicCentimeter,
QgsUnitTypes.VolumeCubicDegrees,
QgsUnitTypes.VolumeUnknownUnit]
for u in units:
res, ok = QgsUnitTypes.stringToVolumeUnit(QgsUnitTypes.toString(u))
assert ok
self.assertEqual(res, u)
# Test converting bad strings
res, ok = QgsUnitTypes.stringToVolumeUnit('bad')
self.assertFalse(ok)
self.assertEqual(res, QgsUnitTypes.VolumeUnknownUnit)
# Test that string is cleaned before conversion
res, ok = QgsUnitTypes.stringToVolumeUnit(' {} '.format(QgsUnitTypes.toString(QgsUnitTypes.VolumeBarrel).upper()))
assert ok
self.assertEqual(res, QgsUnitTypes.VolumeBarrel)
def testEncodeDecodeRenderUnits(self):
"""Test encoding and decoding render units"""
units = [QgsUnitTypes.RenderMillimeters,
@ -571,6 +669,191 @@ class TestQgsUnitTypes(unittest.TestCase):
for t in list(expected.keys()):
self.assertEqual(QgsUnitTypes.areaToDistanceUnit(t), expected[t])
def testVolumeFromUnitToUnitFactor(self):
"""Test calculation of conversion factor between volume units"""
expected = {
QgsUnitTypes.VolumeCubicMeters: {
QgsUnitTypes.VolumeCubicMeters: 1.0,
QgsUnitTypes.VolumeCubicFeet: 35.314666572222,
QgsUnitTypes.VolumeCubicYards: 1.307950613786,
QgsUnitTypes.VolumeBarrel: 6.2898107438466,
QgsUnitTypes.VolumeCubicDecimeter: 1000,
QgsUnitTypes.VolumeLiters: 1000,
QgsUnitTypes.VolumeGallonUS: 264.17205124156,
QgsUnitTypes.VolumeCubicInch: 61023.7438368,
QgsUnitTypes.VolumeCubicCentimeter: 1000000,
QgsUnitTypes.VolumeCubicDegrees: 7.24913798948971e-16,
QgsUnitTypes.VolumeUnknownUnit: 1.0
},
QgsUnitTypes.VolumeCubicFeet: {
QgsUnitTypes.VolumeCubicMeters: 0.0283168,
QgsUnitTypes.VolumeCubicFeet: 1.0,
QgsUnitTypes.VolumeCubicYards: 0.037037,
QgsUnitTypes.VolumeBarrel: 0.178107622,
QgsUnitTypes.VolumeCubicDecimeter: 28.31685,
QgsUnitTypes.VolumeLiters: 28.31685,
QgsUnitTypes.VolumeGallonUS: 7.48052,
QgsUnitTypes.VolumeCubicInch: 1728.000629765,
QgsUnitTypes.VolumeCubicCentimeter: 28316.85,
QgsUnitTypes.VolumeCubicDegrees: 2.0527272837261945e-17,
QgsUnitTypes.VolumeUnknownUnit: 1.0
},
QgsUnitTypes.VolumeCubicYards: {
QgsUnitTypes.VolumeCubicMeters: 0.7645549,
QgsUnitTypes.VolumeCubicFeet: 26.999998234,
QgsUnitTypes.VolumeCubicYards: 1.0,
QgsUnitTypes.VolumeBarrel: 4.808905491,
QgsUnitTypes.VolumeCubicDecimeter: 764.5549,
QgsUnitTypes.VolumeLiters: 764.5549,
QgsUnitTypes.VolumeGallonUS: 201.974025549,
QgsUnitTypes.VolumeCubicInch: 46656.013952472,
QgsUnitTypes.VolumeCubicCentimeter: 764554.9,
QgsUnitTypes.VolumeCubicDegrees: 5.542363970640507e-16,
QgsUnitTypes.VolumeUnknownUnit: 1.0
},
QgsUnitTypes.VolumeBarrel: {
QgsUnitTypes.VolumeCubicMeters: 0.158987294928,
QgsUnitTypes.VolumeCubicFeet: 5.614582837,
QgsUnitTypes.VolumeCubicYards: 0.207947526,
QgsUnitTypes.VolumeBarrel: 1.0,
QgsUnitTypes.VolumeCubicDecimeter: 158.9873,
QgsUnitTypes.VolumeLiters: 158.9873,
QgsUnitTypes.VolumeGallonUS: 41.999998943,
QgsUnitTypes.VolumeCubicInch: 9702.002677722,
QgsUnitTypes.VolumeCubicCentimeter: 158987.3,
QgsUnitTypes.VolumeCubicDegrees: 1.1525208762763973e-16,
QgsUnitTypes.VolumeUnknownUnit: 1.0
},
QgsUnitTypes.VolumeCubicDecimeter: {
QgsUnitTypes.VolumeCubicMeters: 0.001,
QgsUnitTypes.VolumeCubicFeet: 0.0353147,
QgsUnitTypes.VolumeCubicYards: 0.00130795,
QgsUnitTypes.VolumeBarrel: 0.00628981,
QgsUnitTypes.VolumeCubicDecimeter: 1.0,
QgsUnitTypes.VolumeLiters: 1.0,
QgsUnitTypes.VolumeGallonUS: 0.264172,
QgsUnitTypes.VolumeCubicInch: 61.02375899,
QgsUnitTypes.VolumeCubicCentimeter: 1000,
QgsUnitTypes.VolumeCubicDegrees: 7.24913798948971e-19,
QgsUnitTypes.VolumeUnknownUnit: 1.0
},
QgsUnitTypes.VolumeLiters: {
QgsUnitTypes.VolumeCubicMeters: 0.001,
QgsUnitTypes.VolumeCubicFeet: 0.0353147,
QgsUnitTypes.VolumeCubicYards: 0.00130795,
QgsUnitTypes.VolumeBarrel: 0.00628981,
QgsUnitTypes.VolumeCubicDecimeter: 1.0,
QgsUnitTypes.VolumeLiters: 1.0,
QgsUnitTypes.VolumeGallonUS: 0.264172,
QgsUnitTypes.VolumeCubicInch: 61.02375899,
QgsUnitTypes.VolumeCubicCentimeter: 1000,
QgsUnitTypes.VolumeCubicDegrees: 7.24913798948971e-19,
QgsUnitTypes.VolumeUnknownUnit: 1.0
},
QgsUnitTypes.VolumeGallonUS: {
QgsUnitTypes.VolumeCubicMeters: 0.00378541,
QgsUnitTypes.VolumeCubicFeet: 0.133680547,
QgsUnitTypes.VolumeCubicYards: 0.00495113,
QgsUnitTypes.VolumeBarrel: 0.023809524,
QgsUnitTypes.VolumeCubicDecimeter: 3.785412,
QgsUnitTypes.VolumeLiters: 3.785412,
QgsUnitTypes.VolumeGallonUS: 1.0,
QgsUnitTypes.VolumeCubicInch: 231.000069567,
QgsUnitTypes.VolumeCubicCentimeter: 3785.412,
QgsUnitTypes.VolumeCubicDegrees: 2.7440973935070226e-18,
QgsUnitTypes.VolumeUnknownUnit: 1.0
},
QgsUnitTypes.VolumeCubicInch: {
QgsUnitTypes.VolumeCubicMeters: 1.63871e-5,
QgsUnitTypes.VolumeCubicFeet: 0.000578704,
QgsUnitTypes.VolumeCubicYards: 2.14335e-5,
QgsUnitTypes.VolumeBarrel: 0.000103072,
QgsUnitTypes.VolumeCubicDecimeter: 0.0163871,
QgsUnitTypes.VolumeLiters: 0.0163871,
QgsUnitTypes.VolumeGallonUS: 0.004329,
QgsUnitTypes.VolumeCubicInch: 1.0,
QgsUnitTypes.VolumeCubicCentimeter: 16.38706,
QgsUnitTypes.VolumeCubicDegrees: 1.187916242337679e-20,
QgsUnitTypes.VolumeUnknownUnit: 1.0
},
QgsUnitTypes.VolumeCubicCentimeter: {
QgsUnitTypes.VolumeCubicMeters: 1e-6,
QgsUnitTypes.VolumeCubicFeet: 3.53147e-5,
QgsUnitTypes.VolumeCubicYards: 1.30795e-6,
QgsUnitTypes.VolumeBarrel: 6.28981e-6,
QgsUnitTypes.VolumeCubicDecimeter: 0.001,
QgsUnitTypes.VolumeLiters: 0.001,
QgsUnitTypes.VolumeGallonUS: 0.000264172,
QgsUnitTypes.VolumeCubicInch: 0.061023759,
QgsUnitTypes.VolumeCubicCentimeter: 1.0,
QgsUnitTypes.VolumeCubicDegrees: 7.24913798948971e-22,
QgsUnitTypes.VolumeUnknownUnit: 1.0
},
QgsUnitTypes.VolumeCubicDegrees: {
QgsUnitTypes.VolumeCubicMeters: 1379474361572186.2500000,
QgsUnitTypes.VolumeCubicFeet: 39062363874236.74,
QgsUnitTypes.VolumeCubicYards: 1054683882564386.8,
QgsUnitTypes.VolumeBarrel: 219318904165585.66,
QgsUnitTypes.VolumeCubicDecimeter: 1379474361572.1863,
QgsUnitTypes.VolumeLiters: 1379474361572.1863,
QgsUnitTypes.VolumeGallonUS: 5221878801987.693,
QgsUnitTypes.VolumeCubicInch: 22605446363.083416,
QgsUnitTypes.VolumeCubicCentimeter: 1379474361.5721862,
QgsUnitTypes.VolumeCubicDegrees: 1.0,
QgsUnitTypes.VolumeUnknownUnit: 1.0
}
}
for from_unit in list(expected.keys()):
for to_unit in list(expected[from_unit].keys()):
expected_factor = expected[from_unit][to_unit]
res = QgsUnitTypes.fromUnitToUnitFactor(from_unit, to_unit)
self.assertAlmostEqual(res,
expected_factor,
msg='got {:.15f}, expected {:.15f} when converting from {} to {}'.format(res, expected_factor,
QgsUnitTypes.toString(from_unit),
QgsUnitTypes.toString(to_unit)))
# test conversion to unknown units
res = QgsUnitTypes.fromUnitToUnitFactor(from_unit, QgsUnitTypes.VolumeUnknownUnit)
self.assertAlmostEqual(res,
1.0,
msg='got {:.7f}, expected 1.0 when converting from {} to unknown units'.format(res, QgsUnitTypes.toString(from_unit)))
def testDistanceToVolumeUnit(self):
"""Test distanceToVolumeUnit conversion"""
expected = {QgsUnitTypes.DistanceMeters: QgsUnitTypes.VolumeCubicMeters,
QgsUnitTypes.DistanceKilometers: QgsUnitTypes.VolumeCubicMeters,
QgsUnitTypes.DistanceFeet: QgsUnitTypes.VolumeCubicFeet,
QgsUnitTypes.DistanceYards: QgsUnitTypes.VolumeCubicYards,
QgsUnitTypes.DistanceMiles: QgsUnitTypes.VolumeCubicFeet,
QgsUnitTypes.DistanceDegrees: QgsUnitTypes.VolumeCubicDegrees,
QgsUnitTypes.DistanceCentimeters: QgsUnitTypes.VolumeCubicCentimeter,
QgsUnitTypes.DistanceMillimeters: QgsUnitTypes.VolumeCubicCentimeter,
QgsUnitTypes.DistanceUnknownUnit: QgsUnitTypes.VolumeUnknownUnit,
QgsUnitTypes.DistanceNauticalMiles: QgsUnitTypes.VolumeCubicFeet
}
for t in list(expected.keys()):
self.assertEqual(QgsUnitTypes.distanceToVolumeUnit(t), expected[t])
def testVolumeToDistanceUnit(self):
"""Test volumeToDistanceUnit conversion"""
expected = {QgsUnitTypes.VolumeCubicMeters: QgsUnitTypes.DistanceMeters,
QgsUnitTypes.VolumeCubicFeet: QgsUnitTypes.DistanceFeet,
QgsUnitTypes.VolumeCubicYards: QgsUnitTypes.DistanceYards,
QgsUnitTypes.VolumeBarrel: QgsUnitTypes.DistanceFeet,
QgsUnitTypes.VolumeCubicDecimeter: QgsUnitTypes.DistanceCentimeters,
QgsUnitTypes.VolumeLiters: QgsUnitTypes.DistanceMeters,
QgsUnitTypes.VolumeGallonUS: QgsUnitTypes.DistanceFeet,
QgsUnitTypes.VolumeCubicInch: QgsUnitTypes.DistanceFeet,
QgsUnitTypes.VolumeCubicCentimeter: QgsUnitTypes.DistanceCentimeters,
QgsUnitTypes.VolumeCubicDegrees: QgsUnitTypes.DistanceDegrees
}
for t in list(expected.keys()):
self.assertEqual(QgsUnitTypes.volumeToDistanceUnit(t), expected[t])
def testEncodeDecodeAngleUnits(self):
"""Test encoding and decoding angle units"""
units = [QgsUnitTypes.AngleDegrees,