Skip to content

Commit d56dcdb

Browse files
committed
Fix composer scale bar when crs units are non-meters and OTF is off (fix #13610)
1 parent 68f11d4 commit d56dcdb

File tree

4 files changed

+66
-8
lines changed

4 files changed

+66
-8
lines changed

src/core/composer/qgscomposerscalebar.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -305,14 +305,24 @@ double QgsComposerScaleBar::mapWidth() const
305305
da.setSourceCrs( mComposition->mapSettings().destinationCrs().srsid() );
306306
da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", "WGS84" ) );
307307

308-
double measure = da.measureLine( QgsPoint( composerMapRect.xMinimum(), composerMapRect.yMinimum() ), QgsPoint( composerMapRect.xMaximum(), composerMapRect.yMinimum() ) );
309-
if ( mUnits == QgsComposerScaleBar::Feet )
310-
{
311-
measure /= QGis::fromUnitToUnitFactor( QGis::Feet, QGis::Meters );
312-
}
313-
else if ( mUnits == QgsComposerScaleBar::NauticalMiles )
308+
QGis::UnitType units = QGis::Meters;
309+
double measure = da.measureLine( QgsPoint( composerMapRect.xMinimum(), composerMapRect.yMinimum() ),
310+
QgsPoint( composerMapRect.xMaximum(), composerMapRect.yMinimum() ),
311+
units );
312+
switch ( mUnits )
314313
{
315-
measure /= QGis::fromUnitToUnitFactor( QGis::NauticalMiles, QGis::Meters );
314+
case QgsComposerScaleBar::Feet:
315+
measure /= QGis::fromUnitToUnitFactor( QGis::Feet, units );
316+
break;
317+
case QgsComposerScaleBar::NauticalMiles:
318+
measure /= QGis::fromUnitToUnitFactor( QGis::NauticalMiles, units );
319+
break;
320+
case QgsComposerScaleBar::Meters:
321+
measure /= QGis::fromUnitToUnitFactor( QGis::Meters, units );
322+
break;
323+
case QgsComposerScaleBar::MapUnits:
324+
//avoid warning
325+
break;
316326
}
317327
return measure;
318328
}

src/core/qgsdistancearea.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,8 +486,15 @@ double QgsDistanceArea::measureLine( const QList<QgsPoint> &points ) const
486486
}
487487

488488
double QgsDistanceArea::measureLine( const QgsPoint &p1, const QgsPoint &p2 ) const
489+
{
490+
QGis::UnitType units;
491+
return measureLine( p1, p2, units );
492+
}
493+
494+
double QgsDistanceArea::measureLine( const QgsPoint& p1, const QgsPoint& p2, QGis::UnitType& units ) const
489495
{
490496
double result;
497+
units = mCoordTransform->sourceCrs().mapUnits();
491498

492499
try
493500
{
@@ -496,6 +503,7 @@ double QgsDistanceArea::measureLine( const QgsPoint &p1, const QgsPoint &p2 ) co
496503
QgsDebugMsgLevel( QString( "Measuring from %1 to %2" ).arg( p1.toString( 4 ), p2.toString( 4 ) ), 3 );
497504
if ( mEllipsoidalMode && ( mEllipsoid != GEO_NONE ) )
498505
{
506+
units = QGis::Meters;
499507
QgsDebugMsgLevel( QString( "Ellipsoidal calculations is enabled, using ellipsoid %1" ).arg( mEllipsoid ), 4 );
500508
QgsDebugMsgLevel( QString( "From proj4 : %1" ).arg( mCoordTransform->sourceCrs().toProj4() ), 4 );
501509
QgsDebugMsgLevel( QString( "To proj4 : %1" ).arg( mCoordTransform->destCRS().toProj4() ), 4 );

src/core/qgsdistancearea.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,22 @@ class CORE_EXPORT QgsDistanceArea
118118
//! measures line
119119
double measureLine( const QList<QgsPoint>& points ) const;
120120

121-
//! measures line with one segment
121+
/** Measures length of line with one segment
122+
* @param p1 start of line
123+
* @param p2 end of line
124+
* @returns distance in meters, or map units if cartesian calculation was performed
125+
*/
122126
double measureLine( const QgsPoint& p1, const QgsPoint& p2 ) const;
123127

128+
/** Measures length of line with one segment and returns units of distance.
129+
* @param p1 start of line
130+
* @param p2 end of line
131+
* @param units will be set to units of measure
132+
* @returns calculated distance between points. Distance units are stored in units parameter.
133+
* @note added in QGIS 2.12
134+
*/
135+
double measureLine( const QgsPoint& p1, const QgsPoint& p2, QGis::UnitType& units ) const;
136+
124137
//! measures polygon area
125138
double measurePolygon( const QList<QgsPoint>& points ) const;
126139

tests/src/core/testqgsdistancearea.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#include "qgslogger.h"
2626
#include "qgsgeometryfactory.h"
2727
#include "qgsgeometry.h"
28+
#include "qgis.h"
29+
2830

2931
class TestQgsDistanceArea: public QObject
3032
{
@@ -38,6 +40,7 @@ class TestQgsDistanceArea: public QObject
3840
void unit_conversions();
3941
void regression13601();
4042
void collections();
43+
void measureUnits();
4144
};
4245

4346
void TestQgsDistanceArea::initTestCase()
@@ -221,6 +224,30 @@ void TestQgsDistanceArea::collections()
221224
Q_NOWARN_DEPRECATED_POP
222225
}
223226

227+
void TestQgsDistanceArea::measureUnits()
228+
{
229+
//test regression #13610
230+
QgsDistanceArea calc;
231+
calc.setEllipsoidalMode( false );
232+
calc.setEllipsoid( "NONE" );
233+
calc.setSourceCrs( 254L );
234+
QGis::UnitType units;
235+
QgsPoint p1( 1341683.9854275715, 408256.9562717728 );
236+
QgsPoint p2( 1349321.7807031618, 408256.9562717728 );
237+
238+
double result = calc.measureLine( p1, p2, units );
239+
//no OTF, result will be in CRS unit (feet)
240+
QCOMPARE( units, QGis::Feet );
241+
QVERIFY( qgsDoubleNear( result, 7637.7952755903825, 0.001 ) );
242+
243+
calc.setEllipsoidalMode( true );
244+
calc.setEllipsoid( "WGS84" );
245+
result = calc.measureLine( p1, p2, units );
246+
//OTF, result will be in meters
247+
QCOMPARE( units, QGis::Meters );
248+
QVERIFY( qgsDoubleNear( result, 2328.0988253106957, 0.001 ) );
249+
}
250+
224251
QTEST_MAIN( TestQgsDistanceArea )
225252
#include "testqgsdistancearea.moc"
226253

0 commit comments

Comments
 (0)