QGIS API Documentation  master-59fd5e0
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   pj_free( mDestinationProjection );
00159   mDestinationProjection = pj_init_plus( mDestCRS.toProj4().toUtf8() );
00160   pj_free( mSourceProjection );
00161   mSourceProjection = pj_init_plus( mSourceCRS.toProj4().toUtf8() );
00162 
00163 #ifdef COORDINATE_TRANSFORM_VERBOSE
00164   QgsDebugMsg( "From proj : " + mSourceCRS.toProj4() );
00165   QgsDebugMsg( "To proj   : " + mDestCRS.toProj4() );
00166 #endif
00167 
00168   mInitialisedFlag = true;
00169   if ( !mDestinationProjection )
00170   {
00171     mInitialisedFlag = false;
00172   }
00173   if ( !mSourceProjection )
00174   {
00175     mInitialisedFlag = false;
00176   }
00177 #ifdef COORDINATE_TRANSFORM_VERBOSE
00178   if ( mInitialisedFlag )
00179   {
00180     QgsDebugMsg( "------------------------------------------------------------" );
00181     QgsDebugMsg( "The OGR Coordinate transformation for this layer was set to" );
00182     QgsLogger::debug<QgsCoordinateReferenceSystem>( "Input", mSourceCRS, __FILE__, __FUNCTION__, __LINE__ );
00183     QgsLogger::debug<QgsCoordinateReferenceSystem>( "Output", mDestCRS, __FILE__, __FUNCTION__, __LINE__ );
00184     QgsDebugMsg( "------------------------------------------------------------" );
00185   }
00186   else
00187   {
00188     QgsDebugMsg( "------------------------------------------------------------" );
00189     QgsDebugMsg( "The OGR Coordinate transformation FAILED TO INITIALISE!" );
00190     QgsDebugMsg( "------------------------------------------------------------" );
00191   }
00192 #else
00193   if ( !mInitialisedFlag )
00194   {
00195     QgsDebugMsg( "Coordinate transformation failed to initialize!" );
00196   }
00197 #endif
00198 
00199   //XXX todo overload == operator for QgsCoordinateReferenceSystem
00200   //at the moment srs.parameters contains the whole proj def...soon it wont...
00201   //if (mSourceCRS->toProj4() == mDestCRS->toProj4())
00202   if ( mSourceCRS == mDestCRS )
00203   {
00204     // If the source and destination projection are the same, set the short
00205     // circuit flag (no transform takes place)
00206     mShortCircuit = true;
00207     QgsDebugMsgLevel( "Source/Dest CRS equal, shortcircuit is set.", 3 );
00208   }
00209   else
00210   {
00211     // Transform must take place
00212     mShortCircuit = false;
00213     QgsDebugMsgLevel( "Source/Dest CRS UNequal, shortcircuit is NOt set.", 3 );
00214   }
00215 
00216 }
00217 
00218 //
00219 //
00220 // TRANSFORMERS BELOW THIS POINT .........
00221 //
00222 //
00223 //
00224 
00225 
00226 QgsPoint QgsCoordinateTransform::transform( const QgsPoint thePoint, TransformDirection direction ) const
00227 {
00228   if ( mShortCircuit || !mInitialisedFlag )
00229     return thePoint;
00230   // transform x
00231   double x = thePoint.x();
00232   double y = thePoint.y();
00233   double z = 0.0;
00234   try
00235   {
00236     transformCoords( 1, &x, &y, &z, direction );
00237   }
00238   catch ( QgsCsException &cse )
00239   {
00240     // rethrow the exception
00241     QgsDebugMsg( "rethrowing exception" );
00242     throw cse;
00243   }
00244 
00245   return QgsPoint( x, y );
00246 }
00247 
00248 
00249 QgsPoint QgsCoordinateTransform::transform( const double theX, const double theY = 0, TransformDirection direction ) const
00250 {
00251   try
00252   {
00253     return transform( QgsPoint( theX, theY ), direction );
00254   }
00255   catch ( QgsCsException &cse )
00256   {
00257     // rethrow the exception
00258     QgsDebugMsg( "rethrowing exception" );
00259     throw cse;
00260   }
00261 }
00262 
00263 QgsRectangle QgsCoordinateTransform::transform( const QgsRectangle theRect, TransformDirection direction ) const
00264 {
00265   if ( mShortCircuit || !mInitialisedFlag )
00266     return theRect;
00267   // transform x
00268   double x1 = theRect.xMinimum();
00269   double y1 = theRect.yMinimum();
00270   double x2 = theRect.xMaximum();
00271   double y2 = theRect.yMaximum();
00272 
00273   // Number of points to reproject------+
00274   //                                    |
00275   //                                    V
00276   try
00277   {
00278     double z = 0.0;
00279     transformCoords( 1, &x1, &y1, &z, direction );
00280     transformCoords( 1, &x2, &y2, &z, direction );
00281   }
00282   catch ( QgsCsException &cse )
00283   {
00284     // rethrow the exception
00285     QgsDebugMsg( "rethrowing exception" );
00286     throw cse;
00287   }
00288 
00289 #ifdef COORDINATE_TRANSFORM_VERBOSE
00290   QgsDebugMsg( "Rect projection..." );
00291   QgsLogger::debug( "Xmin : ", theRect.xMinimum(), 1, __FILE__, __FUNCTION__, __LINE__ );
00292   QgsLogger::debug( "-->", x1, 1, __FILE__, __FUNCTION__, __LINE__ );
00293   QgsLogger::debug( "Ymin : ", theRect.yMinimum(), 1, __FILE__, __FUNCTION__, __LINE__ );
00294   QgsLogger::debug( "-->", y1, 1, __FILE__, __FUNCTION__, __LINE__ );
00295   QgsLogger::debug( "Xmax : ", theRect.xMaximum(), 1, __FILE__, __FUNCTION__, __LINE__ );
00296   QgsLogger::debug( "-->", x2, 1, __FILE__, __FUNCTION__, __LINE__ );
00297   QgsLogger::debug( "Ymax : ", theRect.yMaximum(), 1, __FILE__, __FUNCTION__, __LINE__ );
00298   QgsLogger::debug( "-->", y2, 1, __FILE__, __FUNCTION__, __LINE__ );
00299 #endif
00300   return QgsRectangle( x1, y1, x2, y2 );
00301 }
00302 
00303 void QgsCoordinateTransform::transformInPlace( double& x, double& y, double& z,
00304     TransformDirection direction ) const
00305 {
00306   if ( mShortCircuit || !mInitialisedFlag )
00307     return;
00308 #ifdef QGISDEBUG
00309 // QgsDebugMsg(QString("Using transform in place %1 %2").arg(__FILE__).arg(__LINE__));
00310 #endif
00311   // transform x
00312   try
00313   {
00314     transformCoords( 1, &x, &y, &z, direction );
00315   }
00316   catch ( QgsCsException &cse )
00317   {
00318     // rethrow the exception
00319     QgsDebugMsg( "rethrowing exception" );
00320     throw cse;
00321   }
00322 }
00323 
00324 void QgsCoordinateTransform::transformPolygon( QPolygonF& poly, TransformDirection direction ) const
00325 {
00326   if ( mShortCircuit || !mInitialisedFlag )
00327   {
00328     return;
00329   }
00330 
00331   //create x, y arrays
00332   int nVertices = poly.size();
00333 
00334   QVector<double> x( nVertices );
00335   QVector<double> y( nVertices );
00336   QVector<double> z( nVertices );
00337 
00338   for ( int i = 0; i < nVertices; ++i )
00339   {
00340     const QPointF& pt = poly.at( i );
00341     x[i] = pt.x();
00342     y[i] = pt.y();
00343     z[i] = 0;
00344   }
00345 
00346   try
00347   {
00348     transformCoords( nVertices, x.data(), y.data(), z.data(), direction );
00349   }
00350   catch ( QgsCsException &cse )
00351   {
00352     // rethrow the exception
00353     QgsDebugMsg( "rethrowing exception" );
00354     throw cse;
00355   }
00356 
00357   for ( int i = 0; i < nVertices; ++i )
00358   {
00359     QPointF& pt = poly[i];
00360     pt.rx() = x[i];
00361     pt.ry() = y[i];
00362   }
00363 }
00364 
00365 void QgsCoordinateTransform::transformInPlace(
00366   QVector<double>& x, QVector<double>& y, QVector<double>& z,
00367   TransformDirection direction ) const
00368 {
00369   if ( mShortCircuit || !mInitialisedFlag )
00370     return;
00371 
00372   Q_ASSERT( x.size() == y.size() );
00373 
00374   // Apparently, if one has a std::vector, it is valid to use the
00375   // address of the first element in the vector as a pointer to an
00376   // array of the vectors data, and hence easily interface with code
00377   // that wants C-style arrays.
00378 
00379   try
00380   {
00381     transformCoords( x.size(), &x[0], &y[0], &z[0], direction );
00382   }
00383   catch ( QgsCsException &cse )
00384   {
00385     // rethrow the exception
00386     QgsDebugMsg( "rethrowing exception" );
00387     throw cse;
00388   }
00389 }
00390 
00391 #ifdef ANDROID
00392 void QgsCoordinateTransform::transformInPlace( float& x, float& y, float& z,
00393     TransformDirection direction ) const
00394 {
00395   if ( mShortCircuit || !mInitialisedFlag )
00396     return;
00397 #ifdef QGISDEBUG
00398 // QgsDebugMsg(QString("Using transform in place %1 %2").arg(__FILE__).arg(__LINE__));
00399 #endif
00400   // transform x
00401   try
00402   {
00403     double xd = x;
00404     double yd = y;
00405     double zd = z;
00406     transformCoords( 1, &xd, &yd, &zd, direction );
00407     x = xd;
00408     y = yd;
00409     z = zd;
00410   }
00411   catch ( QgsCsException &cse )
00412   {
00413     // rethrow the exception
00414     QgsDebugMsg( "rethrowing exception" );
00415     throw cse;
00416   }
00417 }
00418 
00419 void QgsCoordinateTransform::transformInPlace(
00420   QVector<float>& x, QVector<float>& y, QVector<float>& z,
00421   TransformDirection direction ) const
00422 {
00423   if ( mShortCircuit || !mInitialisedFlag )
00424     return;
00425 
00426   Q_ASSERT( x.size() == y.size() );
00427 
00428   // Apparently, if one has a std::vector, it is valid to use the
00429   // address of the first element in the vector as a pointer to an
00430   // array of the vectors data, and hence easily interface with code
00431   // that wants C-style arrays.
00432 
00433   try
00434   {
00435     //copy everything to double vectors since proj needs double
00436     int vectorSize = x.size();
00437     QVector<double> xd( x.size() );
00438     QVector<double> yd( y.size() );
00439     QVector<double> zd( z.size() );
00440     for ( int i = 0; i < vectorSize; ++i )
00441     {
00442       xd[i] = x[i];
00443       yd[i] = y[i];
00444       zd[i] = z[i];
00445     }
00446     transformCoords( x.size(), &xd[0], &yd[0], &zd[0], direction );
00447 
00448     //copy back
00449     for ( int i = 0; i < vectorSize; ++i )
00450     {
00451       x[i] = xd[i];
00452       y[i] = yd[i];
00453       z[i] = zd[i];
00454     }
00455   }
00456   catch ( QgsCsException &cse )
00457   {
00458     // rethrow the exception
00459     QgsDebugMsg( "rethrowing exception" );
00460     throw cse;
00461   }
00462 }
00463 #endif //ANDROID
00464 
00465 
00466 QgsRectangle QgsCoordinateTransform::transformBoundingBox( const QgsRectangle rect, TransformDirection direction ) const
00467 {
00468   // Calculate the bounding box of a QgsRectangle in the source CRS
00469   // when projected to the destination CRS (or the inverse).
00470   // This is done by looking at a number of points spread evenly
00471   // across the rectangle
00472 
00473   if ( mShortCircuit || !mInitialisedFlag )
00474     return rect;
00475 
00476   if ( rect.isEmpty() )
00477   {
00478     QgsPoint p = transform( rect.xMinimum(), rect.yMinimum(), direction );
00479     return QgsRectangle( p, p );
00480   }
00481 
00482   static const int numP = 8;
00483 
00484   QgsRectangle bb_rect;
00485   bb_rect.setMinimal();
00486 
00487   // We're interfacing with C-style vectors in the
00488   // end, so let's do C-style vectors here too.
00489 
00490   double x[numP * numP];
00491   double y[numP * numP];
00492   double z[numP * numP];
00493 
00494   QgsDebugMsg( "Entering transformBoundingBox..." );
00495 
00496   // Populate the vectors
00497 
00498   double dx = rect.width()  / ( double )( numP - 1 );
00499   double dy = rect.height() / ( double )( numP - 1 );
00500 
00501   double pointY = rect.yMinimum();
00502 
00503   for ( int i = 0; i < numP ; i++ )
00504   {
00505 
00506     // Start at right edge
00507     double pointX = rect.xMinimum();
00508 
00509     for ( int j = 0; j < numP; j++ )
00510     {
00511       x[( i*numP ) + j] = pointX;
00512       y[( i*numP ) + j] = pointY;
00513       // and the height...
00514       z[( i*numP ) + j] = 0.0;
00515       // QgsDebugMsg(QString("BBox coord: (%1, %2)").arg(x[(i*numP) + j]).arg(y[(i*numP) + j]));
00516       pointX += dx;
00517     }
00518     pointY += dy;
00519   }
00520 
00521   // Do transformation. Any exception generated must
00522   // be handled in above layers.
00523   try
00524   {
00525     transformCoords( numP * numP, x, y, z, direction );
00526   }
00527   catch ( QgsCsException &cse )
00528   {
00529     // rethrow the exception
00530     QgsDebugMsg( "rethrowing exception" );
00531     throw cse;
00532   }
00533 
00534   // Calculate the bounding box and use that for the extent
00535 
00536   for ( int i = 0; i < numP * numP; i++ )
00537   {
00538     if ( qIsFinite( x[i] ) && qIsFinite( y[i] ) )
00539       bb_rect.combineExtentWith( x[i], y[i] );
00540   }
00541 
00542   QgsDebugMsg( "Projected extent: " + bb_rect.toString() );
00543 
00544   if ( bb_rect.isEmpty() )
00545   {
00546     QgsDebugMsg( "Original extent: " + rect.toString() );
00547   }
00548 
00549   return bb_rect;
00550 }
00551 
00552 void QgsCoordinateTransform::transformCoords( const int& numPoints, double *x, double *y, double *z, TransformDirection direction ) const
00553 {
00554   // Refuse to transform the points if the srs's are invalid
00555   if ( !mSourceCRS.isValid() )
00556   {
00557     QgsMessageLog::logMessage( tr( "The source spatial reference system (CRS) is not valid. "
00558                                    "The coordinates can not be reprojected. The CRS is: %1" )
00559                                .arg( mSourceCRS.toProj4() ), tr( "CRS" ) );
00560     return;
00561   }
00562   if ( !mDestCRS.isValid() )
00563   {
00564     QgsMessageLog::logMessage( tr( "The destination spatial reference system (CRS) is not valid. "
00565                                    "The coordinates can not be reprojected. The CRS is: %1" ).arg( mDestCRS.toProj4() ), tr( "CRS" ) );
00566     return;
00567   }
00568 
00569 #ifdef COORDINATE_TRANSFORM_VERBOSE
00570   double xorg = *x;
00571   double yorg = *y;
00572   QgsDebugMsg( QString( "[[[[[[ Number of points to transform: %1 ]]]]]]" ).arg( numPoints ) );
00573 #endif
00574 
00575   // use proj4 to do the transform
00576   QString dir;
00577   // if the source/destination projection is lat/long, convert the points to radians
00578   // prior to transforming
00579   if (( pj_is_latlong( mDestinationProjection ) && ( direction == ReverseTransform ) )
00580       || ( pj_is_latlong( mSourceProjection ) && ( direction == ForwardTransform ) ) )
00581   {
00582     for ( int i = 0; i < numPoints; ++i )
00583     {
00584       x[i] *= DEG_TO_RAD;
00585       y[i] *= DEG_TO_RAD;
00586       z[i] *= DEG_TO_RAD;
00587     }
00588 
00589   }
00590   int projResult;
00591   if ( direction == ReverseTransform )
00592   {
00593     projResult = pj_transform( mDestinationProjection, mSourceProjection, numPoints, 0, x, y, z );
00594     dir = tr( "inverse transform" );
00595   }
00596   else
00597   {
00598     Q_ASSERT( mSourceProjection != 0 );
00599     Q_ASSERT( mDestinationProjection != 0 );
00600     projResult = pj_transform( mSourceProjection, mDestinationProjection, numPoints, 0, x, y, z );
00601     dir = tr( "forward transform" );
00602   }
00603 
00604   if ( projResult != 0 )
00605   {
00606     //something bad happened....
00607     QString points;
00608 
00609     for ( int i = 0; i < numPoints; ++i )
00610     {
00611       if ( direction == ForwardTransform )
00612       {
00613         points += QString( "(%1, %2)\n" ).arg( x[i], 0, 'f' ).arg( y[i], 0, 'f' );
00614       }
00615       else
00616       {
00617         points += QString( "(%1, %2)\n" ).arg( x[i] * RAD_TO_DEG, 0, 'f' ).arg( y[i] * RAD_TO_DEG, 0, 'f' );
00618       }
00619     }
00620 
00621     QString msg = tr( "%1 of\n"
00622                       "%2"
00623                       "PROJ.4: %3 +to %4\n"
00624                       "Error: %5" )
00625                   .arg( dir )
00626                   .arg( points )
00627                   .arg( mSourceCRS.toProj4() ).arg( mDestCRS.toProj4() )
00628                   .arg( QString::fromUtf8( pj_strerrno( projResult ) ) );
00629 
00630     QgsDebugMsg( "Projection failed emitting invalid transform signal: " + msg );
00631 
00632     emit invalidTransformInput();
00633 
00634     QgsDebugMsg( "throwing exception" );
00635 
00636     throw QgsCsException( msg );
00637   }
00638 
00639   // if the result is lat/long, convert the results from radians back
00640   // to degrees
00641   if (( pj_is_latlong( mDestinationProjection ) && ( direction == ForwardTransform ) )
00642       || ( pj_is_latlong( mSourceProjection ) && ( direction == ReverseTransform ) ) )
00643   {
00644     for ( int i = 0; i < numPoints; ++i )
00645     {
00646       x[i] *= RAD_TO_DEG;
00647       y[i] *= RAD_TO_DEG;
00648       z[i] *= RAD_TO_DEG;
00649     }
00650   }
00651 #ifdef COORDINATE_TRANSFORM_VERBOSE
00652   QgsDebugMsg( QString( "[[[[[[ Projected %1, %2 to %3, %4 ]]]]]]" )
00653                .arg( xorg, 0, 'g', 15 ).arg( yorg, 0, 'g', 15 )
00654                .arg( *x, 0, 'g', 15 ).arg( *y, 0, 'g', 15 ) );
00655 #endif
00656 }
00657 
00658 bool QgsCoordinateTransform::readXML( QDomNode & theNode )
00659 {
00660 
00661   QgsDebugMsg( "Reading Coordinate Transform from xml ------------------------!" );
00662 
00663   QDomNode mySrcNode = theNode.namedItem( "sourcesrs" );
00664   mSourceCRS.readXML( mySrcNode );
00665 
00666   QDomNode myDestNode = theNode.namedItem( "destinationsrs" );
00667   mDestCRS.readXML( myDestNode );
00668 
00669   initialise();
00670 
00671   return true;
00672 }
00673 
00674 bool QgsCoordinateTransform::writeXML( QDomNode & theNode, QDomDocument & theDoc )
00675 {
00676   QDomElement myNodeElement = theNode.toElement();
00677   QDomElement myTransformElement = theDoc.createElement( "coordinatetransform" );
00678 
00679   QDomElement mySourceElement = theDoc.createElement( "sourcesrs" );
00680   mSourceCRS.writeXML( mySourceElement, theDoc );
00681   myTransformElement.appendChild( mySourceElement );
00682 
00683   QDomElement myDestElement = theDoc.createElement( "destinationsrs" );
00684   mDestCRS.writeXML( myDestElement, theDoc );
00685   myTransformElement.appendChild( myDestElement );
00686 
00687   myNodeElement.appendChild( myTransformElement );
00688 
00689   return true;
00690 }
00691 
00692 const char *finder( const char *name )
00693 {
00694   QString proj;
00695 #ifdef WIN32
00696   proj = QApplication::applicationDirPath()
00697          + "/share/proj/" + QString( name );
00698 #else
00699   Q_UNUSED( name );
00700 #endif
00701   return proj.toUtf8();
00702 }
00703 
00704 void QgsCoordinateTransform::setFinder()
00705 {
00706 #if 0
00707   // Attention! It should be possible to set PROJ_LIB
00708   // but it can happen that it was previously set by installer
00709   // (version 0.7) and the old installation was deleted
00710 
00711   // Another problem: PROJ checks if pj_finder was set before
00712   // PROJ_LIB environment variable. pj_finder is probably set in
00713   // GRASS gproj library when plugin is loaded, consequently
00714   // PROJ_LIB is ignored
00715 
00716   pj_set_finder( finder );
00717 #endif
00718 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines