QGIS API Documentation  master-6227475
src/core/qgscoordinatetransform.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                QgsCoordinateTransform.cpp  - Coordinate Transforms
00003                              -------------------
00004     begin                : Dec 2004
00005     copyright            : (C) 2004 Tim Sutton
00006     email                : tim at linfiniti.com
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 #include "qgscoordinatetransform.h"
00018 #include "qgscrscache.h"
00019 #include "qgsmessagelog.h"
00020 #include "qgslogger.h"
00021 
00022 //qt includes
00023 #include <QDomNode>
00024 #include <QDomElement>
00025 #include <QApplication>
00026 #include <QPolygonF>
00027 #include <QVector>
00028 
00029 extern "C"
00030 {
00031 #include <proj_api.h>
00032 }
00033 
00034 // if defined shows all information about transform to stdout
00035 // #define COORDINATE_TRANSFORM_VERBOSE
00036 
00037 QgsCoordinateTransform::QgsCoordinateTransform()
00038     : QObject()
00039     , mInitialisedFlag( false )
00040     , mSourceProjection( 0 )
00041     , mDestinationProjection( 0 )
00042 {
00043   setFinder();
00044 }
00045 
00046 QgsCoordinateTransform::QgsCoordinateTransform( const QgsCoordinateReferenceSystem& source, const QgsCoordinateReferenceSystem& dest )
00047     : QObject()
00048     , mInitialisedFlag( false )
00049     , mSourceProjection( 0 )
00050     , mDestinationProjection( 0 )
00051 {
00052   setFinder();
00053   mSourceCRS = source;
00054   mDestCRS = dest;
00055   initialise();
00056 }
00057 
00058 QgsCoordinateTransform::QgsCoordinateTransform( long theSourceSrsId, long theDestSrsId )
00059     : QObject()
00060     , mInitialisedFlag( false )
00061     , mSourceCRS( theSourceSrsId, QgsCoordinateReferenceSystem::InternalCrsId )
00062     , mDestCRS( theDestSrsId, QgsCoordinateReferenceSystem::InternalCrsId )
00063     , mSourceProjection( 0 )
00064     , mDestinationProjection( 0 )
00065 {
00066   initialise();
00067 }
00068 
00069 QgsCoordinateTransform::QgsCoordinateTransform( QString theSourceCRS, QString theDestCRS )
00070     : QObject()
00071     , mInitialisedFlag( false )
00072     , mSourceProjection( 0 )
00073     , mDestinationProjection( 0 )
00074 {
00075   setFinder();
00076   mSourceCRS.createFromWkt( theSourceCRS );
00077   mDestCRS.createFromWkt( theDestCRS );
00078   // initialize the coordinate system data structures
00079   //XXX Who spells initialize initialise?
00080   //XXX A: Its the queen's english....
00081   //XXX  : Long live the queen! Lets get on with the initialisation...
00082   initialise();
00083 }
00084 
00085 QgsCoordinateTransform::QgsCoordinateTransform( long theSourceSrid,
00086     QString theDestWkt,
00087     QgsCoordinateReferenceSystem::CrsType theSourceCRSType )
00088     : QObject()
00089     , mInitialisedFlag( false )
00090     , mSourceProjection( 0 )
00091     , mDestinationProjection( 0 )
00092 {
00093   setFinder();
00094 
00095   mSourceCRS.createFromId( theSourceSrid, theSourceCRSType );
00096   mDestCRS.createFromWkt( theDestWkt );
00097   // initialize the coordinate system data structures
00098   //XXX Who spells initialize initialise?
00099   //XXX A: Its the queen's english....
00100   //XXX  : Long live the queen! Lets get on with the initialisation...
00101   initialise();
00102 }
00103 
00104 QgsCoordinateTransform::~QgsCoordinateTransform()
00105 {
00106   // free the proj objects
00107   if ( mSourceProjection )
00108   {
00109     pj_free( mSourceProjection );
00110   }
00111   if ( mDestinationProjection )
00112   {
00113     pj_free( mDestinationProjection );
00114   }
00115 }
00116 
00117 void QgsCoordinateTransform::setSourceCrs( const QgsCoordinateReferenceSystem& theCRS )
00118 {
00119   mSourceCRS = theCRS;
00120   initialise();
00121 }
00122 void QgsCoordinateTransform::setDestCRS( const QgsCoordinateReferenceSystem& theCRS )
00123 {
00124   mDestCRS = theCRS;
00125   initialise();
00126 }
00127 
00128 void QgsCoordinateTransform::setDestCRSID( long theCRSID )
00129 {
00131   mDestCRS.createFromSrsId( theCRSID );
00132   initialise();
00133 }
00134 
00135 // XXX This whole function is full of multiple return statements!!!
00136 // And probably shouldn't be a void
00137 void QgsCoordinateTransform::initialise()
00138 {
00139   // XXX Warning - multiple return paths in this block!!
00140   if ( !mSourceCRS.isValid() )
00141   {
00142     //mSourceCRS = defaultWkt;
00143     // Pass through with no projection since we have no idea what the layer
00144     // coordinates are and projecting them may not be appropriate
00145     mShortCircuit = true;
00146     QgsDebugMsg( "SourceCRS seemed invalid!" );
00147     return;
00148   }
00149 
00150   if ( !mDestCRS.isValid() )
00151   {
00152     //No destination projection is set so we set the default output projection to
00153     //be the same as input proj.
00154     mDestCRS = QgsCRSCache::instance()->crsByAuthId( mSourceCRS.authid() );
00155   }
00156 
00157   // init the projections (destination and source)
00158   mDestinationProjection = pj_init_plus( mDestCRS.toProj4().toUtf8() );
00159   mSourceProjection = pj_init_plus( mSourceCRS.toProj4().toUtf8() );
00160 
00161 #ifdef COORDINATE_TRANSFORM_VERBOSE
00162   QgsDebugMsg( "From proj : " + mSourceCRS.toProj4() );
00163   QgsDebugMsg( "To proj   : " + mDestCRS.toProj4() );
00164 #endif
00165 
00166   mInitialisedFlag = true;
00167   if ( !mDestinationProjection )
00168   {
00169     mInitialisedFlag = false;
00170   }
00171   if ( !mSourceProjection )
00172   {
00173     mInitialisedFlag = false;
00174   }
00175 #ifdef COORDINATE_TRANSFORM_VERBOSE
00176   if ( mInitialisedFlag )
00177   {
00178     QgsDebugMsg( "------------------------------------------------------------" );
00179     QgsDebugMsg( "The OGR Coordinate transformation for this layer was set to" );
00180     QgsLogger::debug<QgsCoordinateReferenceSystem>( "Input", mSourceCRS, __FILE__, __FUNCTION__, __LINE__ );
00181     QgsLogger::debug<QgsCoordinateReferenceSystem>( "Output", mDestCRS, __FILE__, __FUNCTION__, __LINE__ );
00182     QgsDebugMsg( "------------------------------------------------------------" );
00183   }
00184   else
00185   {
00186     QgsDebugMsg( "------------------------------------------------------------" );
00187     QgsDebugMsg( "The OGR Coordinate transformation FAILED TO INITIALISE!" );
00188     QgsDebugMsg( "------------------------------------------------------------" );
00189   }
00190 #else
00191   if ( !mInitialisedFlag )
00192   {
00193     QgsDebugMsg( "Coordinate transformation failed to initialize!" );
00194   }
00195 #endif
00196 
00197   //XXX todo overload == operator for QgsCoordinateReferenceSystem
00198   //at the moment srs.parameters contains the whole proj def...soon it wont...
00199   //if (mSourceCRS->toProj4() == mDestCRS->toProj4())
00200   if ( mSourceCRS == mDestCRS )
00201   {
00202     // If the source and destination projection are the same, set the short
00203     // circuit flag (no transform takes place)
00204     mShortCircuit = true;
00205     QgsDebugMsgLevel( "Source/Dest CRS equal, shortcircuit is set.", 3 );
00206   }
00207   else
00208   {
00209     // Transform must take place
00210     mShortCircuit = false;
00211     QgsDebugMsgLevel( "Source/Dest CRS UNequal, shortcircuit is NOt set.", 3 );
00212   }
00213 
00214 }
00215 
00216 //
00217 //
00218 // TRANSFORMERS BELOW THIS POINT .........
00219 //
00220 //
00221 //
00222 
00223 
00224 QgsPoint QgsCoordinateTransform::transform( const QgsPoint thePoint, TransformDirection direction ) const
00225 {
00226   if ( mShortCircuit || !mInitialisedFlag )
00227     return thePoint;
00228   // transform x
00229   double x = thePoint.x();
00230   double y = thePoint.y();
00231   double z = 0.0;
00232   try
00233   {
00234     transformCoords( 1, &x, &y, &z, direction );
00235   }
00236   catch ( QgsCsException &cse )
00237   {
00238     // rethrow the exception
00239     QgsDebugMsg( "rethrowing exception" );
00240     throw cse;
00241   }
00242 
00243   return QgsPoint( x, y );
00244 }
00245 
00246 
00247 QgsPoint QgsCoordinateTransform::transform( const double theX, const double theY = 0, TransformDirection direction ) const
00248 {
00249   try
00250   {
00251     return transform( QgsPoint( theX, theY ), direction );
00252   }
00253   catch ( QgsCsException &cse )
00254   {
00255     // rethrow the exception
00256     QgsDebugMsg( "rethrowing exception" );
00257     throw cse;
00258   }
00259 }
00260 
00261 QgsRectangle QgsCoordinateTransform::transform( const QgsRectangle theRect, TransformDirection direction ) const
00262 {
00263   if ( mShortCircuit || !mInitialisedFlag )
00264     return theRect;
00265   // transform x
00266   double x1 = theRect.xMinimum();
00267   double y1 = theRect.yMinimum();
00268   double x2 = theRect.xMaximum();
00269   double y2 = theRect.yMaximum();
00270 
00271   // Number of points to reproject------+
00272   //                                    |
00273   //                                    V
00274   try
00275   {
00276     double z = 0.0;
00277     transformCoords( 1, &x1, &y1, &z, direction );
00278     transformCoords( 1, &x2, &y2, &z, direction );
00279   }
00280   catch ( QgsCsException &cse )
00281   {
00282     // rethrow the exception
00283     QgsDebugMsg( "rethrowing exception" );
00284     throw cse;
00285   }
00286 
00287 #ifdef COORDINATE_TRANSFORM_VERBOSE
00288   QgsDebugMsg( "Rect projection..." );
00289   QgsLogger::debug( "Xmin : ", theRect.xMinimum(), 1, __FILE__, __FUNCTION__, __LINE__ );
00290   QgsLogger::debug( "-->", x1, 1, __FILE__, __FUNCTION__, __LINE__ );
00291   QgsLogger::debug( "Ymin : ", theRect.yMinimum(), 1, __FILE__, __FUNCTION__, __LINE__ );
00292   QgsLogger::debug( "-->", y1, 1, __FILE__, __FUNCTION__, __LINE__ );
00293   QgsLogger::debug( "Xmax : ", theRect.xMaximum(), 1, __FILE__, __FUNCTION__, __LINE__ );
00294   QgsLogger::debug( "-->", x2, 1, __FILE__, __FUNCTION__, __LINE__ );
00295   QgsLogger::debug( "Ymax : ", theRect.yMaximum(), 1, __FILE__, __FUNCTION__, __LINE__ );
00296   QgsLogger::debug( "-->", y2, 1, __FILE__, __FUNCTION__, __LINE__ );
00297 #endif
00298   return QgsRectangle( x1, y1, x2, y2 );
00299 }
00300 
00301 void QgsCoordinateTransform::transformInPlace( double& x, double& y, double& z,
00302     TransformDirection direction ) const
00303 {
00304   if ( mShortCircuit || !mInitialisedFlag )
00305     return;
00306 #ifdef QGISDEBUG
00307 // QgsDebugMsg(QString("Using transform in place %1 %2").arg(__FILE__).arg(__LINE__));
00308 #endif
00309   // transform x
00310   try
00311   {
00312     transformCoords( 1, &x, &y, &z, direction );
00313   }
00314   catch ( QgsCsException &cse )
00315   {
00316     // rethrow the exception
00317     QgsDebugMsg( "rethrowing exception" );
00318     throw cse;
00319   }
00320 }
00321 
00322 void QgsCoordinateTransform::transformPolygon( QPolygonF& poly, TransformDirection direction ) const
00323 {
00324   if ( mShortCircuit || !mInitialisedFlag )
00325   {
00326     return;
00327   }
00328 
00329   //create x, y arrays
00330   int nVertices = poly.size();
00331 
00332   QVector<double> x( nVertices );
00333   QVector<double> y( nVertices );
00334   QVector<double> z( nVertices );
00335 
00336   for ( int i = 0; i < nVertices; ++i )
00337   {
00338     const QPointF& pt = poly.at( i );
00339     x[i] = pt.x();
00340     y[i] = pt.y();
00341     z[i] = 0;
00342   }
00343 
00344   try
00345   {
00346     transformCoords( nVertices, x.data(), y.data(), z.data(), direction );
00347   }
00348   catch ( QgsCsException &cse )
00349   {
00350     // rethrow the exception
00351     QgsDebugMsg( "rethrowing exception" );
00352     throw cse;
00353   }
00354 
00355   for ( int i = 0; i < nVertices; ++i )
00356   {
00357     QPointF& pt = poly[i];
00358     pt.rx() = x[i];
00359     pt.ry() = y[i];
00360   }
00361 }
00362 
00363 void QgsCoordinateTransform::transformInPlace(
00364   QVector<double>& x, QVector<double>& y, QVector<double>& z,
00365   TransformDirection direction ) const
00366 {
00367   if ( mShortCircuit || !mInitialisedFlag )
00368     return;
00369 
00370   Q_ASSERT( x.size() == y.size() );
00371 
00372   // Apparently, if one has a std::vector, it is valid to use the
00373   // address of the first element in the vector as a pointer to an
00374   // array of the vectors data, and hence easily interface with code
00375   // that wants C-style arrays.
00376 
00377   try
00378   {
00379     transformCoords( x.size(), &x[0], &y[0], &z[0], direction );
00380   }
00381   catch ( QgsCsException &cse )
00382   {
00383     // rethrow the exception
00384     QgsDebugMsg( "rethrowing exception" );
00385     throw cse;
00386   }
00387 }
00388 
00389 #ifdef ANDROID
00390 void QgsCoordinateTransform::transformInPlace( float& x, float& y, float& z,
00391     TransformDirection direction ) const
00392 {
00393   if ( mShortCircuit || !mInitialisedFlag )
00394     return;
00395 #ifdef QGISDEBUG
00396 // QgsDebugMsg(QString("Using transform in place %1 %2").arg(__FILE__).arg(__LINE__));
00397 #endif
00398   // transform x
00399   try
00400   {
00401     double xd = x;
00402     double yd = y;
00403     double zd = z;
00404     transformCoords( 1, &xd, &yd, &zd, direction );
00405     x = xd;
00406     y = yd;
00407     z = zd;
00408   }
00409   catch ( QgsCsException &cse )
00410   {
00411     // rethrow the exception
00412     QgsDebugMsg( "rethrowing exception" );
00413     throw cse;
00414   }
00415 }
00416 
00417 void QgsCoordinateTransform::transformInPlace(
00418   QVector<float>& x, QVector<float>& y, QVector<float>& z,
00419   TransformDirection direction ) const
00420 {
00421   if ( mShortCircuit || !mInitialisedFlag )
00422     return;
00423 
00424   Q_ASSERT( x.size() == y.size() );
00425 
00426   // Apparently, if one has a std::vector, it is valid to use the
00427   // address of the first element in the vector as a pointer to an
00428   // array of the vectors data, and hence easily interface with code
00429   // that wants C-style arrays.
00430 
00431   try
00432   {
00433     //copy everything to double vectors since proj needs double
00434     int vectorSize = x.size();
00435     QVector<double> xd( x.size() );
00436     QVector<double> yd( y.size() );
00437     QVector<double> zd( z.size() );
00438     for ( int i = 0; i < vectorSize; ++i )
00439     {
00440       xd[i] = x[i];
00441       yd[i] = y[i];
00442       zd[i] = z[i];
00443     }
00444     transformCoords( x.size(), &xd[0], &yd[0], &zd[0], direction );
00445 
00446     //copy back
00447     for ( int i = 0; i < vectorSize; ++i )
00448     {
00449       x[i] = xd[i];
00450       y[i] = yd[i];
00451       z[i] = zd[i];
00452     }
00453   }
00454   catch ( QgsCsException &cse )
00455   {
00456     // rethrow the exception
00457     QgsDebugMsg( "rethrowing exception" );
00458     throw cse;
00459   }
00460 }
00461 #endif //ANDROID
00462 
00463 
00464 QgsRectangle QgsCoordinateTransform::transformBoundingBox( const QgsRectangle rect, TransformDirection direction ) const
00465 {
00466   // Calculate the bounding box of a QgsRectangle in the source CRS
00467   // when projected to the destination CRS (or the inverse).
00468   // This is done by looking at a number of points spread evenly
00469   // across the rectangle
00470 
00471   if ( mShortCircuit || !mInitialisedFlag )
00472     return rect;
00473 
00474   if ( rect.isEmpty() )
00475   {
00476     QgsPoint p = transform( rect.xMinimum(), rect.yMinimum(), direction );
00477     return QgsRectangle( p, p );
00478   }
00479 
00480   static const int numP = 8;
00481 
00482   QgsRectangle bb_rect;
00483   bb_rect.setMinimal();
00484 
00485   // We're interfacing with C-style vectors in the
00486   // end, so let's do C-style vectors here too.
00487 
00488   double x[numP * numP];
00489   double y[numP * numP];
00490   double z[numP * numP];
00491 
00492   QgsDebugMsg( "Entering transformBoundingBox..." );
00493 
00494   // Populate the vectors
00495 
00496   double dx = rect.width()  / ( double )( numP - 1 );
00497   double dy = rect.height() / ( double )( numP - 1 );
00498 
00499   double pointY = rect.yMinimum();
00500 
00501   for ( int i = 0; i < numP ; i++ )
00502   {
00503 
00504     // Start at right edge
00505     double pointX = rect.xMinimum();
00506 
00507     for ( int j = 0; j < numP; j++ )
00508     {
00509       x[( i*numP ) + j] = pointX;
00510       y[( i*numP ) + j] = pointY;
00511       // and the height...
00512       z[( i*numP ) + j] = 0.0;
00513       // QgsDebugMsg(QString("BBox coord: (%1, %2)").arg(x[(i*numP) + j]).arg(y[(i*numP) + j]));
00514       pointX += dx;
00515     }
00516     pointY += dy;
00517   }
00518 
00519   // Do transformation. Any exception generated must
00520   // be handled in above layers.
00521   try
00522   {
00523     transformCoords( numP * numP, x, y, z, direction );
00524   }
00525   catch ( QgsCsException &cse )
00526   {
00527     // rethrow the exception
00528     QgsDebugMsg( "rethrowing exception" );
00529     throw cse;
00530   }
00531 
00532   // Calculate the bounding box and use that for the extent
00533 
00534   for ( int i = 0; i < numP * numP; i++ )
00535   {
00536     if ( qIsFinite( x[i] ) && qIsFinite( y[i] ) )
00537       bb_rect.combineExtentWith( x[i], y[i] );
00538   }
00539 
00540   QgsDebugMsg( "Projected extent: " + bb_rect.toString() );
00541 
00542   if ( bb_rect.isEmpty() )
00543   {
00544     QgsDebugMsg( "Original extent: " + rect.toString() );
00545   }
00546 
00547   return bb_rect;
00548 }
00549 
00550 void QgsCoordinateTransform::transformCoords( const int& numPoints, double *x, double *y, double *z, TransformDirection direction ) const
00551 {
00552   // Refuse to transform the points if the srs's are invalid
00553   if ( !mSourceCRS.isValid() )
00554   {
00555     QgsMessageLog::logMessage( tr( "The source spatial reference system (CRS) is not valid. "
00556                                    "The coordinates can not be reprojected. The CRS is: %1" )
00557                                .arg( mSourceCRS.toProj4() ), tr( "CRS" ) );
00558     return;
00559   }
00560   if ( !mDestCRS.isValid() )
00561   {
00562     QgsMessageLog::logMessage( tr( "The destination spatial reference system (CRS) is not valid. "
00563                                    "The coordinates can not be reprojected. The CRS is: %1" ).arg( mDestCRS.toProj4() ), tr( "CRS" ) );
00564     return;
00565   }
00566 
00567 #ifdef COORDINATE_TRANSFORM_VERBOSE
00568   double xorg = *x;
00569   double yorg = *y;
00570   QgsDebugMsg( QString( "[[[[[[ Number of points to transform: %1 ]]]]]]" ).arg( numPoints ) );
00571 #endif
00572 
00573   // use proj4 to do the transform
00574   QString dir;
00575   // if the source/destination projection is lat/long, convert the points to radians
00576   // prior to transforming
00577   if (( pj_is_latlong( mDestinationProjection ) && ( direction == ReverseTransform ) )
00578       || ( pj_is_latlong( mSourceProjection ) && ( direction == ForwardTransform ) ) )
00579   {
00580     for ( int i = 0; i < numPoints; ++i )
00581     {
00582       x[i] *= DEG_TO_RAD;
00583       y[i] *= DEG_TO_RAD;
00584       z[i] *= DEG_TO_RAD;
00585     }
00586 
00587   }
00588   int projResult;
00589   if ( direction == ReverseTransform )
00590   {
00591     projResult = pj_transform( mDestinationProjection, mSourceProjection, numPoints, 0, x, y, z );
00592     dir = tr( "inverse transform" );
00593   }
00594   else
00595   {
00596     Q_ASSERT( mSourceProjection != 0 );
00597     Q_ASSERT( mDestinationProjection != 0 );
00598     projResult = pj_transform( mSourceProjection, mDestinationProjection, numPoints, 0, x, y, z );
00599     dir = tr( "forward transform" );
00600   }
00601 
00602   if ( projResult != 0 )
00603   {
00604     //something bad happened....
00605     QString points;
00606 
00607     for ( int i = 0; i < numPoints; ++i )
00608     {
00609       if ( direction == ForwardTransform )
00610       {
00611         points += QString( "(%1, %2)\n" ).arg( x[i], 0, 'f' ).arg( y[i], 0, 'f' );
00612       }
00613       else
00614       {
00615         points += QString( "(%1, %2)\n" ).arg( x[i] * RAD_TO_DEG, 0, 'f' ).arg( y[i] * RAD_TO_DEG, 0, 'f' );
00616       }
00617     }
00618 
00619     QString msg = tr( "%1 of\n"
00620                       "%2"
00621                       "PROJ.4: %3 +to %4\n"
00622                       "Error: %5" )
00623                   .arg( dir )
00624                   .arg( points )
00625                   .arg( mSourceCRS.toProj4() ).arg( mDestCRS.toProj4() )
00626                   .arg( QString::fromUtf8( pj_strerrno( projResult ) ) );
00627 
00628     QgsDebugMsg( "Projection failed emitting invalid transform signal: " + msg );
00629 
00630     emit invalidTransformInput();
00631 
00632     QgsDebugMsg( "throwing exception" );
00633 
00634     throw QgsCsException( msg );
00635   }
00636 
00637   // if the result is lat/long, convert the results from radians back
00638   // to degrees
00639   if (( pj_is_latlong( mDestinationProjection ) && ( direction == ForwardTransform ) )
00640       || ( pj_is_latlong( mSourceProjection ) && ( direction == ReverseTransform ) ) )
00641   {
00642     for ( int i = 0; i < numPoints; ++i )
00643     {
00644       x[i] *= RAD_TO_DEG;
00645       y[i] *= RAD_TO_DEG;
00646       z[i] *= RAD_TO_DEG;
00647     }
00648   }
00649 #ifdef COORDINATE_TRANSFORM_VERBOSE
00650   QgsDebugMsg( QString( "[[[[[[ Projected %1, %2 to %3, %4 ]]]]]]" )
00651                .arg( xorg, 0, 'g', 15 ).arg( yorg, 0, 'g', 15 )
00652                .arg( *x, 0, 'g', 15 ).arg( *y, 0, 'g', 15 ) );
00653 #endif
00654 }
00655 
00656 bool QgsCoordinateTransform::readXML( QDomNode & theNode )
00657 {
00658 
00659   QgsDebugMsg( "Reading Coordinate Transform from xml ------------------------!" );
00660 
00661   QDomNode mySrcNode = theNode.namedItem( "sourcesrs" );
00662   mSourceCRS.readXML( mySrcNode );
00663 
00664   QDomNode myDestNode = theNode.namedItem( "destinationsrs" );
00665   mDestCRS.readXML( myDestNode );
00666 
00667   initialise();
00668 
00669   return true;
00670 }
00671 
00672 bool QgsCoordinateTransform::writeXML( QDomNode & theNode, QDomDocument & theDoc )
00673 {
00674   QDomElement myNodeElement = theNode.toElement();
00675   QDomElement myTransformElement = theDoc.createElement( "coordinatetransform" );
00676 
00677   QDomElement mySourceElement = theDoc.createElement( "sourcesrs" );
00678   mSourceCRS.writeXML( mySourceElement, theDoc );
00679   myTransformElement.appendChild( mySourceElement );
00680 
00681   QDomElement myDestElement = theDoc.createElement( "destinationsrs" );
00682   mDestCRS.writeXML( myDestElement, theDoc );
00683   myTransformElement.appendChild( myDestElement );
00684 
00685   myNodeElement.appendChild( myTransformElement );
00686 
00687   return true;
00688 }
00689 
00690 const char *finder( const char *name )
00691 {
00692   QString proj;
00693 #ifdef WIN32
00694   proj = QApplication::applicationDirPath()
00695          + "/share/proj/" + QString( name );
00696 #else
00697   Q_UNUSED( name );
00698 #endif
00699   return proj.toUtf8();
00700 }
00701 
00702 void QgsCoordinateTransform::setFinder()
00703 {
00704 #if 0
00705   // Attention! It should be possible to set PROJ_LIB
00706   // but it can happen that it was previously set by installer
00707   // (version 0.7) and the old installation was deleted
00708 
00709   // Another problem: PROJ checks if pj_finder was set before
00710   // PROJ_LIB environment variable. pj_finder is probably set in
00711   // GRASS gproj library when plugin is loaded, consequently
00712   // PROJ_LIB is ignored
00713 
00714   pj_set_finder( finder );
00715 #endif
00716 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines