Quantum GIS API Documentation
1.8
|
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 }