|
QGIS API Documentation
master-6227475
|
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 }