Skip to content

Commit

Permalink
Move unit handling helpers out of QGis and QgsSymbolLayerUtils
Browse files Browse the repository at this point in the history
into a new QgsUnitTypes helper class. Add unit tests.

TODO QGIS 3.0: Move QGis::UnitType and QgsSymbolV2::OutputUnit
to QgsUnitTypes
  • Loading branch information
nyalldawson committed Feb 3, 2016
1 parent 5a8e4cc commit ddabad2
Show file tree
Hide file tree
Showing 33 changed files with 795 additions and 252 deletions.
1 change: 1 addition & 0 deletions python/core/core.sip
Expand Up @@ -125,6 +125,7 @@
%Include qgsstringutils.sip
%Include qgstolerance.sip
%Include qgstracer.sip
%Include qgsunittypes.sip
%Include qgsvectordataprovider.sip
%Include qgsvectorfilewriter.sip
%Include qgsvectorlayer.sip
Expand Down
20 changes: 14 additions & 6 deletions python/core/qgis.sip
Expand Up @@ -129,16 +129,24 @@ class QGis
NauticalMiles
};

//! Provides the canonical name of the type value
static QString toLiteral( QGis::UnitType unit );
//! @deprecated use QgsUnitTypes::encodeUnit() instead
static QString toLiteral( QGis::UnitType unit ) /Deprecated/;

//! Converts from the canonical name to the type value
static UnitType fromLiteral( const QString& literal, QGis::UnitType defaultType = UnknownUnit );
//! @deprecated use QgsUnitTypes::decodeDistanceUnit() instead
static UnitType fromLiteral( const QString& literal, QGis::UnitType defaultType = UnknownUnit ) /Deprecated/;

//! Provides translated version of the type value
static QString tr( QGis::UnitType unit );
//! @deprecated use QgsUnitTypes::toString() instead
static QString tr( QGis::UnitType unit ) /Deprecated/;

//! Provides type value from translated version
static UnitType fromTr( const QString& literal, QGis::UnitType defaultType = UnknownUnit );
//! @deprecated use QgsUnitTypes::stringToDistanceUnit() instead
static UnitType fromTr( const QString& literal, QGis::UnitType defaultType = UnknownUnit ) /Deprecated/;

//! Returns the conversion factor between the specified units
static double fromUnitToUnitFactor( QGis::UnitType fromUnit, QGis::UnitType toUnit );
//! @deprecated use QgsUnitTyoes::fromUnitToUnitFactor() instead
static double fromUnitToUnitFactor( QGis::UnitType fromUnit, QGis::UnitType toUnit ) /Deprecated/;

/** Converts a string to a double in a permissive way, eg allowing for incorrect
* numbers of digits between thousand separators
Expand Down
80 changes: 80 additions & 0 deletions python/core/qgsunittypes.sip
@@ -0,0 +1,80 @@
/** \ingroup core
* \class QgsUnitTypes
* \brief Helper functions for various unit types.
* \note Added in version 2.14
*/

class QgsUnitTypes
{
%TypeHeaderCode
#include <qgsunittypes.h>
%End

public:

/** Types of distance units
*/
enum DistanceUnitType
{
Standard, /*!< unit is a standard measurement unit */
Geographic, /*!< unit is a geographic (eg degree based) unit */
UnknownType, /*!< unknown unit type */
};

/** Returns the type for a distance unit.
*/
static DistanceUnitType unitType( QGis::UnitType unit );

/** Encodes a distance unit to a string.
* @param unit unit to encode
* @returns encoded string
* @see decodeDistanceUnit()
*/
static QString encodeUnit( QGis::UnitType unit );

/** Decodes a distance 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 QGis::UnitType decodeDistanceUnit( const QString& string, bool *ok = 0 );

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

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

/** Returns the conversion factor between the specified distance units.
* @param fromUnit distance unit to convert from
* @param toUnit distance unit to convert to
* @returns multiplication factor to convert between units
*/
static double fromUnitToUnitFactor( QGis::UnitType fromUnit, QGis::UnitType toUnit );


/** Encodes a symbol unit to a string.
* @param unit unit to encode
* @returns encoded string
* @see decodeSymbolUnit()
*/
static QString encodeUnit( QgsSymbolV2::OutputUnit unit );

/** Decodes a symbol 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 QgsSymbolV2::OutputUnit decodeSymbolUnit( const QString& string, bool *ok = 0 );

};

6 changes: 4 additions & 2 deletions python/core/symbology-ng/qgssymbollayerv2utils.sip
Expand Up @@ -51,8 +51,10 @@ class QgsSymbolLayerV2Utils
static QString encodeSldRealVector( const QVector<qreal>& v );
static QVector<qreal> decodeSldRealVector( const QString& s );

static QString encodeOutputUnit( QgsSymbolV2::OutputUnit unit );
static QgsSymbolV2::OutputUnit decodeOutputUnit( const QString& str );
//! @deprecated use QgsUnitTypes::encodeUnit() instead
static QString encodeOutputUnit( QgsSymbolV2::OutputUnit unit ) /Deprecated/;
//! @deprecated use QgsUnitTypes::decodeSymbolUnit() instead
static QgsSymbolV2::OutputUnit decodeOutputUnit( const QString& str ) /Deprecated/;

static QString encodeSldUom( QgsSymbolV2::OutputUnit unit, double *scaleFactor );
static QgsSymbolV2::OutputUnit decodeSldUom( const QString& str, double *scaleFactor );
Expand Down
5 changes: 3 additions & 2 deletions src/app/qgsdecorationitem.cpp
Expand Up @@ -26,6 +26,7 @@
#include "qgspoint.h"
#include "qgsproject.h"
#include "qgssymbollayerv2utils.h" //for pointOnLineWithDistance
#include "qgsunittypes.h"

#include <QPainter>
#include <QAction>
Expand Down Expand Up @@ -66,15 +67,15 @@ void QgsDecorationItem::projectRead()
QgsDebugMsg( "Entered" );
mEnabled = QgsProject::instance()->readBoolEntry( mNameConfig, "/Enabled", false );
mPlacement = static_cast< Placement >( QgsProject::instance()->readNumEntry( mNameConfig, "/Placement", static_cast< int >( mPlacement ) ) );
mMarginUnit = QgsSymbolLayerV2Utils::decodeOutputUnit( QgsProject::instance()->readEntry( mNameConfig, "/MarginUnit", QgsSymbolLayerV2Utils::encodeOutputUnit( mMarginUnit ) ) );
mMarginUnit = QgsUnitTypes::decodeSymbolUnit( QgsProject::instance()->readEntry( mNameConfig, "/MarginUnit", QgsUnitTypes::encodeUnit( mMarginUnit ) ) );
}

void QgsDecorationItem::saveToProject()
{
QgsDebugMsg( "Entered" );
QgsProject::instance()->writeEntry( mNameConfig, "/Enabled", mEnabled );
QgsProject::instance()->writeEntry( mNameConfig, "/Placement", static_cast< int >( mPlacement ) );
QgsProject::instance()->writeEntry( mNameConfig, "/MarginUnit", QgsSymbolLayerV2Utils::encodeOutputUnit( mMarginUnit ) );
QgsProject::instance()->writeEntry( mNameConfig, "/MarginUnit", QgsUnitTypes::encodeUnit( mMarginUnit ) );
}

void QgsDecorationItem::setName( const char *name )
Expand Down
9 changes: 6 additions & 3 deletions src/app/qgsdecorationscalebar.cpp
Expand Up @@ -31,7 +31,7 @@ email : sbr00pwb@users.sourceforge.net
#include "qgsmaptopixel.h"
#include "qgspoint.h"
#include "qgsproject.h"

#include "qgsunittypes.h"

#include <QPainter>
#include <QAction>
Expand Down Expand Up @@ -132,11 +132,14 @@ void QgsDecorationScaleBar::render( QPainter * theQPainter )
int myTextOffsetX = 3;

QSettings settings;
QGis::UnitType myPreferredUnits = QGis::fromLiteral( settings.value( "/qgis/measure/displayunits", QGis::toLiteral( QGis::Meters ) ).toString() );
bool ok = false;
QGis::UnitType myPreferredUnits = QgsUnitTypes::decodeDistanceUnit( settings.value( "/qgis/measure/displayunits" ).toString(), &ok );
if ( !ok )
myPreferredUnits = QGis::Meters;
QGis::UnitType myMapUnits = canvas->mapUnits();

// Adjust units meter/feet/... or vice versa
myMapUnitsPerPixelDouble *= QGis::fromUnitToUnitFactor( myMapUnits, myPreferredUnits );
myMapUnitsPerPixelDouble *= QgsUnitTypes::fromUnitToUnitFactor( myMapUnits, myPreferredUnits );
myMapUnits = myPreferredUnits;

//Calculate size of scale bar for preferred number of map units
Expand Down
5 changes: 4 additions & 1 deletion src/app/qgsmaptoolidentifyaction.cpp
Expand Up @@ -35,6 +35,7 @@
#include "qgsproject.h"
#include "qgsmaplayerregistry.h"
#include "qgsrendererv2.h"
#include "qgsunittypes.h"

#include <QSettings>
#include <QMouseEvent>
Expand Down Expand Up @@ -187,7 +188,9 @@ QGis::UnitType QgsMapToolIdentifyAction::displayUnits()
{
// Get the units for display
QSettings settings;
return QGis::fromLiteral( settings.value( "/qgis/measure/displayunits", QGis::toLiteral( QGis::Meters ) ).toString() );
bool ok = false;
QGis::UnitType unit = QgsUnitTypes::decodeDistanceUnit( settings.value( "/qgis/measure/displayunits" ).toString(), &ok );
return ok ? unit : QGis::Meters;
}

void QgsMapToolIdentifyAction::handleCopyToClipboard( QgsFeatureStore & featureStore )
Expand Down
31 changes: 16 additions & 15 deletions src/app/qgsmeasuredialog.cpp
Expand Up @@ -25,6 +25,7 @@
#include "qgsmaprenderer.h"
#include "qgsproject.h"
#include "qgscoordinatereferencesystem.h"
#include "qgsunittypes.h"

#include <QCloseEvent>
#include <QLocale>
Expand All @@ -49,14 +50,14 @@ QgsMeasureDialog::QgsMeasureDialog( QgsMeasureTool* tool, Qt::WindowFlags f )
mMeasureArea = tool->measureArea();
mTotal = 0.;

mUnitsCombo->addItem( QGis::tr( QGis::Meters ) );
mUnitsCombo->addItem( QGis::tr( QGis::Feet ) );
mUnitsCombo->addItem( QGis::tr( QGis::Degrees ) );
mUnitsCombo->addItem( QGis::tr( QGis::NauticalMiles ) );
mUnitsCombo->addItem( QgsUnitTypes::toString( QGis::Meters ) );
mUnitsCombo->addItem( QgsUnitTypes::toString( QGis::Feet ) );
mUnitsCombo->addItem( QgsUnitTypes::toString( QGis::Degrees ) );
mUnitsCombo->addItem( QgsUnitTypes::toString( QGis::NauticalMiles ) );

QSettings settings;
QString units = settings.value( "/qgis/measure/displayunits", QGis::toLiteral( QGis::Meters ) ).toString();
mUnitsCombo->setCurrentIndex( mUnitsCombo->findText( QGis::tr( QGis::fromLiteral( units ) ), Qt::MatchFixedString ) );
QString units = settings.value( "/qgis/measure/displayunits", QgsUnitTypes::encodeUnit( QGis::Meters ) ).toString();
mUnitsCombo->setCurrentIndex( mUnitsCombo->findText( QgsUnitTypes::toString( QgsUnitTypes::decodeDistanceUnit( units ) ), Qt::MatchFixedString ) );

updateSettings();

Expand All @@ -78,7 +79,7 @@ void QgsMeasureDialog::updateSettings()
mDecimalPlaces = settings.value( "/qgis/measure/decimalplaces", "3" ).toInt();
mCanvasUnits = mTool->canvas()->mapUnits();
// Configure QgsDistanceArea
mDisplayUnits = QGis::fromTr( mUnitsCombo->currentText() );
mDisplayUnits = QgsUnitTypes::stringToDistanceUnit( mUnitsCombo->currentText() );
mDa.setSourceCrs( mTool->canvas()->mapSettings().destinationCrs().srsid() );
mDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
// Only use ellipsoidal calculation when project wide transformation is enabled.
Expand All @@ -95,16 +96,16 @@ void QgsMeasureDialog::updateSettings()
QgsDebugMsg( QString( "Ellipsoid ID : %1" ).arg( mDa.ellipsoid() ) );
QgsDebugMsg( QString( "Ellipsoidal : %1" ).arg( mDa.ellipsoidalEnabled() ? "true" : "false" ) );
QgsDebugMsg( QString( "Decimalplaces: %1" ).arg( mDecimalPlaces ) );
QgsDebugMsg( QString( "Display units: %1" ).arg( QGis::toLiteral( mDisplayUnits ) ) );
QgsDebugMsg( QString( "Canvas units : %1" ).arg( QGis::toLiteral( mCanvasUnits ) ) );
QgsDebugMsg( QString( "Display units: %1" ).arg( QgsUnitTypes::encodeUnit( mDisplayUnits ) ) );
QgsDebugMsg( QString( "Canvas units : %1" ).arg( QgsUnitTypes::encodeUnit( mCanvasUnits ) ) );

mTotal = 0;
updateUi();
}

void QgsMeasureDialog::unitsChanged( const QString &units )
{
mDisplayUnits = QGis::fromTr( units );
mDisplayUnits = QgsUnitTypes::stringToDistanceUnit( units );
mTable->clear();
mTotal = 0.;
updateUi();
Expand Down Expand Up @@ -273,7 +274,7 @@ void QgsMeasureDialog::updateUi()
if ( ! mTool->canvas()->hasCrsTransformEnabled() )
{
toolTip += "<br> * " + tr( "Project CRS transformation is turned off." ) + ' ';
toolTip += tr( "Canvas units setting is taken from project properties setting (%1)." ).arg( QGis::tr( mCanvasUnits ) );
toolTip += tr( "Canvas units setting is taken from project properties setting (%1)." ).arg( QgsUnitTypes::toString( mCanvasUnits ) );
toolTip += "<br> * " + tr( "Ellipsoidal calculation is not possible, as project CRS is undefined." );
setWindowTitle( tr( "Measure (OTF off)" ) );
}
Expand All @@ -287,14 +288,14 @@ void QgsMeasureDialog::updateUi()
else
{
toolTip += "<br> * " + tr( "Project CRS transformation is turned on but ellipsoidal calculation is not selected." );
toolTip += "<br> * " + tr( "The canvas units setting is taken from the project CRS (%1)." ).arg( QGis::tr( mCanvasUnits ) );
toolTip += "<br> * " + tr( "The canvas units setting is taken from the project CRS (%1)." ).arg( QgsUnitTypes::toString( mCanvasUnits ) );
}
setWindowTitle( tr( "Measure (OTF on)" ) );
}

if (( mCanvasUnits == QGis::Meters && mDisplayUnits == QGis::Feet ) || ( mCanvasUnits == QGis::Feet && mDisplayUnits == QGis::Meters ) )
{
toolTip += "<br> * " + tr( "Finally, the value is converted from %1 to %2." ).arg( QGis::tr( mCanvasUnits ), QGis::tr( mDisplayUnits ) );
toolTip += "<br> * " + tr( "Finally, the value is converted from %1 to %2." ).arg( QgsUnitTypes::toString( mCanvasUnits ), QgsUnitTypes::toString( mDisplayUnits ) );
}

editTotal->setToolTip( toolTip );
Expand All @@ -304,7 +305,7 @@ void QgsMeasureDialog::updateUi()
QGis::UnitType newDisplayUnits;
double dummy = 1.0;
convertMeasurement( dummy, newDisplayUnits, true );
mTable->setHeaderLabels( QStringList( tr( "Segments [%1]" ).arg( QGis::tr( newDisplayUnits ) ) ) );
mTable->setHeaderLabels( QStringList( tr( "Segments [%1]" ).arg( QgsUnitTypes::toString( newDisplayUnits ) ) ) );

if ( mMeasureArea )
{
Expand Down Expand Up @@ -354,7 +355,7 @@ void QgsMeasureDialog::convertMeasurement( double &measure, QGis::UnitType &u, b
// Get the canvas units
QGis::UnitType myUnits = mCanvasUnits;

QgsDebugMsg( QString( "Preferred display units are %1" ).arg( QGis::toLiteral( mDisplayUnits ) ) );
QgsDebugMsg( QString( "Preferred display units are %1" ).arg( QgsUnitTypes::encodeUnit( mDisplayUnits ) ) );

mDa.convertMeasurement( measure, myUnits, mDisplayUnits, isArea );
u = myUnits;
Expand Down
15 changes: 10 additions & 5 deletions src/app/qgsoptions.cpp
Expand Up @@ -40,6 +40,7 @@
#include "qgssymbollayerv2utils.h"
#include "qgscolordialog.h"
#include "qgsexpressioncontext.h"
#include "qgsunittypes.h"

#include <QInputDialog>
#include <QFileDialog>
Expand Down Expand Up @@ -459,7 +460,11 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl ) :
}

// Set the units for measuring
QGis::UnitType myDisplayUnits = QGis::fromLiteral( mSettings->value( "/qgis/measure/displayunits", QGis::toLiteral( QGis::Meters ) ).toString() );
bool ok = false;
QGis::UnitType myDisplayUnits = QgsUnitTypes::decodeDistanceUnit( mSettings->value( "/qgis/measure/displayunits" ).toString(), &ok );
if ( !ok )
myDisplayUnits = QGis::Meters;

if ( myDisplayUnits == QGis::Feet )
{
radFeet->setChecked( true );
Expand Down Expand Up @@ -1241,19 +1246,19 @@ void QgsOptions::saveOptions()

if ( radFeet->isChecked() )
{
mSettings->setValue( "/qgis/measure/displayunits", QGis::toLiteral( QGis::Feet ) );
mSettings->setValue( "/qgis/measure/displayunits", QgsUnitTypes::encodeUnit( QGis::Feet ) );
}
else if ( radNautical->isChecked() )
{
mSettings->setValue( "/qgis/measure/displayunits", QGis::toLiteral( QGis::NauticalMiles ) );
mSettings->setValue( "/qgis/measure/displayunits", QgsUnitTypes::encodeUnit( QGis::NauticalMiles ) );
}
else if ( radDegrees->isChecked() )
{
mSettings->setValue( "/qgis/measure/displayunits", QGis::toLiteral( QGis::Degrees ) );
mSettings->setValue( "/qgis/measure/displayunits", QgsUnitTypes::encodeUnit( QGis::Degrees ) );
}
else
{
mSettings->setValue( "/qgis/measure/displayunits", QGis::toLiteral( QGis::Meters ) );
mSettings->setValue( "/qgis/measure/displayunits", QgsUnitTypes::encodeUnit( QGis::Meters ) );
}

QString angleUnitString = "degrees";
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -192,6 +192,7 @@ SET(QGIS_CORE_SRCS
qgstracer.cpp
qgstransaction.cpp
qgstransactiongroup.cpp
qgsunittypes.cpp
qgsvectordataprovider.cpp
qgsvectorfilewriter.cpp
qgsvectorlayer.cpp
Expand Down Expand Up @@ -668,6 +669,7 @@ SET(QGIS_CORE_HDRS
qgstextlabelfeature.h
qgstolerance.h
qgstracer.h
qgsunittypes.h

qgsvectordataprovider.h
qgsvectorlayercache.h
Expand Down
7 changes: 4 additions & 3 deletions src/core/composer/qgscomposerscalebar.cpp
Expand Up @@ -29,6 +29,7 @@
#include "qgsproject.h"
#include "qgssymbollayerv2utils.h"
#include "qgsfontutils.h"
#include "qgsunittypes.h"
#include <QDomDocument>
#include <QDomElement>
#include <QFontMetricsF>
Expand Down Expand Up @@ -312,13 +313,13 @@ double QgsComposerScaleBar::mapWidth() const
switch ( mUnits )
{
case QgsComposerScaleBar::Feet:
measure /= QGis::fromUnitToUnitFactor( QGis::Feet, units );
measure /= QgsUnitTypes::fromUnitToUnitFactor( QGis::Feet, units );
break;
case QgsComposerScaleBar::NauticalMiles:
measure /= QGis::fromUnitToUnitFactor( QGis::NauticalMiles, units );
measure /= QgsUnitTypes::fromUnitToUnitFactor( QGis::NauticalMiles, units );
break;
case QgsComposerScaleBar::Meters:
measure /= QGis::fromUnitToUnitFactor( QGis::Meters, units );
measure /= QgsUnitTypes::fromUnitToUnitFactor( QGis::Meters, units );
break;
case QgsComposerScaleBar::MapUnits:
//avoid warning
Expand Down

0 comments on commit ddabad2

Please sign in to comment.