Skip to content

Commit a19886d

Browse files
committed
Fix #9951 (perimeter completely wrong with OTF on)
With OTF on and computation on an ellipsoid, the coordinates were transformed twice(!) when measuring perimeter.
1 parent 1d1eed4 commit a19886d

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

python/core/qgsdistancearea.sip

+5
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ class QgsDistanceArea
9999
double computeDistanceBearing( const QgsPoint& p1, const QgsPoint& p2,
100100
double* course1 = NULL, double* course2 = NULL );
101101

102+
//! uses flat / planimetric / Euclidean distance
103+
double computeDistanceFlat( const QgsPoint& p1, const QgsPoint& p2 );
104+
105+
//! calculate distance with given coordinates (does not do a transform anymore)
106+
double computeDistance( const QList<QgsPoint>& points );
102107

103108
/**
104109
calculates area of polygon on ellipsoid

src/core/qgsdistancearea.cpp

+44-2
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ double QgsDistanceArea::measureLine( const QgsPoint &p1, const QgsPoint &p2 )
474474
else
475475
{
476476
QgsDebugMsgLevel( "Cartesian calculation on canvas coordinates", 4 );
477-
result = sqrt(( p2.x() - p1.x() ) * ( p2.x() - p1.x() ) + ( p2.y() - p1.y() ) * ( p2.y() - p1.y() ) );
477+
result = computeDistanceFlat( p1, p2 );
478478
}
479479
}
480480
catch ( QgsCsException &cse )
@@ -565,7 +565,7 @@ const unsigned char *QgsDistanceArea::measurePolygon( const unsigned char* featu
565565
if ( idx == 0 )
566566
{
567567
// exterior ring
568-
*perimeter += measureLine( points );
568+
*perimeter += computeDistance( points );
569569
}
570570
}
571571
}
@@ -712,6 +712,48 @@ double QgsDistanceArea::computeDistanceBearing(
712712
return s;
713713
}
714714

715+
double QgsDistanceArea::computeDistanceFlat( const QgsPoint& p1, const QgsPoint& p2 )
716+
{
717+
return sqrt( ( p2.x() - p1.x() ) * ( p2.x() - p1.x() ) + ( p2.y() - p1.y() ) * ( p2.y() - p1.y() ) );
718+
}
719+
720+
double QgsDistanceArea::computeDistance( const QList<QgsPoint>& points )
721+
{
722+
if ( points.size() < 2 )
723+
return 0;
724+
725+
double total = 0;
726+
QgsPoint p1, p2;
727+
728+
try
729+
{
730+
p1 = points[0];
731+
732+
for ( QList<QgsPoint>::const_iterator i = points.begin(); i != points.end(); ++i )
733+
{
734+
p2 = *i;
735+
if ( mEllipsoidalMode && ( mEllipsoid != GEO_NONE ) )
736+
{
737+
total += computeDistanceBearing( p1, p2 );
738+
}
739+
else
740+
{
741+
total += computeDistanceFlat( p1, p2 );
742+
}
743+
744+
p1 = p2;
745+
}
746+
747+
return total;
748+
}
749+
catch ( QgsCsException &cse )
750+
{
751+
Q_UNUSED( cse );
752+
QgsMessageLog::logMessage( QObject::tr( "Caught a coordinate system exception while trying to transform a point. Unable to calculate line length." ) );
753+
return 0.0;
754+
}
755+
}
756+
715757

716758

717759
///////////////////////////////////////////////////////////

src/core/qgsdistancearea.h

+5
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ class CORE_EXPORT QgsDistanceArea
130130
double computeDistanceBearing( const QgsPoint& p1, const QgsPoint& p2,
131131
double* course1 = NULL, double* course2 = NULL );
132132

133+
//! uses flat / planimetric / Euclidean distance
134+
double computeDistanceFlat( const QgsPoint& p1, const QgsPoint& p2 );
135+
136+
//! calculate distance with given coordinates (does not do a transform anymore)
137+
double computeDistance( const QList<QgsPoint>& points );
133138

134139
/**
135140
calculates area of polygon on ellipsoid

0 commit comments

Comments
 (0)