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