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