Skip to content

Commit

Permalink
Fix composer scale bar when crs units are non-meters and OTF is off (fix
Browse files Browse the repository at this point in the history
 #13610)

(cherry-picked from d56dcdb)
  • Loading branch information
nyalldawson committed Nov 18, 2015
1 parent 6320dcf commit 3667651
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 10 deletions.
24 changes: 17 additions & 7 deletions src/core/composer/qgscomposerscalebar.cpp
Expand Up @@ -209,14 +209,24 @@ double QgsComposerScaleBar::mapWidth() const
da.setSourceCrs( mComposition->mapSettings().destinationCrs().srsid() );
da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", "WGS84" ) );

double measure = da.measureLine( QgsPoint( composerMapRect.xMinimum(), composerMapRect.yMinimum() ), QgsPoint( composerMapRect.xMaximum(), composerMapRect.yMinimum() ) );
if ( mUnits == QgsComposerScaleBar::Feet )
{
measure /= QGis::fromUnitToUnitFactor( QGis::Feet, QGis::Meters );
}
else if ( mUnits == QgsComposerScaleBar::NauticalMiles )
QGis::UnitType units = QGis::Meters;
double measure = da.measureLine( QgsPoint( composerMapRect.xMinimum(), composerMapRect.yMinimum() ),
QgsPoint( composerMapRect.xMaximum(), composerMapRect.yMinimum() ),
units );
switch ( mUnits )
{
measure /= QGis::fromUnitToUnitFactor( QGis::NauticalMiles, QGis::Meters );
case QgsComposerScaleBar::Feet:
measure /= QGis::fromUnitToUnitFactor( QGis::Feet, units );
break;
case QgsComposerScaleBar::NauticalMiles:
measure /= QGis::fromUnitToUnitFactor( QGis::NauticalMiles, units );
break;
case QgsComposerScaleBar::Meters:
measure /= QGis::fromUnitToUnitFactor( QGis::Meters, units );
break;
case QgsComposerScaleBar::MapUnits:
//avoid warning
break;
}
return measure;
}
Expand Down
8 changes: 8 additions & 0 deletions src/core/qgsdistancearea.cpp
Expand Up @@ -460,8 +460,15 @@ double QgsDistanceArea::measureLine( const QList<QgsPoint> &points )
}

double QgsDistanceArea::measureLine( const QgsPoint &p1, const QgsPoint &p2 )
{
QGis::UnitType units;
return measureLine( p1, p2, units );
}

double QgsDistanceArea::measureLine( const QgsPoint& p1, const QgsPoint& p2, QGis::UnitType& units ) const
{
double result;
units = mCoordTransform->sourceCrs().mapUnits();

try
{
Expand All @@ -470,6 +477,7 @@ double QgsDistanceArea::measureLine( const QgsPoint &p1, const QgsPoint &p2 )
QgsDebugMsgLevel( QString( "Measuring from %1 to %2" ).arg( p1.toString( 4 ) ).arg( p2.toString( 4 ) ), 3 );
if ( mEllipsoidalMode && ( mEllipsoid != GEO_NONE ) )
{
units = QGis::Meters;
QgsDebugMsgLevel( QString( "Ellipsoidal calculations is enabled, using ellipsoid %1" ).arg( mEllipsoid ), 4 );
QgsDebugMsgLevel( QString( "From proj4 : %1" ).arg( mCoordTransform->sourceCrs().toProj4() ), 4 );
QgsDebugMsgLevel( QString( "To proj4 : %1" ).arg( mCoordTransform->destCRS().toProj4() ), 4 );
Expand Down
17 changes: 15 additions & 2 deletions src/core/qgsdistancearea.h
Expand Up @@ -95,8 +95,21 @@ class CORE_EXPORT QgsDistanceArea
//! measures line
double measureLine( const QList<QgsPoint>& points );

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

/** Measures length of line with one segment and returns units of distance.
* @param p1 start of line
* @param p2 end of line
* @param units will be set to units of measure
* @returns calculated distance between points. Distance units are stored in units parameter.
* @note added in QGIS 2.12
*/
double measureLine( const QgsPoint& p1, const QgsPoint& p2, QGis::UnitType& units ) const;

//! measures polygon area
double measurePolygon( const QList<QgsPoint>& points );
Expand Down
26 changes: 25 additions & 1 deletion tests/src/core/testqgsdistancearea.cpp
Expand Up @@ -163,7 +163,31 @@ void TestQgsDistanceArea::unit_conversions()
QString myTxt = QgsDistanceArea::textUnit( inputValue, 7, inputUnit, true, false );
QString expectedTxt = QLocale::system().toString( 2.4710538146717, 'g', 1 + 7 );
QVERIFY( myTxt.startsWith( expectedTxt ) ); // Ignore units for now.
};
}

void TestQgsDistanceArea::measureUnits()
{
//test regression #13610
QgsDistanceArea calc;
calc.setEllipsoidalMode( false );
calc.setEllipsoid( "NONE" );
calc.setSourceCrs( 254L );
QGis::UnitType units;
QgsPoint p1( 1341683.9854275715, 408256.9562717728 );
QgsPoint p2( 1349321.7807031618, 408256.9562717728 );

double result = calc.measureLine( p1, p2, units );
//no OTF, result will be in CRS unit (feet)
QCOMPARE( units, QGis::Feet );
QVERIFY( qgsDoubleNear( result, 7637.7952755903825, 0.001 ) );

calc.setEllipsoidalMode( true );
calc.setEllipsoid( "WGS84" );
result = calc.measureLine( p1, p2, units );
//OTF, result will be in meters
QCOMPARE( units, QGis::Meters );
QVERIFY( qgsDoubleNear( result, 2328.0988253106957, 0.001 ) );
}

QTEST_MAIN( TestQgsDistanceArea )
#include "testqgsdistancearea.moc"
Expand Down

0 comments on commit 3667651

Please sign in to comment.