Skip to content

Commit

Permalink
[FEATURE] Add km, yards and miles to distance unit options
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Feb 28, 2016
1 parent 5e2e468 commit b223593
Show file tree
Hide file tree
Showing 13 changed files with 355 additions and 25 deletions.
14 changes: 9 additions & 5 deletions python/core/qgis.sip
Expand Up @@ -144,16 +144,20 @@ class QGis
//TODO QGIS 3.0 - clean up and move to QgsUnitTypes and rename to DistanceUnit
enum UnitType
{
Meters,
Feet,
Degrees, //for 1.0 api backwards compatibility
UnknownUnit,
Meters, /*!< meters */
Feet, /*!< imperial feet */
Degrees, /*!< degrees, for planar geographic CRS distance measurements */ //for 1.0 api backwards compatibility
NauticalMiles, /*!< nautical miles */
Kilometers, /*!< kilometers */
Yards, /*!< imperial yards */
Miles, /*!< terrestial miles */

UnknownUnit, /*!< unknown distance unit */

// for [1.4;1.8] api compatibility
DecimalDegrees, // was 2
DegreesMinutesSeconds, // was 4
DegreesDecimalMinutes, // was 5
NauticalMiles
};

//! Provides the canonical name of the type value
Expand Down
18 changes: 15 additions & 3 deletions python/core/qgsdistancearea.sip
Expand Up @@ -177,10 +177,21 @@ class QgsDistanceArea
* @param keepBaseUnit set to false to allow conversion of large distances to more suitable units, eg meters
* to kilometers
* @return formatted measurement string
* @deprecated use formatDistance() or formatArea() instead
*/
static QString textUnit( double value, int decimals, QGis::UnitType u, bool isArea, bool keepBaseUnit = false ) /Deprecated/;

/** Returns an distance formatted as a friendly string.
* @param distance distance to format
* @param decimals number of decimal places to show
* @param unit unit of distance
* @param keepBaseUnit set to false to allow conversion of large distances to more suitable units, eg meters to
* kilometers
* @returns formatted distance string
* @note added in QGIS 2.16
* @see formatArea()
*/
//TODO QGIS 3.0 - remove isArea parameter (use AreaUnit variant instead), rename to formatDistance
static QString textUnit( double value, int decimals, QGis::UnitType u, bool isArea, bool keepBaseUnit = false );
static QString formatDistance( double distance, int decimals, QGis::UnitType unit, bool keepBaseUnit = false );

/** Returns an area formatted as a friendly string.
* @param area area to format
Expand All @@ -190,10 +201,11 @@ class QgsDistanceArea
* square kilometers
* @returns formatted area string
* @note added in QGIS 2.14
* @see textUnit()
* @see formatDistance()
*/
static QString formatArea( double area, int decimals, QgsUnitTypes::AreaUnit unit, bool keepBaseUnit = false );


//! Helper for conversion between physical units
// TODO QGIS 3.0 - remove this method, as its behaviour is non-intuitive.
void convertMeasurement( double &measure /In,Out/, QGis::UnitType &measureUnits /In,Out/, QGis::UnitType displayUnits, bool isArea ) const;
Expand Down
5 changes: 4 additions & 1 deletion src/app/qgsmeasuredialog.cpp
Expand Up @@ -252,7 +252,7 @@ QString QgsMeasureDialog::formatDistance( double distance, bool convertUnits ) c

if ( convertUnits )
distance = convertLength( distance, mDistanceUnits );
return QgsDistanceArea::textUnit( distance, mDecimalPlaces, mDistanceUnits, false, baseUnit );
return QgsDistanceArea::formatDistance( distance, mDecimalPlaces, mDistanceUnits, baseUnit );
}

QString QgsMeasureDialog::formatArea( double area, bool convertUnits ) const
Expand Down Expand Up @@ -504,7 +504,10 @@ void QgsMeasureDialog::repopulateComboBoxUnits( bool isArea )
else
{
mUnitsCombo->addItem( QgsUnitTypes::toString( QGis::Meters ), QGis::Meters );
mUnitsCombo->addItem( QgsUnitTypes::toString( QGis::Kilometers ), QGis::Kilometers );
mUnitsCombo->addItem( QgsUnitTypes::toString( QGis::Feet ), QGis::Feet );
mUnitsCombo->addItem( QgsUnitTypes::toString( QGis::Yards ), QGis::Yards );
mUnitsCombo->addItem( QgsUnitTypes::toString( QGis::Miles ), QGis::Miles );
mUnitsCombo->addItem( QgsUnitTypes::toString( QGis::Degrees ), QGis::Degrees );
mUnitsCombo->addItem( QgsUnitTypes::toString( QGis::NauticalMiles ), QGis::NauticalMiles );
}
Expand Down
3 changes: 3 additions & 0 deletions src/app/qgsoptions.cpp
Expand Up @@ -461,7 +461,10 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl ) :

// Set the units for measuring
mDistanceUnitsComboBox->addItem( tr( "Meters" ), QGis::Meters );
mDistanceUnitsComboBox->addItem( tr( "Kilometers" ), QGis::Kilometers );
mDistanceUnitsComboBox->addItem( tr( "Feet" ), QGis::Feet );
mDistanceUnitsComboBox->addItem( tr( "Yards" ), QGis::Yards );
mDistanceUnitsComboBox->addItem( tr( "Miles" ), QGis::Miles );
mDistanceUnitsComboBox->addItem( tr( "Nautical miles" ), QGis::NauticalMiles );
mDistanceUnitsComboBox->addItem( tr( "Degrees" ), QGis::Degrees );
mDistanceUnitsComboBox->addItem( tr( "Map units" ), QGis::UnknownUnit );
Expand Down
3 changes: 3 additions & 0 deletions src/app/qgsprojectproperties.cpp
Expand Up @@ -87,7 +87,10 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *pa
mCoordinateDisplayComboBox->addItem( tr( "Degrees, minutes, seconds" ), DegreesMinutesSeconds );

mDistanceUnitsCombo->addItem( tr( "Meters" ), QGis::Meters );
mDistanceUnitsCombo->addItem( tr( "Kilometers" ), QGis::Kilometers );
mDistanceUnitsCombo->addItem( tr( "Feet" ), QGis::Feet );
mDistanceUnitsCombo->addItem( tr( "Yards" ), QGis::Yards );
mDistanceUnitsCombo->addItem( tr( "Miles" ), QGis::Miles );
mDistanceUnitsCombo->addItem( tr( "Nautical miles" ), QGis::NauticalMiles );
mDistanceUnitsCombo->addItem( tr( "Degrees" ), QGis::Degrees );
mDistanceUnitsCombo->addItem( tr( "Map units" ), QGis::UnknownUnit );
Expand Down
14 changes: 9 additions & 5 deletions src/core/qgis.h
Expand Up @@ -154,16 +154,20 @@ class CORE_EXPORT QGis
//TODO QGIS 3.0 - clean up and move to QgsUnitTypes and rename to DistanceUnit
enum UnitType
{
Meters = 0,
Feet = 1,
Degrees = 2, //for 1.0 api backwards compatibility
UnknownUnit = 3,
Meters = 0, /*!< meters */
Feet = 1, /*!< imperial feet */
Degrees = 2, /*!< degrees, for planar geographic CRS distance measurements */ //for 1.0 api backwards compatibility
NauticalMiles = 7, /*!< nautical miles */
Kilometers = 8, /*!< kilometers */
Yards = 9, /*!< imperial yards */
Miles = 10, /*!< terrestial miles */

UnknownUnit = 3, /*!< unknown distance unit */

// for [1.4;1.8] api compatibility
DecimalDegrees = 2, // was 2
DegreesMinutesSeconds = 2, // was 4
DegreesDecimalMinutes = 2, // was 5
NauticalMiles = 7
};

//! Provides the canonical name of the type value
Expand Down
103 changes: 103 additions & 0 deletions src/core/qgsdistancearea.cpp
Expand Up @@ -1096,6 +1096,109 @@ QString QgsDistanceArea::textUnit( double value, int decimals, QGis::UnitType u,
return QString( "%L1%2" ).arg( value, 0, 'f', decimals ).arg( unitLabel );
}

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

switch ( unit )
{
case QGis::Meters:
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 QGis::Kilometers:
if ( keepBaseUnit || qAbs( distance ) >= 1.0 )
{
unitLabel = QObject::tr( " km" );
}
else
{
unitLabel = QObject::tr( " m" );
distance = distance * 1000;
}
break;

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

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

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

case QGis::NauticalMiles:
unitLabel = QObject::tr( " NM" );
break;

case QGis::Degrees:

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

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

return QString( "%L1%2" ).arg( distance, 0, 'f', decimals ).arg( unitLabel );
}

QString QgsDistanceArea::formatArea( double area, int decimals, QgsUnitTypes::AreaUnit unit, bool keepBaseUnit )
{
QString unitLabel;
Expand Down
17 changes: 14 additions & 3 deletions src/core/qgsdistancearea.h
Expand Up @@ -221,10 +221,21 @@ class CORE_EXPORT QgsDistanceArea
* @param keepBaseUnit set to false to allow conversion of large distances to more suitable units, eg meters
* to kilometers
* @return formatted measurement string
* @deprecated use formatDistance() or formatArea() instead
*/
Q_DECL_DEPRECATED static QString textUnit( double value, int decimals, QGis::UnitType u, bool isArea, bool keepBaseUnit = false );

/** Returns an distance formatted as a friendly string.
* @param distance distance to format
* @param decimals number of decimal places to show
* @param unit unit of distance
* @param keepBaseUnit set to false to allow conversion of large distances to more suitable units, eg meters to
* kilometers
* @returns formatted distance string
* @note added in QGIS 2.16
* @see formatArea()
*/
//TODO QGIS 3.0 - remove isArea parameter (use AreaUnit variant instead), rename to formatDistance
static QString textUnit( double value, int decimals, QGis::UnitType u, bool isArea, bool keepBaseUnit = false );
static QString formatDistance( double distance, int decimals, QGis::UnitType unit, bool keepBaseUnit = false );

/** Returns an area formatted as a friendly string.
* @param area area to format
Expand All @@ -234,7 +245,7 @@ class CORE_EXPORT QgsDistanceArea
* square kilometers
* @returns formatted area string
* @note added in QGIS 2.14
* @see textUnit()
* @see formatDistance()
*/
static QString formatArea( double area, int decimals, QgsUnitTypes::AreaUnit unit, bool keepBaseUnit = false );

Expand Down

0 comments on commit b223593

Please sign in to comment.