00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <cmath>
00018 #include <sqlite3.h>
00019 #include <QDir>
00020 #include <QString>
00021 #include <QLocale>
00022 #include <QObject>
00023
00024 #include "qgis.h"
00025 #include "qgspoint.h"
00026 #include "qgscoordinatetransform.h"
00027 #include "qgscoordinatereferencesystem.h"
00028 #include "qgsgeometry.h"
00029 #include "qgsdistancearea.h"
00030 #include "qgsapplication.h"
00031 #include "qgslogger.h"
00032
00033
00034 #ifndef M_PI
00035 #define M_PI 3.14159265358979323846
00036 #endif
00037
00038 #define DEG2RAD(x) ((x)*M_PI/180)
00039
00040
00041 QgsDistanceArea::QgsDistanceArea()
00042 {
00043
00044 mProjectionsEnabled = false;
00045 mCoordTransform = new QgsCoordinateTransform;
00046 setSourceCrs( GEOCRS_ID );
00047 setEllipsoid( "WGS84" );
00048 }
00049
00050
00051 QgsDistanceArea::~QgsDistanceArea()
00052 {
00053 delete mCoordTransform;
00054 }
00055
00056
00057 void QgsDistanceArea::setProjectionsEnabled( bool flag )
00058 {
00059 mProjectionsEnabled = flag;
00060 }
00061
00062 void QgsDistanceArea::setSourceCrs( long srsid )
00063 {
00064 QgsCoordinateReferenceSystem srcCRS;
00065 srcCRS.createFromSrsId( srsid );
00066 mCoordTransform->setSourceCrs( srcCRS );
00067 }
00068
00069 void QgsDistanceArea::setSourceEpsgCrsId( long epsgId )
00070 {
00071 QgsCoordinateReferenceSystem srcCRS;
00072 srcCRS.createFromEpsg( epsgId );
00073 mCoordTransform->setSourceCrs( srcCRS );
00074 }
00075
00076 bool QgsDistanceArea::setEllipsoid( const QString& ellipsoid )
00077 {
00078 QString radius, parameter2;
00079
00080
00081
00082 sqlite3 *myDatabase;
00083 const char *myTail;
00084 sqlite3_stmt *myPreparedStatement;
00085 int myResult;
00086
00087
00088 if ( ellipsoid == "NONE" )
00089 {
00090 mEllipsoid = "NONE";
00091 return true;
00092 }
00093
00094
00095 myResult = sqlite3_open( QgsApplication::srsDbFilePath().toUtf8().data(), &myDatabase );
00096 if ( myResult )
00097 {
00098 QgsDebugMsg( QString( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
00099
00100
00101 return false;
00102 }
00103
00104 QString mySql = "select radius, parameter2 from tbl_ellipsoid where acronym='" + ellipsoid + "'";
00105 myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
00106
00107 if ( myResult == SQLITE_OK )
00108 {
00109 if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
00110 {
00111 radius = QString(( char * )sqlite3_column_text( myPreparedStatement, 0 ) );
00112 parameter2 = QString(( char * )sqlite3_column_text( myPreparedStatement, 1 ) );
00113 }
00114 }
00115
00116 sqlite3_finalize( myPreparedStatement );
00117 sqlite3_close( myDatabase );
00118
00119
00120 if ( radius.isEmpty() || parameter2.isEmpty() )
00121 {
00122 QgsDebugMsg( QString( "setEllipsoid: no row in tbl_ellipsoid for acronym '%1'" ).arg( ellipsoid ) );
00123 return false;
00124 }
00125
00126
00127 if ( radius.left( 2 ) == "a=" )
00128 mSemiMajor = radius.mid( 2 ).toDouble();
00129 else
00130 {
00131 QgsDebugMsg( QString( "setEllipsoid: wrong format of radius field: '%1'" ).arg( radius ) );
00132 return false;
00133 }
00134
00135
00136
00137
00138 if ( parameter2.left( 2 ) == "b=" )
00139 {
00140 mSemiMinor = parameter2.mid( 2 ).toDouble();
00141 mInvFlattening = mSemiMajor / ( mSemiMajor - mSemiMinor );
00142 }
00143 else if ( parameter2.left( 3 ) == "rf=" )
00144 {
00145 mInvFlattening = parameter2.mid( 3 ).toDouble();
00146 mSemiMinor = mSemiMajor - ( mInvFlattening / mSemiMajor );
00147 }
00148 else
00149 {
00150 QgsDebugMsg( QString( "setEllipsoid: wrong format of parameter2 field: '%1'" ).arg( parameter2 ) );
00151 return false;
00152 }
00153
00154 QgsDebugMsg( QString( "setEllipsoid: a=%1, b=%2, 1/f=%3" ).arg( mSemiMajor ).arg( mSemiMinor ).arg( mInvFlattening ) );
00155
00156
00157
00158 QString proj4 = "+proj=longlat +ellps=";
00159 proj4 += ellipsoid;
00160 proj4 += " +no_defs";
00161 QgsCoordinateReferenceSystem destCRS;
00162 destCRS.createFromProj4( proj4 );
00163
00164
00165 mCoordTransform->setDestCRS( destCRS );
00166
00167
00168 computeAreaInit();
00169
00170 mEllipsoid = ellipsoid;
00171 return true;
00172 }
00173
00174
00175 double QgsDistanceArea::measure( QgsGeometry* geometry )
00176 {
00177 if ( !geometry )
00178 return 0.0;
00179
00180 unsigned char* wkb = geometry->asWkb();
00181 if ( !wkb )
00182 return 0.0;
00183
00184 unsigned char* ptr;
00185 unsigned int wkbType;
00186 double res, resTotal = 0;
00187 int count, i;
00188
00189 memcpy( &wkbType, ( wkb + 1 ), sizeof( wkbType ) );
00190
00191
00192 bool hasZptr = false;
00193
00194 switch ( wkbType )
00195 {
00196 case QGis::WKBLineString25D:
00197 hasZptr = true;
00198 case QGis::WKBLineString:
00199 measureLine( wkb, &res, hasZptr );
00200 QgsDebugMsg( "returning " + QString::number( res ) );
00201 return res;
00202
00203 case QGis::WKBMultiLineString25D:
00204 hasZptr = true;
00205 case QGis::WKBMultiLineString:
00206 count = *(( int* )( wkb + 5 ) );
00207 ptr = wkb + 9;
00208 for ( i = 0; i < count; i++ )
00209 {
00210 ptr = measureLine( ptr, &res, hasZptr );
00211 resTotal += res;
00212 }
00213 QgsDebugMsg( "returning " + QString::number( resTotal ) );
00214 return resTotal;
00215
00216 case QGis::WKBPolygon25D:
00217 hasZptr = true;
00218 case QGis::WKBPolygon:
00219 measurePolygon( wkb, &res, hasZptr );
00220 QgsDebugMsg( "returning " + QString::number( res ) );
00221 return res;
00222
00223 case QGis::WKBMultiPolygon25D:
00224 hasZptr = true;
00225 case QGis::WKBMultiPolygon:
00226 count = *(( int* )( wkb + 5 ) );
00227 ptr = wkb + 9;
00228 for ( i = 0; i < count; i++ )
00229 {
00230 ptr = measurePolygon( ptr, &res, hasZptr );
00231 resTotal += res;
00232 }
00233 QgsDebugMsg( "returning " + QString::number( resTotal ) );
00234 return resTotal;
00235
00236 default:
00237 QgsDebugMsg( QString( "measure: unexpected geometry type: %1" ).arg( wkbType ) );
00238 return 0;
00239 }
00240 }
00241
00242
00243 unsigned char* QgsDistanceArea::measureLine( unsigned char* feature, double* area, bool hasZptr )
00244 {
00245 unsigned char *ptr = feature + 5;
00246 unsigned int nPoints = *(( int* )ptr );
00247 ptr = feature + 9;
00248
00249 QList<QgsPoint> points;
00250 double x, y;
00251
00252 QgsDebugMsg( "This feature WKB has " + QString::number( nPoints ) + " points" );
00253
00254 for ( unsigned int i = 0; i < nPoints; ++i )
00255 {
00256 x = *(( double * ) ptr );
00257 ptr += sizeof( double );
00258 y = *(( double * ) ptr );
00259 ptr += sizeof( double );
00260 if ( hasZptr )
00261 {
00262
00263 ptr += sizeof( double );
00264 }
00265
00266 points.append( QgsPoint( x, y ) );
00267 }
00268
00269 *area = measureLine( points );
00270 return ptr;
00271 }
00272
00273 double QgsDistanceArea::measureLine( const QList<QgsPoint>& points )
00274 {
00275 if ( points.size() < 2 )
00276 return 0;
00277
00278 double total = 0;
00279 QgsPoint p1, p2;
00280
00281 try
00282 {
00283 if ( mProjectionsEnabled && ( mEllipsoid != "NONE" ) )
00284 p1 = mCoordTransform->transform( points[0] );
00285 else
00286 p1 = points[0];
00287
00288 for ( QList<QgsPoint>::const_iterator i = points.begin(); i != points.end(); ++i )
00289 {
00290 if ( mProjectionsEnabled && ( mEllipsoid != "NONE" ) )
00291 {
00292 p2 = mCoordTransform->transform( *i );
00293 total += computeDistanceBearing( p1, p2 );
00294 }
00295 else
00296 {
00297 p2 = *i;
00298 total += measureLine( p1, p2 );
00299 }
00300
00301 p1 = p2;
00302 }
00303
00304 return total;
00305 }
00306 catch ( QgsCsException &cse )
00307 {
00308 Q_UNUSED( cse );
00309 QgsLogger::warning( QObject::tr( "Caught a coordinate system exception while trying to transform a point. Unable to calculate line length." ) );
00310 return 0.0;
00311 }
00312
00313 }
00314
00315 double QgsDistanceArea::measureLine( const QgsPoint& p1, const QgsPoint& p2 )
00316 {
00317 try
00318 {
00319 QgsPoint pp1 = p1, pp2 = p2;
00320 if ( mProjectionsEnabled && ( mEllipsoid != "NONE" ) )
00321 {
00322 pp1 = mCoordTransform->transform( p1 );
00323 pp2 = mCoordTransform->transform( p2 );
00324 return computeDistanceBearing( pp1, pp2 );
00325 }
00326 else
00327 {
00328 return sqrt(( p2.x() - p1.x() )*( p2.x() - p1.x() ) + ( p2.y() - p1.y() )*( p2.y() - p1.y() ) );
00329 }
00330 }
00331 catch ( QgsCsException &cse )
00332 {
00333 Q_UNUSED( cse );
00334 QgsLogger::warning( QObject::tr( "Caught a coordinate system exception while trying to transform a point. Unable to calculate line length." ) );
00335 return 0.0;
00336 }
00337 }
00338
00339
00340 unsigned char* QgsDistanceArea::measurePolygon( unsigned char* feature, double* area, bool hasZptr )
00341 {
00342
00343 unsigned int numRings = *(( int* )( feature + 1 + sizeof( int ) ) );
00344
00345 if ( numRings == 0 )
00346 return 0;
00347
00348
00349 unsigned char* ptr = feature + 1 + 2 * sizeof( int );
00350
00351 QList<QgsPoint> points;
00352 QgsPoint pnt;
00353 double x, y, areaTmp;
00354 *area = 0;
00355
00356 try
00357 {
00358 for ( unsigned int idx = 0; idx < numRings; idx++ )
00359 {
00360 int nPoints = *(( int* )ptr );
00361 ptr += 4;
00362
00363
00364
00365 for ( int jdx = 0; jdx < nPoints; jdx++ )
00366 {
00367 x = *(( double * ) ptr );
00368 ptr += sizeof( double );
00369 y = *(( double * ) ptr );
00370 ptr += sizeof( double );
00371 if ( hasZptr )
00372 {
00373
00374 ptr += sizeof( double );
00375 }
00376
00377 pnt = QgsPoint( x, y );
00378
00379 if ( mProjectionsEnabled && ( mEllipsoid != "NONE" ) )
00380 {
00381 pnt = mCoordTransform->transform( pnt );
00382 }
00383 points.append( pnt );
00384 }
00385
00386 if ( points.size() > 2 )
00387 {
00388 areaTmp = computePolygonArea( points );
00389 if ( idx == 0 )
00390 *area += areaTmp;
00391 else
00392 *area -= areaTmp;
00393 }
00394
00395 points.clear();
00396 }
00397 }
00398 catch ( QgsCsException &cse )
00399 {
00400 Q_UNUSED( cse );
00401 QgsLogger::warning( QObject::tr( "Caught a coordinate system exception while trying to transform a point. Unable to calculate polygon area." ) );
00402 }
00403
00404 return ptr;
00405 }
00406
00407
00408 double QgsDistanceArea::measurePolygon( const QList<QgsPoint>& points )
00409 {
00410
00411 try
00412 {
00413 if ( mProjectionsEnabled && ( mEllipsoid != "NONE" ) )
00414 {
00415 QList<QgsPoint> pts;
00416 for ( QList<QgsPoint>::const_iterator i = points.begin(); i != points.end(); ++i )
00417 {
00418 pts.append( mCoordTransform->transform( *i ) );
00419 }
00420 return computePolygonArea( pts );
00421 }
00422 else
00423 {
00424 return computePolygonArea( points );
00425 }
00426 }
00427 catch ( QgsCsException &cse )
00428 {
00429 Q_UNUSED( cse );
00430 QgsLogger::warning( QObject::tr( "Caught a coordinate system exception while trying to transform a point. Unable to calculate polygon area." ) );
00431 return 0.0;
00432 }
00433 }
00434
00435
00436 double QgsDistanceArea::bearing( const QgsPoint& p1, const QgsPoint& p2 )
00437 {
00438 QgsPoint pp1 = p1, pp2 = p2;
00439 double bearing;
00440
00441 if ( mProjectionsEnabled && ( mEllipsoid != "NONE" ) )
00442 {
00443 pp1 = mCoordTransform->transform( p1 );
00444 pp2 = mCoordTransform->transform( p2 );
00445 computeDistanceBearing( pp1, pp2, &bearing );
00446 }
00447 else
00448 {
00449 double dx = p2.x() - p1.x();
00450 double dy = p2.y() - p1.y();
00451 bearing = atan2( dx, dy );
00452 }
00453
00454 return bearing;
00455 }
00456
00457
00459
00460
00461 double QgsDistanceArea::computeDistanceBearing(
00462 const QgsPoint& p1, const QgsPoint& p2,
00463 double* course1, double* course2 )
00464 {
00465 if ( p1.x() == p2.x() && p1.y() == p2.y() )
00466 return 0;
00467
00468
00469 double a = mSemiMajor;
00470 double b = mSemiMinor;
00471 double f = 1 / mInvFlattening;
00472
00473 double p1_lat = DEG2RAD( p1.y() ), p1_lon = DEG2RAD( p1.x() );
00474 double p2_lat = DEG2RAD( p2.y() ), p2_lon = DEG2RAD( p2.x() );
00475
00476 double L = p2_lon - p1_lon;
00477 double U1 = atan(( 1 - f ) * tan( p1_lat ) );
00478 double U2 = atan(( 1 - f ) * tan( p2_lat ) );
00479 double sinU1 = sin( U1 ), cosU1 = cos( U1 );
00480 double sinU2 = sin( U2 ), cosU2 = cos( U2 );
00481 double lambda = L;
00482 double lambdaP = 2 * M_PI;
00483
00484 double sinLambda = 0;
00485 double cosLambda = 0;
00486 double sinSigma = 0;
00487 double cosSigma = 0;
00488 double sigma = 0;
00489 double alpha = 0;
00490 double cosSqAlpha = 0;
00491 double cos2SigmaM = 0;
00492 double C = 0;
00493 double tu1 = 0;
00494 double tu2 = 0;
00495
00496 int iterLimit = 20;
00497 while ( fabs( lambda - lambdaP ) > 1e-12 && --iterLimit > 0 )
00498 {
00499 sinLambda = sin( lambda );
00500 cosLambda = cos( lambda );
00501 tu1 = ( cosU2 * sinLambda );
00502 tu2 = ( cosU1 * sinU2 - sinU1 * cosU2 * cosLambda );
00503 sinSigma = sqrt( tu1 * tu1 + tu2 * tu2 );
00504 cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
00505 sigma = atan2( sinSigma, cosSigma );
00506 alpha = asin( cosU1 * cosU2 * sinLambda / sinSigma );
00507 cosSqAlpha = cos( alpha ) * cos( alpha );
00508 cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
00509 C = f / 16 * cosSqAlpha * ( 4 + f * ( 4 - 3 * cosSqAlpha ) );
00510 lambdaP = lambda;
00511 lambda = L + ( 1 - C ) * f * sin( alpha ) *
00512 ( sigma + C * sinSigma * ( cos2SigmaM + C * cosSigma * ( -1 + 2 * cos2SigmaM * cos2SigmaM ) ) );
00513 }
00514
00515 if ( iterLimit == 0 )
00516 return -1;
00517
00518 double uSq = cosSqAlpha * ( a * a - b * b ) / ( b * b );
00519 double A = 1 + uSq / 16384 * ( 4096 + uSq * ( -768 + uSq * ( 320 - 175 * uSq ) ) );
00520 double B = uSq / 1024 * ( 256 + uSq * ( -128 + uSq * ( 74 - 47 * uSq ) ) );
00521 double deltaSigma = B * sinSigma * ( cos2SigmaM + B / 4 * ( cosSigma * ( -1 + 2 * cos2SigmaM * cos2SigmaM ) -
00522 B / 6 * cos2SigmaM * ( -3 + 4 * sinSigma * sinSigma ) * ( -3 + 4 * cos2SigmaM * cos2SigmaM ) ) );
00523 double s = b * A * ( sigma - deltaSigma );
00524
00525 if ( course1 )
00526 {
00527 *course1 = atan2( tu1, tu2 );
00528 }
00529 if ( course2 )
00530 {
00531
00532 *course2 = atan2( cosU1 * sinLambda, -sinU1 * cosU2 + cosU1 * sinU2 * cosLambda ) + M_PI;
00533 }
00534
00535 return s;
00536 }
00537
00538
00539
00541
00542
00543
00544
00545 double QgsDistanceArea::getQ( double x )
00546 {
00547 double sinx, sinx2;
00548
00549 sinx = sin( x );
00550 sinx2 = sinx * sinx;
00551
00552 return sinx *( 1 + sinx2 *( m_QA + sinx2 *( m_QB + sinx2 * m_QC ) ) );
00553 }
00554
00555
00556 double QgsDistanceArea::getQbar( double x )
00557 {
00558 double cosx, cosx2;
00559
00560 cosx = cos( x );
00561 cosx2 = cosx * cosx;
00562
00563 return cosx *( m_QbarA + cosx2 *( m_QbarB + cosx2 *( m_QbarC + cosx2 * m_QbarD ) ) );
00564 }
00565
00566
00567 void QgsDistanceArea::computeAreaInit()
00568 {
00569 double a2 = ( mSemiMajor * mSemiMajor );
00570 double e2 = 1 - ( a2 / ( mSemiMinor * mSemiMinor ) );
00571 double e4, e6;
00572
00573 m_TwoPI = M_PI + M_PI;
00574
00575 e4 = e2 * e2;
00576 e6 = e4 * e2;
00577
00578 m_AE = a2 * ( 1 - e2 );
00579
00580 m_QA = ( 2.0 / 3.0 ) * e2;
00581 m_QB = ( 3.0 / 5.0 ) * e4;
00582 m_QC = ( 4.0 / 7.0 ) * e6;
00583
00584 m_QbarA = -1.0 - ( 2.0 / 3.0 ) * e2 - ( 3.0 / 5.0 ) * e4 - ( 4.0 / 7.0 ) * e6;
00585 m_QbarB = ( 2.0 / 9.0 ) * e2 + ( 2.0 / 5.0 ) * e4 + ( 4.0 / 7.0 ) * e6;
00586 m_QbarC = - ( 3.0 / 25.0 ) * e4 - ( 12.0 / 35.0 ) * e6;
00587 m_QbarD = ( 4.0 / 49.0 ) * e6;
00588
00589 m_Qp = getQ( M_PI / 2 );
00590 m_E = 4 * M_PI * m_Qp * m_AE;
00591 if ( m_E < 0.0 ) m_E = -m_E;
00592 }
00593
00594
00595 double QgsDistanceArea::computePolygonArea( const QList<QgsPoint>& points )
00596 {
00597 double x1, y1, x2, y2, dx, dy;
00598 double Qbar1, Qbar2;
00599 double area;
00600
00601 QgsDebugMsgLevel( "Ellipsoid: " + mEllipsoid, 3 );
00602 if (( ! mProjectionsEnabled ) || ( mEllipsoid == "NONE" ) )
00603 {
00604 return computePolygonFlatArea( points );
00605 }
00606 int n = points.size();
00607 x2 = DEG2RAD( points[n-1].x() );
00608 y2 = DEG2RAD( points[n-1].y() );
00609 Qbar2 = getQbar( y2 );
00610
00611 area = 0.0;
00612
00613 for ( int i = 0; i < n; i++ )
00614 {
00615 x1 = x2;
00616 y1 = y2;
00617 Qbar1 = Qbar2;
00618
00619 x2 = DEG2RAD( points[i].x() );
00620 y2 = DEG2RAD( points[i].y() );
00621 Qbar2 = getQbar( y2 );
00622
00623 if ( x1 > x2 )
00624 while ( x1 - x2 > M_PI )
00625 x2 += m_TwoPI;
00626 else if ( x2 > x1 )
00627 while ( x2 - x1 > M_PI )
00628 x1 += m_TwoPI;
00629
00630 dx = x2 - x1;
00631 area += dx * ( m_Qp - getQ( y2 ) );
00632
00633 if (( dy = y2 - y1 ) != 0.0 )
00634 area += dx * getQ( y2 ) - ( dx / dy ) * ( Qbar2 - Qbar1 );
00635 }
00636 if (( area *= m_AE ) < 0.0 )
00637 area = -area;
00638
00639
00640
00641
00642
00643
00644 if ( area > m_E ) area = m_E;
00645 if ( area > m_E / 2 ) area = m_E - area;
00646
00647 return area;
00648 }
00649
00650 double QgsDistanceArea::computePolygonFlatArea( const QList<QgsPoint>& points )
00651 {
00652
00653 double area = 0.0;
00654 int i, size;
00655
00656 size = points.size();
00657
00658
00659 for ( i = 0; i < size; i++ )
00660 {
00661
00662
00663
00664 area = area + points[i].x() * points[( i+1 ) % size].y() - points[( i+1 ) % size].x() * points[i].y();
00665 }
00666
00667 area = area / 2.0;
00668 return fabs( area );
00669 }
00670
00671 QString QgsDistanceArea::textUnit( double value, int decimals, QGis::UnitType u, bool isArea, bool keepBaseUnit )
00672 {
00673 QString unitLabel;
00674
00675
00676 switch ( u )
00677 {
00678 case QGis::Meters:
00679 if ( isArea )
00680 {
00681 if ( keepBaseUnit )
00682 {
00683 unitLabel = QObject::tr( " m2" );
00684 }
00685 else if ( fabs( value ) > 1000000.0 )
00686 {
00687 unitLabel = QObject::tr( " km2" );
00688 value = value / 1000000.0;
00689 }
00690 else if ( fabs( value ) > 10000.0 )
00691 {
00692 unitLabel = QObject::tr( " ha" );
00693 value = value / 10000.0;
00694 }
00695 else
00696 {
00697 unitLabel = QObject::tr( " m2" );
00698 }
00699 }
00700 else
00701 {
00702 if ( keepBaseUnit || fabs( value ) == 0.0 )
00703 {
00704 unitLabel = QObject::tr( " m" );
00705 }
00706 else if ( fabs( value ) > 1000.0 )
00707 {
00708 unitLabel = QObject::tr( " km" );
00709 value = value / 1000;
00710 }
00711 else if ( fabs( value ) < 0.01 )
00712 {
00713 unitLabel = QObject::tr( " mm" );
00714 value = value * 1000;
00715 }
00716 else if ( fabs( value ) < 0.1 )
00717 {
00718 unitLabel = QObject::tr( " cm" );
00719 value = value * 100;
00720 }
00721 else
00722 {
00723 unitLabel = QObject::tr( " m" );
00724 }
00725 }
00726 break;
00727 case QGis::Feet:
00728 if ( isArea )
00729 {
00730 if ( keepBaseUnit || fabs( value ) <= ( 528.0*528.0 ) )
00731 {
00732 unitLabel = QObject::tr( " sq ft" );
00733 }
00734 else
00735 {
00736 unitLabel = QObject::tr( " sq mile" );
00737 value = value / ( 5280.0 * 5280.0 );
00738 }
00739 }
00740 else
00741 {
00742 if ( fabs( value ) <= 528.0 || keepBaseUnit )
00743 {
00744 if ( fabs( value ) == 1.0 )
00745 {
00746 unitLabel = QObject::tr( " foot" );
00747 }
00748 else
00749 {
00750 unitLabel = QObject::tr( " feet" );
00751 }
00752 }
00753 else
00754 {
00755 unitLabel = QObject::tr( " mile" );
00756 value = value / 5280.0;
00757 }
00758 }
00759 break;
00760 case QGis::Degrees:
00761 if ( isArea )
00762 {
00763 unitLabel = QObject::tr( " sq.deg." );
00764 }
00765 else
00766 {
00767 if ( fabs( value ) == 1.0 )
00768 unitLabel = QObject::tr( " degree" );
00769 else
00770 unitLabel = QObject::tr( " degrees" );
00771 }
00772 break;
00773 case QGis::UnknownUnit:
00774 unitLabel = QObject::tr( " unknown" );
00775 default:
00776 QgsDebugMsg( QString( "Error: not picked up map units - actual value = %1" ).arg( u ) );
00777 };
00778
00779
00780 return QLocale::system().toString( value, 'f', decimals ) + unitLabel;
00781
00782 }