Skip to content

Commit

Permalink
Fix #9951 (perimeter completely wrong with OTF on)
Browse files Browse the repository at this point in the history
With OTF on and computation on an ellipsoid, the coordinates
were transformed twice(!) when measuring perimeter.
  • Loading branch information
wonder-sk committed Jun 10, 2014
1 parent 1d1eed4 commit a19886d
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 2 deletions.
5 changes: 5 additions & 0 deletions python/core/qgsdistancearea.sip
Expand Up @@ -99,6 +99,11 @@ class QgsDistanceArea
double computeDistanceBearing( const QgsPoint& p1, const QgsPoint& p2,
double* course1 = NULL, double* course2 = NULL );

//! uses flat / planimetric / Euclidean distance
double computeDistanceFlat( const QgsPoint& p1, const QgsPoint& p2 );

//! calculate distance with given coordinates (does not do a transform anymore)
double computeDistance( const QList<QgsPoint>& points );

/**
calculates area of polygon on ellipsoid
Expand Down
46 changes: 44 additions & 2 deletions src/core/qgsdistancearea.cpp
Expand Up @@ -474,7 +474,7 @@ double QgsDistanceArea::measureLine( const QgsPoint &p1, const QgsPoint &p2 )
else
{
QgsDebugMsgLevel( "Cartesian calculation on canvas coordinates", 4 );
result = sqrt(( p2.x() - p1.x() ) * ( p2.x() - p1.x() ) + ( p2.y() - p1.y() ) * ( p2.y() - p1.y() ) );
result = computeDistanceFlat( p1, p2 );
}
}
catch ( QgsCsException &cse )
Expand Down Expand Up @@ -565,7 +565,7 @@ const unsigned char *QgsDistanceArea::measurePolygon( const unsigned char* featu
if ( idx == 0 )
{
// exterior ring
*perimeter += measureLine( points );
*perimeter += computeDistance( points );
}
}
}
Expand Down Expand Up @@ -712,6 +712,48 @@ double QgsDistanceArea::computeDistanceBearing(
return s;
}

double QgsDistanceArea::computeDistanceFlat( const QgsPoint& p1, const QgsPoint& p2 )
{
return sqrt( ( p2.x() - p1.x() ) * ( p2.x() - p1.x() ) + ( p2.y() - p1.y() ) * ( p2.y() - p1.y() ) );
}

double QgsDistanceArea::computeDistance( const QList<QgsPoint>& points )
{
if ( points.size() < 2 )
return 0;

double total = 0;
QgsPoint p1, p2;

try
{
p1 = points[0];

for ( QList<QgsPoint>::const_iterator i = points.begin(); i != points.end(); ++i )
{
p2 = *i;
if ( mEllipsoidalMode && ( mEllipsoid != GEO_NONE ) )
{
total += computeDistanceBearing( p1, p2 );
}
else
{
total += computeDistanceFlat( p1, p2 );
}

p1 = p2;
}

return total;
}
catch ( QgsCsException &cse )
{
Q_UNUSED( cse );
QgsMessageLog::logMessage( QObject::tr( "Caught a coordinate system exception while trying to transform a point. Unable to calculate line length." ) );
return 0.0;
}
}



///////////////////////////////////////////////////////////
Expand Down
5 changes: 5 additions & 0 deletions src/core/qgsdistancearea.h
Expand Up @@ -130,6 +130,11 @@ class CORE_EXPORT QgsDistanceArea
double computeDistanceBearing( const QgsPoint& p1, const QgsPoint& p2,
double* course1 = NULL, double* course2 = NULL );

//! uses flat / planimetric / Euclidean distance
double computeDistanceFlat( const QgsPoint& p1, const QgsPoint& p2 );

//! calculate distance with given coordinates (does not do a transform anymore)
double computeDistance( const QList<QgsPoint>& points );

/**
calculates area of polygon on ellipsoid
Expand Down

0 comments on commit a19886d

Please sign in to comment.