Skip to content

Commit ae08961

Browse files
committed
Merge pull request #208 from homann/issue1969
Issue1969 - Improvements to use of measurement functionality
2 parents ca7fa30 + 6862a94 commit ae08961

18 files changed

+7486
-3703
lines changed

i18n/qgis_sv.ts

Lines changed: 7274 additions & 3589 deletions
Large diffs are not rendered by default.

python/core/qgsdistancearea.sip

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ class QgsDistanceArea
1414
~QgsDistanceArea();
1515

1616
//! sets whether coordinates must be projected to ellipsoid before measuring
17-
void setProjectionsEnabled(bool flag);
17+
void setEllipsoidalMode(bool flag);
18+
void setProjectionsEnabled(bool flag) /Deprecated/;
1819

1920
//! returns projections enabled flag
20-
bool hasCrsTransformEnabled();
21+
bool ellipsoidalEnabled();
22+
bool hasCrsTransformEnabled() /Deprecated/;
2123

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

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

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

src/analysis/network/qgsgraphbuilderintr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class ANALYSIS_EXPORT QgsGraphBuilderInterface
4646
{
4747
mDa.setSourceCrs( mCrs.srsid() );
4848
mDa.setEllipsoid( ellipsoidID );
49-
mDa.setProjectionsEnabled( ctfEnabled );
49+
mDa.setEllipsoidalMode( ctfEnabled );
5050
}
5151

5252
//! Destructor

src/app/qgsmaptoolidentify.cpp

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ bool QgsMapToolIdentify::identifyVectorLayer( QgsVectorLayer *layer, int x, int
245245
QgsDistanceArea calc;
246246
if ( !featureList.count() == 0 )
247247
{
248-
calc.setProjectionsEnabled( mCanvas->hasCrsTransformEnabled() ); // project?
248+
calc.setEllipsoidalMode( mCanvas->hasCrsTransformEnabled() );
249249
calc.setEllipsoid( ellipsoid );
250250
calc.setSourceCrs( layer->crs().srsid() );
251251
}
@@ -387,43 +387,23 @@ void QgsMapToolIdentify::convertMeasurement( QgsDistanceArea &calc, double &meas
387387
// Helper for converting between meters and feet
388388
// The parameter &u is out only...
389389

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

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

404-
// Only convert between meters and feet
405-
if ( myUnits == QGis::Meters && myDisplayUnitsTxt == "feet" )
397+
QGis::UnitType displayUnits;
398+
if ( myDisplayUnitsTxt == "feet" )
406399
{
407-
QgsDebugMsg( QString( "Converting %1 meters" ).arg( QString::number( measure ) ) );
408-
measure /= 0.3048;
409-
if ( isArea )
410-
{
411-
measure /= 0.3048;
412-
}
413-
QgsDebugMsg( QString( "to %1 feet" ).arg( QString::number( measure ) ) );
414-
myUnits = QGis::Feet;
400+
displayUnits = QGis::Feet;
415401
}
416-
if ( myUnits == QGis::Feet && myDisplayUnitsTxt == "meters" )
402+
else
417403
{
418-
QgsDebugMsg( QString( "Converting %1 feet" ).arg( QString::number( measure ) ) );
419-
measure *= 0.3048;
420-
if ( isArea )
421-
{
422-
measure *= 0.3048;
423-
}
424-
QgsDebugMsg( QString( "to %1 meters" ).arg( QString::number( measure ) ) );
425-
myUnits = QGis::Meters;
404+
displayUnits = QGis::Meters;
426405
}
427406

407+
calc.convertMeasurement( measure, myUnits, displayUnits, isArea );
428408
u = myUnits;
429409
}

src/app/qgsmaptoolmeasureangle.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ void QgsMapToolMeasureAngle::configureDistanceArea()
183183
QString ellipsoidId = settings.value( "/qgis/measure/ellipsoid", "WGS84" ).toString();
184184
mDa.setSourceCrs( mCanvas->mapRenderer()->destinationCrs().srsid() );
185185
mDa.setEllipsoid( ellipsoidId );
186-
mDa.setProjectionsEnabled( mResultDisplay->projectionEnabled() );
186+
mDa.setEllipsoidalMode( mResultDisplay->projectionEnabled() ); // FIXME (not when proj is turned off)
187187
}
188188

189189

src/app/qgsmeasuredialog.cpp

Lines changed: 55 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ QgsMeasureDialog::QgsMeasureDialog( QgsMeasureTool* tool, Qt::WFlags f )
5959

6060
connect( mcbProjectionEnabled, SIGNAL( stateChanged( int ) ),
6161
this, SLOT( changeProjectionEnabledState() ) );
62+
// Update when project wide transformation has changed
63+
connect( mTool->canvas()->mapRenderer(), SIGNAL( hasCrsTransformEnabled( bool ) ),
64+
this, SLOT( changeProjectionEnabledState() ) );
65+
// Update when project CRS has changed
66+
connect( mTool->canvas()->mapRenderer(), SIGNAL( destinationSrsChanged() ),
67+
this, SLOT( changeProjectionEnabledState() ) );
6268

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

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

215222
void QgsMeasureDialog::updateUi()
216223
{
224+
// Only enable checkbox when project wide transformation is on
225+
mcbProjectionEnabled->setEnabled( mTool->canvas()->hasCrsTransformEnabled() );
226+
227+
configureDistanceArea();
228+
217229
QSettings settings;
218-
int decimalPlaces = settings.value( "/qgis/measure/decimalplaces", "3" ).toInt();
219230

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

225-
switch ( myDisplayUnits )
235+
QString toolTip = tr( "The calculations are based on:" );
236+
if ( ! mTool->canvas()->hasCrsTransformEnabled() )
226237
{
227-
case QGis::Meters:
228-
mTable->setHeaderLabels( QStringList( tr( "Segments (in meters)" ) ) );
229-
break;
230-
case QGis::Feet:
231-
mTable->setHeaderLabels( QStringList( tr( "Segments (in feet)" ) ) );
232-
break;
233-
case QGis::Degrees:
234-
mTable->setHeaderLabels( QStringList( tr( "Segments (in degrees)" ) ) );
235-
break;
236-
case QGis::UnknownUnit:
237-
mTable->setHeaderLabels( QStringList( tr( "Segments" ) ) );
238+
toolTip += "<br> * " + tr( "Project CRS transformation is turned off." ) + " ";
239+
toolTip += tr( "Canvas units setting is taken from project properties setting (%1)." ).arg( QGis::tr( mapUnits ) );
240+
toolTip += "<br> * " + tr( "Ellipsoidal calculation is not possible, as project CRS is undefined." );
241+
}
242+
else
243+
{
244+
if ( mDa.ellipsoidalEnabled() )
245+
{
246+
toolTip += "<br> * " + tr( "Project CRS transformation is turned on and ellipsoidal calculation is selected." ) + " ";
247+
toolTip += "<br> * " + tr( "The coordinates are transformed to the chosen ellipsoid (%1), and the result is in meters" ).arg( mDa.ellipsoid() );
248+
}
249+
else
250+
{
251+
toolTip += "<br> * " + tr( "Project CRS transformation is turned on but ellipsoidal calculation is not selected." );
252+
toolTip += "<br> * " + tr( "The canvas units setting is taken from the project CRS (%1)." ).arg( QGis::tr( mapUnits ) );
253+
}
238254
}
239255

256+
if (( mapUnits == QGis::Meters && displayUnits == QGis::Feet ) || ( mapUnits == QGis::Feet && displayUnits == QGis::Meters ) )
257+
{
258+
toolTip += "<br> * " + tr( "Finally, the value is converted from %2 to %3." ).arg( QGis::tr( mapUnits ) ).arg( QGis::tr( displayUnits ) );
259+
}
260+
261+
editTotal->setToolTip( toolTip );
262+
mTable->setToolTip( toolTip );
263+
264+
int decimalPlaces = settings.value( "/qgis/measure/decimalplaces", "3" ).toInt();
265+
266+
mTable->setHeaderLabels( QStringList( tr( "Segments [%1]" ).arg( QGis::tr( displayUnits ) ) ) );
267+
240268
if ( mMeasureArea )
241269
{
242270
mTable->hide();
@@ -247,52 +275,23 @@ void QgsMeasureDialog::updateUi()
247275
mTable->show();
248276
editTotal->setText( formatDistance( 0, decimalPlaces ) );
249277
}
250-
251-
configureDistanceArea();
252278
}
253279

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

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

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

272-
// Only convert between meters and feet
273-
if ( myUnits == QGis::Meters && myDisplayUnitsTxt == "feet" )
274-
{
275-
QgsDebugMsg( QString( "Converting %1 meters" ).arg( QString::number( measure ) ) );
276-
measure /= 0.3048;
277-
if ( isArea )
278-
{
279-
measure /= 0.3048;
280-
}
281-
QgsDebugMsg( QString( "to %1 feet" ).arg( QString::number( measure ) ) );
282-
myUnits = QGis::Feet;
283-
}
284-
if ( myUnits == QGis::Feet && myDisplayUnitsTxt == "meters" )
285-
{
286-
QgsDebugMsg( QString( "Converting %1 feet" ).arg( QString::number( measure ) ) );
287-
measure *= 0.3048;
288-
if ( isArea )
289-
{
290-
measure *= 0.3048;
291-
}
292-
QgsDebugMsg( QString( "to %1 meters" ).arg( QString::number( measure ) ) );
293-
myUnits = QGis::Meters;
294-
}
292+
QgsDebugMsg( QString( "Preferred display units are %1" ).arg( QGis::toLiteral( displayUnits ) ) );
295293

294+
mDa.convertMeasurement( measure, myUnits, displayUnits, isArea );
296295
u = myUnits;
297296
}
298297

@@ -301,9 +300,13 @@ void QgsMeasureDialog::changeProjectionEnabledState()
301300
// store value
302301
QSettings settings;
303302
if ( mcbProjectionEnabled->isChecked() )
303+
{
304304
settings.setValue( "/qgis/measure/projectionEnabled", 2 );
305+
}
305306
else
307+
{
306308
settings.setValue( "/qgis/measure/projectionEnabled", 0 );
309+
}
307310

308311
// clear interface
309312
mTable->clear();
@@ -362,5 +365,6 @@ void QgsMeasureDialog::configureDistanceArea()
362365
QString ellipsoidId = settings.value( "/qgis/measure/ellipsoid", "WGS84" ).toString();
363366
mDa.setSourceCrs( mTool->canvas()->mapRenderer()->destinationCrs().srsid() );
364367
mDa.setEllipsoid( ellipsoidId );
365-
mDa.setProjectionsEnabled( mcbProjectionEnabled->isChecked() );
368+
// Only use ellipsoidal calculation when project wide transformation is enabled.
369+
mDa.setEllipsoidalMode( mcbProjectionEnabled->isChecked() && mTool->canvas()->hasCrsTransformEnabled() );
366370
}

src/app/qgsmeasuredialog.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ class QgsMeasureDialog : public QDialog, private Ui::QgsMeasureBase
6262

6363
//! Show the help for the dialog
6464
void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
65-
private slots:
66-
//! on change state projection enable
65+
66+
//! on change state projection/ellipsoid enable
6767
void changeProjectionEnabledState();
6868

6969
private:

src/core/composer/qgscomposerscalebar.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ double QgsComposerScaleBar::mapWidth() const
187187
else
188188
{
189189
QgsDistanceArea da;
190-
da.setProjectionsEnabled( true );
190+
da.setEllipsoidalMode( mComposerMap->mapRenderer()->hasCrsTransformEnabled() );
191191
da.setSourceCrs( mComposerMap->mapRenderer()->destinationCrs().srsid() );
192192
QSettings s;
193193
da.setEllipsoid( s.value( "/qgis/measure/ellipsoid", "WGS84" ).toString() );

src/core/qgis.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#ifndef QGSVERSION
2020
#include "qgsversion.h"
2121
#endif
22-
22+
#include <QCoreApplication>
2323
#include "qgsconfig.h"
2424

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

70+
7071
const double QGis::DEFAULT_IDENTIFY_RADIUS = 0.5;
7172

73+
// description strings for units
74+
// Order must match enum indices
75+
const char* QGis::qgisUnitTypes[] =
76+
{
77+
QT_TRANSLATE_NOOP( "QGis::UnitType", "meters" ),
78+
QT_TRANSLATE_NOOP( "QGis::UnitType", "feet" ),
79+
QT_TRANSLATE_NOOP( "QGis::UnitType", "degrees" ),
80+
QT_TRANSLATE_NOOP( "QGis::UnitType", "<unknown>" ),
81+
QT_TRANSLATE_NOOP( "QGis::UnitType", "degrees" ),
82+
QT_TRANSLATE_NOOP( "QGis::UnitType", "degrees" ),
83+
QT_TRANSLATE_NOOP( "QGis::UnitType", "degrees" )
84+
};
85+
86+
QGis::UnitType QGis::fromLiteral( QString literal, QGis::UnitType defaultType )
87+
{
88+
for ( unsigned int i = 0; i < ( sizeof( qgisUnitTypes ) / sizeof( qgisUnitTypes[0] ) ); i++ )
89+
{
90+
if ( literal == qgisUnitTypes[ i ] )
91+
{
92+
return static_cast<UnitType>( i );
93+
}
94+
}
95+
return defaultType;
96+
}
97+
98+
QString QGis::toLiteral( QGis::UnitType unit )
99+
{
100+
return QString( qgisUnitTypes[ static_cast<int>( unit )] );
101+
}
102+
103+
QString QGis::tr( QGis::UnitType unit )
104+
{
105+
return QCoreApplication::translate( "QGis::UnitType", qPrintable( toLiteral( unit ) ) );
106+
}

src/core/qgis.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include <QEvent>
2222
#include <QString>
23+
#include <QMetaType>
2324
#include <cfloat>
2425
#include <cmath>
2526
#include <qnumeric.h>
@@ -96,6 +97,13 @@ class CORE_EXPORT QGis
9697
DegreesDecimalMinutes = 2, // was 5
9798
};
9899

100+
// Provides the canonical name of the type value
101+
static QString toLiteral( QGis::UnitType unit );
102+
// Converts from the canonical name to the type value
103+
static UnitType fromLiteral( QString literal, QGis::UnitType defaultType = UnknownUnit );
104+
// Provides translated version of the type value
105+
static QString tr( QGis::UnitType unit );
106+
99107
//! User defined event types
100108
enum UserEvent
101109
{
@@ -109,6 +117,11 @@ class CORE_EXPORT QGis
109117
};
110118

111119
static const double DEFAULT_IDENTIFY_RADIUS;
120+
121+
private:
122+
// String representation of unit types (set in qgis.cpp)
123+
static const char *qgisUnitTypes[];
124+
112125
};
113126

114127
// hack to workaround warnings when casting void pointers

0 commit comments

Comments
 (0)