Skip to content
Permalink
Browse files

Merge pull request #208 from homann/issue1969

Issue1969 - Improvements to use of measurement functionality
  • Loading branch information
timlinux committed Aug 25, 2012
2 parents ca7fa30 + 6862a94 commit ae089619c2c75803776f7cc8279ed592ef053183

Large diffs are not rendered by default.

@@ -14,10 +14,12 @@ class QgsDistanceArea
~QgsDistanceArea();

//! sets whether coordinates must be projected to ellipsoid before measuring
void setProjectionsEnabled(bool flag);
void setEllipsoidalMode(bool flag);
void setProjectionsEnabled(bool flag) /Deprecated/;

//! returns projections enabled flag
bool hasCrsTransformEnabled();
bool ellipsoidalEnabled();
bool hasCrsTransformEnabled() /Deprecated/;

//! sets source spatial reference system (by QGIS CRS)
void setSourceCrs(long srsid);
@@ -67,4 +69,7 @@ class QgsDistanceArea

static QString textUnit( double value, int decimals, QGis::UnitType u, bool isArea, bool keepBaseUnit = false );

//! Helper for conversion between physical units
void convertMeasurement( double &measure, QGis::UnitType &measureUnits, QGis::UnitType displayUnits, bool isArea );

};
@@ -46,7 +46,7 @@ class ANALYSIS_EXPORT QgsGraphBuilderInterface
{
mDa.setSourceCrs( mCrs.srsid() );
mDa.setEllipsoid( ellipsoidID );
mDa.setProjectionsEnabled( ctfEnabled );
mDa.setEllipsoidalMode( ctfEnabled );
}

//! Destructor
@@ -245,7 +245,7 @@ bool QgsMapToolIdentify::identifyVectorLayer( QgsVectorLayer *layer, int x, int
QgsDistanceArea calc;
if ( !featureList.count() == 0 )
{
calc.setProjectionsEnabled( mCanvas->hasCrsTransformEnabled() ); // project?
calc.setEllipsoidalMode( mCanvas->hasCrsTransformEnabled() );
calc.setEllipsoid( ellipsoid );
calc.setSourceCrs( layer->crs().srsid() );
}
@@ -387,43 +387,23 @@ void QgsMapToolIdentify::convertMeasurement( QgsDistanceArea &calc, double &meas
// Helper for converting between meters and feet
// The parameter &u is out only...

// Get the canvas units
QGis::UnitType myUnits = mCanvas->mapUnits();
if (( myUnits == QGis::Degrees || myUnits == QGis::Feet ) &&
calc.ellipsoid() != "NONE" &&
calc.hasCrsTransformEnabled() )
{
// Measuring on an ellipsoid returns meters, and so does using projections???
myUnits = QGis::Meters;
QgsDebugMsg( "We're measuring on an ellipsoid or using projections, the system is returning meters" );
}

// Get the units for display
QSettings settings;
QString myDisplayUnitsTxt = settings.value( "/qgis/measure/displayunits", "meters" ).toString();

// Only convert between meters and feet
if ( myUnits == QGis::Meters && myDisplayUnitsTxt == "feet" )
QGis::UnitType displayUnits;
if ( myDisplayUnitsTxt == "feet" )
{
QgsDebugMsg( QString( "Converting %1 meters" ).arg( QString::number( measure ) ) );
measure /= 0.3048;
if ( isArea )
{
measure /= 0.3048;
}
QgsDebugMsg( QString( "to %1 feet" ).arg( QString::number( measure ) ) );
myUnits = QGis::Feet;
displayUnits = QGis::Feet;
}
if ( myUnits == QGis::Feet && myDisplayUnitsTxt == "meters" )
else
{
QgsDebugMsg( QString( "Converting %1 feet" ).arg( QString::number( measure ) ) );
measure *= 0.3048;
if ( isArea )
{
measure *= 0.3048;
}
QgsDebugMsg( QString( "to %1 meters" ).arg( QString::number( measure ) ) );
myUnits = QGis::Meters;
displayUnits = QGis::Meters;
}

calc.convertMeasurement( measure, myUnits, displayUnits, isArea );
u = myUnits;
}
@@ -183,7 +183,7 @@ void QgsMapToolMeasureAngle::configureDistanceArea()
QString ellipsoidId = settings.value( "/qgis/measure/ellipsoid", "WGS84" ).toString();
mDa.setSourceCrs( mCanvas->mapRenderer()->destinationCrs().srsid() );
mDa.setEllipsoid( ellipsoidId );
mDa.setProjectionsEnabled( mResultDisplay->projectionEnabled() );
mDa.setEllipsoidalMode( mResultDisplay->projectionEnabled() ); // FIXME (not when proj is turned off)
}


@@ -59,6 +59,12 @@ QgsMeasureDialog::QgsMeasureDialog( QgsMeasureTool* tool, Qt::WFlags f )

connect( mcbProjectionEnabled, SIGNAL( stateChanged( int ) ),
this, SLOT( changeProjectionEnabledState() ) );
// Update when project wide transformation has changed
connect( mTool->canvas()->mapRenderer(), SIGNAL( hasCrsTransformEnabled( bool ) ),
this, SLOT( changeProjectionEnabledState() ) );
// Update when project CRS has changed
connect( mTool->canvas()->mapRenderer(), SIGNAL( destinationSrsChanged() ),
this, SLOT( changeProjectionEnabledState() ) );

updateUi();
}
@@ -118,6 +124,7 @@ void QgsMeasureDialog::mouseMove( QgsPoint &point )
convertMeasurement( d, myDisplayUnits, false );
QTreeWidgetItem *item = mTable->topLevelItem( mTable->topLevelItemCount() - 1 );
item->setText( 0, QLocale::system().toString( d, 'f', decimalPlaces ) );
QgsDebugMsg( QString( "Final result is %1" ).arg( item->text( 0 ) ) );
}
}

@@ -214,29 +221,50 @@ QString QgsMeasureDialog::formatArea( double area, int decimalPlaces )

void QgsMeasureDialog::updateUi()
{
// Only enable checkbox when project wide transformation is on
mcbProjectionEnabled->setEnabled( mTool->canvas()->hasCrsTransformEnabled() );

configureDistanceArea();

QSettings settings;
int decimalPlaces = settings.value( "/qgis/measure/decimalplaces", "3" ).toInt();

double dummy = 1.0;
QGis::UnitType myDisplayUnits;
// The dummy distance is ignored
convertMeasurement( dummy, myDisplayUnits, false );
// Set tooltip to indicate how we calculate measurments
QGis::UnitType mapUnits = mTool->canvas()->mapUnits();
QGis::UnitType displayUnits = QGis::fromLiteral( settings.value( "/qgis/measure/displayunits", QGis::toLiteral( QGis::Meters ) ).toString() );

switch ( myDisplayUnits )
QString toolTip = tr( "The calculations are based on:" );
if ( ! mTool->canvas()->hasCrsTransformEnabled() )
{
case QGis::Meters:
mTable->setHeaderLabels( QStringList( tr( "Segments (in meters)" ) ) );
break;
case QGis::Feet:
mTable->setHeaderLabels( QStringList( tr( "Segments (in feet)" ) ) );
break;
case QGis::Degrees:
mTable->setHeaderLabels( QStringList( tr( "Segments (in degrees)" ) ) );
break;
case QGis::UnknownUnit:
mTable->setHeaderLabels( QStringList( tr( "Segments" ) ) );
toolTip += "<br> * " + tr( "Project CRS transformation is turned off." ) + " ";
toolTip += tr( "Canvas units setting is taken from project properties setting (%1)." ).arg( QGis::tr( mapUnits ) );
toolTip += "<br> * " + tr( "Ellipsoidal calculation is not possible, as project CRS is undefined." );
}
else
{
if ( mDa.ellipsoidalEnabled() )
{
toolTip += "<br> * " + tr( "Project CRS transformation is turned on and ellipsoidal calculation is selected." ) + " ";
toolTip += "<br> * " + tr( "The coordinates are transformed to the chosen ellipsoid (%1), and the result is in meters" ).arg( mDa.ellipsoid() );
}
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( mapUnits ) );
}
}

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

editTotal->setToolTip( toolTip );
mTable->setToolTip( toolTip );

int decimalPlaces = settings.value( "/qgis/measure/decimalplaces", "3" ).toInt();

mTable->setHeaderLabels( QStringList( tr( "Segments [%1]" ).arg( QGis::tr( displayUnits ) ) ) );

if ( mMeasureArea )
{
mTable->hide();
@@ -247,52 +275,23 @@ void QgsMeasureDialog::updateUi()
mTable->show();
editTotal->setText( formatDistance( 0, decimalPlaces ) );
}

configureDistanceArea();
}

void QgsMeasureDialog::convertMeasurement( double &measure, QGis::UnitType &u, bool isArea )
{
// Helper for converting between meters and feet
// The parameter &u is out only...

// Get the canvas units
QGis::UnitType myUnits = mTool->canvas()->mapUnits();
if (( myUnits == QGis::Degrees || myUnits == QGis::Feet ) &&
mcbProjectionEnabled->isChecked() )
{
// Measuring on an ellipsoid returns meters, and so does using projections???
myUnits = QGis::Meters;
QgsDebugMsg( "We're measuring on an ellipsoid or using projections, the system is returning meters" );
}

// Get the units for display
QSettings settings;
QString myDisplayUnitsTxt = settings.value( "/qgis/measure/displayunits", "meters" ).toString();
QGis::UnitType displayUnits = QGis::fromLiteral( settings.value( "/qgis/measure/displayunits", QGis::toLiteral( QGis::Meters ) ).toString() );

// Only convert between meters and feet
if ( myUnits == QGis::Meters && myDisplayUnitsTxt == "feet" )
{
QgsDebugMsg( QString( "Converting %1 meters" ).arg( QString::number( measure ) ) );
measure /= 0.3048;
if ( isArea )
{
measure /= 0.3048;
}
QgsDebugMsg( QString( "to %1 feet" ).arg( QString::number( measure ) ) );
myUnits = QGis::Feet;
}
if ( myUnits == QGis::Feet && myDisplayUnitsTxt == "meters" )
{
QgsDebugMsg( QString( "Converting %1 feet" ).arg( QString::number( measure ) ) );
measure *= 0.3048;
if ( isArea )
{
measure *= 0.3048;
}
QgsDebugMsg( QString( "to %1 meters" ).arg( QString::number( measure ) ) );
myUnits = QGis::Meters;
}
QgsDebugMsg( QString( "Preferred display units are %1" ).arg( QGis::toLiteral( displayUnits ) ) );

mDa.convertMeasurement( measure, myUnits, displayUnits, isArea );
u = myUnits;
}

@@ -301,9 +300,13 @@ void QgsMeasureDialog::changeProjectionEnabledState()
// store value
QSettings settings;
if ( mcbProjectionEnabled->isChecked() )
{
settings.setValue( "/qgis/measure/projectionEnabled", 2 );
}
else
{
settings.setValue( "/qgis/measure/projectionEnabled", 0 );
}

// clear interface
mTable->clear();
@@ -362,5 +365,6 @@ void QgsMeasureDialog::configureDistanceArea()
QString ellipsoidId = settings.value( "/qgis/measure/ellipsoid", "WGS84" ).toString();
mDa.setSourceCrs( mTool->canvas()->mapRenderer()->destinationCrs().srsid() );
mDa.setEllipsoid( ellipsoidId );
mDa.setProjectionsEnabled( mcbProjectionEnabled->isChecked() );
// Only use ellipsoidal calculation when project wide transformation is enabled.
mDa.setEllipsoidalMode( mcbProjectionEnabled->isChecked() && mTool->canvas()->hasCrsTransformEnabled() );
}
@@ -62,8 +62,8 @@ class QgsMeasureDialog : public QDialog, private Ui::QgsMeasureBase

//! Show the help for the dialog
void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
private slots:
//! on change state projection enable

//! on change state projection/ellipsoid enable
void changeProjectionEnabledState();

private:
@@ -187,7 +187,7 @@ double QgsComposerScaleBar::mapWidth() const
else
{
QgsDistanceArea da;
da.setProjectionsEnabled( true );
da.setEllipsoidalMode( mComposerMap->mapRenderer()->hasCrsTransformEnabled() );
da.setSourceCrs( mComposerMap->mapRenderer()->destinationCrs().srsid() );
QSettings s;
da.setEllipsoid( s.value( "/qgis/measure/ellipsoid", "WGS84" ).toString() );
@@ -19,7 +19,7 @@
#ifndef QGSVERSION
#include "qgsversion.h"
#endif

#include <QCoreApplication>
#include "qgsconfig.h"

#include <ogr_api.h>
@@ -67,5 +67,40 @@ const char* QGis::qgisFeatureTypes[] =
"WKBMultiPolygon"
};


const double QGis::DEFAULT_IDENTIFY_RADIUS = 0.5;

// description strings for units
// Order must match enum indices
const char* QGis::qgisUnitTypes[] =
{
QT_TRANSLATE_NOOP( "QGis::UnitType", "meters" ),
QT_TRANSLATE_NOOP( "QGis::UnitType", "feet" ),
QT_TRANSLATE_NOOP( "QGis::UnitType", "degrees" ),
QT_TRANSLATE_NOOP( "QGis::UnitType", "<unknown>" ),
QT_TRANSLATE_NOOP( "QGis::UnitType", "degrees" ),
QT_TRANSLATE_NOOP( "QGis::UnitType", "degrees" ),
QT_TRANSLATE_NOOP( "QGis::UnitType", "degrees" )
};

QGis::UnitType QGis::fromLiteral( QString literal, QGis::UnitType defaultType )
{
for ( unsigned int i = 0; i < ( sizeof( qgisUnitTypes ) / sizeof( qgisUnitTypes[0] ) ); i++ )
{
if ( literal == qgisUnitTypes[ i ] )
{
return static_cast<UnitType>( i );
}
}
return defaultType;
}

QString QGis::toLiteral( QGis::UnitType unit )
{
return QString( qgisUnitTypes[ static_cast<int>( unit )] );
}

QString QGis::tr( QGis::UnitType unit )
{
return QCoreApplication::translate( "QGis::UnitType", qPrintable( toLiteral( unit ) ) );
}
@@ -20,6 +20,7 @@

#include <QEvent>
#include <QString>
#include <QMetaType>
#include <cfloat>
#include <cmath>
#include <qnumeric.h>
@@ -96,6 +97,13 @@ class CORE_EXPORT QGis
DegreesDecimalMinutes = 2, // was 5
};

// Provides the canonical name of the type value
static QString toLiteral( QGis::UnitType unit );
// Converts from the canonical name to the type value
static UnitType fromLiteral( QString literal, QGis::UnitType defaultType = UnknownUnit );
// Provides translated version of the type value
static QString tr( QGis::UnitType unit );

//! User defined event types
enum UserEvent
{
@@ -109,6 +117,11 @@ class CORE_EXPORT QGis
};

static const double DEFAULT_IDENTIFY_RADIUS;

private:
// String representation of unit types (set in qgis.cpp)
static const char *qgisUnitTypes[];

};

// hack to workaround warnings when casting void pointers

0 comments on commit ae08961

Please sign in to comment.
You can’t perform that action at this time.