Skip to content

Commit 3667651

Browse files
committed
Fix composer scale bar when crs units are non-meters and OTF is off (fix #13610)
(cherry-picked from d56dcdb)
1 parent 6320dcf commit 3667651

File tree

4 files changed

+65
-10
lines changed

4 files changed

+65
-10
lines changed

src/core/composer/qgscomposerscalebar.cpp

+17-7
Original file line numberDiff line numberDiff line change
@@ -209,14 +209,24 @@ double QgsComposerScaleBar::mapWidth() const
209209
da.setSourceCrs( mComposition->mapSettings().destinationCrs().srsid() );
210210
da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", "WGS84" ) );
211211

212-
double measure = da.measureLine( QgsPoint( composerMapRect.xMinimum(), composerMapRect.yMinimum() ), QgsPoint( composerMapRect.xMaximum(), composerMapRect.yMinimum() ) );
213-
if ( mUnits == QgsComposerScaleBar::Feet )
214-
{
215-
measure /= QGis::fromUnitToUnitFactor( QGis::Feet, QGis::Meters );
216-
}
217-
else if ( mUnits == QgsComposerScaleBar::NauticalMiles )
212+
QGis::UnitType units = QGis::Meters;
213+
double measure = da.measureLine( QgsPoint( composerMapRect.xMinimum(), composerMapRect.yMinimum() ),
214+
QgsPoint( composerMapRect.xMaximum(), composerMapRect.yMinimum() ),
215+
units );
216+
switch ( mUnits )
218217
{
219-
measure /= QGis::fromUnitToUnitFactor( QGis::NauticalMiles, QGis::Meters );
218+
case QgsComposerScaleBar::Feet:
219+
measure /= QGis::fromUnitToUnitFactor( QGis::Feet, units );
220+
break;
221+
case QgsComposerScaleBar::NauticalMiles:
222+
measure /= QGis::fromUnitToUnitFactor( QGis::NauticalMiles, units );
223+
break;
224+
case QgsComposerScaleBar::Meters:
225+
measure /= QGis::fromUnitToUnitFactor( QGis::Meters, units );
226+
break;
227+
case QgsComposerScaleBar::MapUnits:
228+
//avoid warning
229+
break;
220230
}
221231
return measure;
222232
}

src/core/qgsdistancearea.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,15 @@ double QgsDistanceArea::measureLine( const QList<QgsPoint> &points )
460460
}
461461

462462
double QgsDistanceArea::measureLine( const QgsPoint &p1, const QgsPoint &p2 )
463+
{
464+
QGis::UnitType units;
465+
return measureLine( p1, p2, units );
466+
}
467+
468+
double QgsDistanceArea::measureLine( const QgsPoint& p1, const QgsPoint& p2, QGis::UnitType& units ) const
463469
{
464470
double result;
471+
units = mCoordTransform->sourceCrs().mapUnits();
465472

466473
try
467474
{
@@ -470,6 +477,7 @@ double QgsDistanceArea::measureLine( const QgsPoint &p1, const QgsPoint &p2 )
470477
QgsDebugMsgLevel( QString( "Measuring from %1 to %2" ).arg( p1.toString( 4 ) ).arg( p2.toString( 4 ) ), 3 );
471478
if ( mEllipsoidalMode && ( mEllipsoid != GEO_NONE ) )
472479
{
480+
units = QGis::Meters;
473481
QgsDebugMsgLevel( QString( "Ellipsoidal calculations is enabled, using ellipsoid %1" ).arg( mEllipsoid ), 4 );
474482
QgsDebugMsgLevel( QString( "From proj4 : %1" ).arg( mCoordTransform->sourceCrs().toProj4() ), 4 );
475483
QgsDebugMsgLevel( QString( "To proj4 : %1" ).arg( mCoordTransform->destCRS().toProj4() ), 4 );

src/core/qgsdistancearea.h

+15-2
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,21 @@ class CORE_EXPORT QgsDistanceArea
9595
//! measures line
9696
double measureLine( const QList<QgsPoint>& points );
9797

98-
//! measures line with one segment
99-
double measureLine( const QgsPoint& p1, const QgsPoint& p2 );
98+
/** Measures length of line with one segment
99+
* @param p1 start of line
100+
* @param p2 end of line
101+
* @returns distance in meters, or map units if cartesian calculation was performed
102+
*/
103+
double measureLine( const QgsPoint& p1, const QgsPoint& p2 ) const;
104+
105+
/** Measures length of line with one segment and returns units of distance.
106+
* @param p1 start of line
107+
* @param p2 end of line
108+
* @param units will be set to units of measure
109+
* @returns calculated distance between points. Distance units are stored in units parameter.
110+
* @note added in QGIS 2.12
111+
*/
112+
double measureLine( const QgsPoint& p1, const QgsPoint& p2, QGis::UnitType& units ) const;
100113

101114
//! measures polygon area
102115
double measurePolygon( const QList<QgsPoint>& points );

tests/src/core/testqgsdistancearea.cpp

+25-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,31 @@ void TestQgsDistanceArea::unit_conversions()
163163
QString myTxt = QgsDistanceArea::textUnit( inputValue, 7, inputUnit, true, false );
164164
QString expectedTxt = QLocale::system().toString( 2.4710538146717, 'g', 1 + 7 );
165165
QVERIFY( myTxt.startsWith( expectedTxt ) ); // Ignore units for now.
166-
};
166+
}
167+
168+
void TestQgsDistanceArea::measureUnits()
169+
{
170+
//test regression #13610
171+
QgsDistanceArea calc;
172+
calc.setEllipsoidalMode( false );
173+
calc.setEllipsoid( "NONE" );
174+
calc.setSourceCrs( 254L );
175+
QGis::UnitType units;
176+
QgsPoint p1( 1341683.9854275715, 408256.9562717728 );
177+
QgsPoint p2( 1349321.7807031618, 408256.9562717728 );
178+
179+
double result = calc.measureLine( p1, p2, units );
180+
//no OTF, result will be in CRS unit (feet)
181+
QCOMPARE( units, QGis::Feet );
182+
QVERIFY( qgsDoubleNear( result, 7637.7952755903825, 0.001 ) );
183+
184+
calc.setEllipsoidalMode( true );
185+
calc.setEllipsoid( "WGS84" );
186+
result = calc.measureLine( p1, p2, units );
187+
//OTF, result will be in meters
188+
QCOMPARE( units, QGis::Meters );
189+
QVERIFY( qgsDoubleNear( result, 2328.0988253106957, 0.001 ) );
190+
}
167191

168192
QTEST_MAIN( TestQgsDistanceArea )
169193
#include "testqgsdistancearea.moc"

0 commit comments

Comments
 (0)