35 #define M_PI 3.14159265358979323846
38 #define DEG2RAD(x) ((x)*M_PI/180)
65 if (
this == & origDA )
110 QString radius, parameter2;
116 sqlite3_stmt *myPreparedStatement;
130 if ( ellipsoid.startsWith(
"PARAMETER" ) )
132 QStringList paramList = ellipsoid.split(
":" );
133 bool semiMajorOk, semiMinorOk;
134 double semiMajor = paramList[1].toDouble( & semiMajorOk );
135 double semiMinor = paramList[2].toDouble( & semiMinorOk );
136 if ( semiMajorOk && semiMinorOk )
158 QString mySql =
"select radius, parameter2 from tbl_ellipsoid where acronym='" + ellipsoid +
"'";
159 myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
161 if ( myResult == SQLITE_OK )
163 if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
165 radius = QString((
char * )sqlite3_column_text( myPreparedStatement, 0 ) );
166 parameter2 = QString((
char * )sqlite3_column_text( myPreparedStatement, 1 ) );
170 sqlite3_finalize( myPreparedStatement );
171 sqlite3_close( myDatabase );
174 if ( radius.isEmpty() || parameter2.isEmpty() )
176 QgsDebugMsg( QString(
"setEllipsoid: no row in tbl_ellipsoid for acronym '%1'" ).arg( ellipsoid ) );
181 if ( radius.left( 2 ) ==
"a=" )
185 QgsDebugMsg( QString(
"setEllipsoid: wrong format of radius field: '%1'" ).arg( radius ) );
192 if ( parameter2.left( 2 ) ==
"b=" )
197 else if ( parameter2.left( 3 ) ==
"rf=" )
204 QgsDebugMsg( QString(
"setEllipsoid: wrong format of parameter2 field: '%1'" ).arg( parameter2 ) );
212 QString proj4 =
"+proj=longlat +ellps=" + ellipsoid +
" +no_defs";
219 if ( destCRS.
srsid() == 0 )
221 QString myName = QString(
" * %1 (%2)" )
222 .arg(
QObject::tr(
"Generated CRS",
"A CRS automatically generated from layer info get this prefix for description" ) )
243 mEllipsoid = QString(
"PARAMETER:%1:%2" ).arg( semiMajor ).arg( semiMinor );
260 const unsigned char* wkb = geometry->
asWkb();
264 const unsigned char* ptr;
265 unsigned int wkbType;
266 double res, resTotal = 0;
269 memcpy( &wkbType, ( wkb + 1 ),
sizeof( wkbType ) );
272 bool hasZptr =
false;
280 QgsDebugMsg(
"returning " + QString::number( res ) );
286 count = *((
int* )( wkb + 5 ) );
288 for ( i = 0; i < count; i++ )
293 QgsDebugMsg(
"returning " + QString::number( resTotal ) );
300 QgsDebugMsg(
"returning " + QString::number( res ) );
306 count = *((
int* )( wkb + 5 ) );
308 for ( i = 0; i < count; i++ )
318 QgsDebugMsg(
"returning " + QString::number( resTotal ) );
322 QgsDebugMsg( QString(
"measure: unexpected geometry type: %1" ).arg( wkbType ) );
332 const unsigned char* wkb = geometry->
asWkb();
336 const unsigned char* ptr;
337 unsigned int wkbType;
338 double res = 0.0, resTotal = 0.0;
341 memcpy( &wkbType, ( wkb + 1 ),
sizeof( wkbType ) );
344 bool hasZptr =
false;
358 QgsDebugMsg(
"returning " + QString::number( res ) );
364 count = *((
int* )( wkb + 5 ) );
366 for ( i = 0; i < count; i++ )
376 QgsDebugMsg(
"returning " + QString::number( resTotal ) );
380 QgsDebugMsg( QString(
"measure: unexpected geometry type: %1" ).arg( wkbType ) );
388 const unsigned char *ptr = feature + 5;
389 unsigned int nPoints = *((
int* )ptr );
392 QList<QgsPoint> points;
395 QgsDebugMsg(
"This feature WKB has " + QString::number( nPoints ) +
" points" );
397 for (
unsigned int i = 0; i < nPoints; ++i )
399 x = *((
double * ) ptr );
400 ptr +=
sizeof( double );
401 y = *((
double * ) ptr );
402 ptr +=
sizeof( double );
406 ptr +=
sizeof( double );
418 if ( points.size() < 2 )
431 for ( QList<QgsPoint>::const_iterator i = points.begin(); i != points.end(); ++i )
474 QgsDebugMsgLevel( QString(
"New points are %1 and %2, calculating..." ).arg( pp1.
toString( 4 ) ).arg( pp2.toString( 4 ) ), 4 );
480 result = sqrt(( p2.
x() - p1.
x() ) * ( p2.
x() - p1.
x() ) + ( p2.
y() - p1.
y() ) * ( p2.
y() - p1.
y() ) );
503 unsigned int numRings = *((
int* )( feature + 1 +
sizeof(
int ) ) );
512 const unsigned char* ptr = feature + 1 + 2 *
sizeof( int );
514 QList<QgsPoint> points;
524 for (
unsigned int idx = 0; idx < numRings; idx++ )
526 int nPoints = *((
int* )ptr );
531 for (
int jdx = 0; jdx < nPoints; jdx++ )
533 x = *((
double * ) ptr );
534 ptr +=
sizeof( double );
535 y = *((
double * ) ptr );
536 ptr +=
sizeof( double );
540 ptr +=
sizeof( double );
549 points.append( pnt );
552 if ( points.size() > 2 )
598 for ( QList<QgsPoint>::const_iterator i = points.begin(); i != points.end(); ++i )
631 double dx = p2.
x() - p1.
x();
632 double dy = p2.
y() - p1.
y();
633 bearing = atan2( dx, dy );
645 double* course1,
double* course2 )
647 if ( p1.
x() == p2.
x() && p1.
y() == p2.
y() )
658 double L = p2_lon - p1_lon;
659 double U1 = atan(( 1 - f ) * tan( p1_lat ) );
660 double U2 = atan(( 1 - f ) * tan( p2_lat ) );
661 double sinU1 = sin( U1 ), cosU1 = cos( U1 );
662 double sinU2 = sin( U2 ), cosU2 = cos( U2 );
664 double lambdaP = 2 *
M_PI;
666 double sinLambda = 0;
667 double cosLambda = 0;
672 double cosSqAlpha = 0;
673 double cos2SigmaM = 0;
679 while ( qAbs( lambda - lambdaP ) > 1e-12 && --iterLimit > 0 )
681 sinLambda = sin( lambda );
682 cosLambda = cos( lambda );
683 tu1 = ( cosU2 * sinLambda );
684 tu2 = ( cosU1 * sinU2 - sinU1 * cosU2 * cosLambda );
685 sinSigma = sqrt( tu1 * tu1 + tu2 * tu2 );
686 cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
687 sigma = atan2( sinSigma, cosSigma );
688 alpha = asin( cosU1 * cosU2 * sinLambda / sinSigma );
689 cosSqAlpha = cos( alpha ) * cos( alpha );
690 cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
691 C = f / 16 * cosSqAlpha * ( 4 + f * ( 4 - 3 * cosSqAlpha ) );
693 lambda = L + ( 1 - C ) * f * sin( alpha ) *
694 ( sigma + C * sinSigma * ( cos2SigmaM + C * cosSigma * ( -1 + 2 * cos2SigmaM * cos2SigmaM ) ) );
697 if ( iterLimit == 0 )
700 double uSq = cosSqAlpha * ( a * a - b * b ) / ( b * b );
701 double A = 1 + uSq / 16384 * ( 4096 + uSq * ( -768 + uSq * ( 320 - 175 * uSq ) ) );
702 double B = uSq / 1024 * ( 256 + uSq * ( -128 + uSq * ( 74 - 47 * uSq ) ) );
703 double deltaSigma = B * sinSigma * ( cos2SigmaM + B / 4 * ( cosSigma * ( -1 + 2 * cos2SigmaM * cos2SigmaM ) -
704 B / 6 * cos2SigmaM * ( -3 + 4 * sinSigma * sinSigma ) * ( -3 + 4 * cos2SigmaM * cos2SigmaM ) ) );
705 double s = b * A * ( sigma - deltaSigma );
709 *course1 = atan2( tu1, tu2 );
714 *course2 = atan2( cosU1 * sinLambda, -sinU1 * cosU2 + cosU1 * sinU2 * cosLambda ) +
M_PI;
734 return sinx *( 1 + sinx2 *(
m_QA + sinx2 *(
m_QB + sinx2 *
m_QC ) ) );
760 m_AE = a2 * ( 1 - e2 );
762 m_QA = ( 2.0 / 3.0 ) * e2;
763 m_QB = ( 3.0 / 5.0 ) * e4;
764 m_QC = ( 4.0 / 7.0 ) * e6;
766 m_QbarA = -1.0 - ( 2.0 / 3.0 ) * e2 - ( 3.0 / 5.0 ) * e4 - ( 4.0 / 7.0 ) * e6;
767 m_QbarB = ( 2.0 / 9.0 ) * e2 + ( 2.0 / 5.0 ) * e4 + ( 4.0 / 7.0 ) * e6;
768 m_QbarC = - ( 3.0 / 25.0 ) * e4 - ( 12.0 / 35.0 ) * e6;
780 double x1, y1, x2, y2, dx, dy;
789 int n = points.size();
790 x2 =
DEG2RAD( points[n-1].x() );
791 y2 =
DEG2RAD( points[n-1].y() );
796 for (
int i = 0; i < n; i++ )
807 while ( x1 - x2 >
M_PI )
810 while ( x2 - x1 >
M_PI )
816 if (( dy = y2 - y1 ) != 0.0 )
817 area += dx *
getQ( y2 ) - ( dx / dy ) * ( Qbar2 - Qbar1 );
819 if (( area *=
m_AE ) < 0.0 )
829 if ( area >
m_E / 2 )
841 size = points.size();
844 for ( i = 0; i <
size; i++ )
849 area = area + points[i].x() * points[( i+1 ) % size].y() - points[( i+1 ) % size].x() * points[i].y();
867 unitLabel = QObject::trUtf8(
" m²" );
869 else if ( qAbs( value ) > 1000000.0 )
871 unitLabel = QObject::trUtf8(
" km²" );
872 value = value / 1000000.0;
874 else if ( qAbs( value ) > 10000.0 )
877 value = value / 10000.0;
881 unitLabel = QObject::trUtf8(
" m²" );
886 if ( keepBaseUnit || qAbs( value ) == 0.0 )
890 else if ( qAbs( value ) > 1000.0 )
893 value = value / 1000;
895 else if ( qAbs( value ) < 0.01 )
898 value = value * 1000;
900 else if ( qAbs( value ) < 0.1 )
914 if ( keepBaseUnit || qAbs( value ) <= 0.5*43560.0 )
919 else if ( qAbs( value ) <= 0.5*5280.0*5280.0 )
929 value /= 5280.0 * 5280.0;
934 if ( qAbs( value ) <= 528.0 || keepBaseUnit )
936 if ( qAbs( value ) == 1.0 )
959 if ( qAbs( value ) == 1.0 )
968 QgsDebugMsg( QString(
"Error: not picked up map units - actual value = %1" ).arg( u ) );
972 return QLocale::system().toString( value,
'f', decimals ) + unitLabel;
986 QgsDebugMsg(
"We're measuring on an ellipsoid or using projections, the system is returning meters" );
992 QgsDebugMsg( QString(
"Converting %1 meters" ).arg( QString::number( measure ) ) );
998 QgsDebugMsg( QString(
"to %1 feet" ).arg( QString::number( measure ) ) );
1003 QgsDebugMsg( QString(
"Converting %1 feet" ).arg( QString::number( measure ) ) );
1009 QgsDebugMsg( QString(
"to %1 meters" ).arg( QString::number( measure ) ) );