34
32
// if defined shows all information about transform to stdout
35
33
// #define COORDINATE_TRANSFORM_VERBOSE
39
QgsCoordinateTransform::QgsCoordinateTransform( ) : QObject(), mSourceCRS(), mDestCRS()
35
QgsCoordinateTransform::QgsCoordinateTransform()
37
, mInitialisedFlag( false )
38
, mSourceProjection( 0 )
39
, mDestinationProjection( 0 )
45
QgsCoordinateTransform::QgsCoordinateTransform( const QgsCoordinateReferenceSystem& source,
46
const QgsCoordinateReferenceSystem& dest )
44
QgsCoordinateTransform::QgsCoordinateTransform( const QgsCoordinateReferenceSystem& source, const QgsCoordinateReferenceSystem& dest )
46
, mInitialisedFlag( false )
47
, mSourceProjection( 0 )
48
, mDestinationProjection( 0 )
49
51
mSourceCRS = source;
54
56
QgsCoordinateTransform::QgsCoordinateTransform( long theSourceSrsId, long theDestSrsId )
55
: mSourceCRS( theSourceSrsId, QgsCoordinateReferenceSystem::InternalCrsId ),
56
mDestCRS( theDestSrsId, QgsCoordinateReferenceSystem::InternalCrsId )
58
, mInitialisedFlag( false )
59
, mSourceCRS( theSourceSrsId, QgsCoordinateReferenceSystem::InternalCrsId )
60
, mDestCRS( theDestSrsId, QgsCoordinateReferenceSystem::InternalCrsId )
61
, mSourceProjection( 0 )
62
, mDestinationProjection( 0 )
61
QgsCoordinateTransform::QgsCoordinateTransform( QString theSourceCRS, QString theDestCRS ) : QObject()
67
QgsCoordinateTransform::QgsCoordinateTransform( QString theSourceCRS, QString theDestCRS )
69
, mInitialisedFlag( false )
70
, mSourceProjection( 0 )
71
, mDestinationProjection( 0 )
65
74
mSourceCRS.createFromWkt( theSourceCRS );
74
83
QgsCoordinateTransform::QgsCoordinateTransform( long theSourceSrid,
75
84
QString theDestWkt,
76
QgsCoordinateReferenceSystem::CrsType theSourceCRSType ): QObject()
85
QgsCoordinateReferenceSystem::CrsType theSourceCRSType )
87
, mInitialisedFlag( false )
88
, mSourceProjection( 0 )
89
, mDestinationProjection( 0 )
89
102
QgsCoordinateTransform::~QgsCoordinateTransform()
91
104
// free the proj objects
92
if ( mSourceProjection != 0 )
105
if ( mSourceProjection )
94
107
pj_free( mSourceProjection );
96
if ( mDestinationProjection != 0 )
109
if ( mDestinationProjection )
98
111
pj_free( mDestinationProjection );
122
134
// And probably shouldn't be a void
123
135
void QgsCoordinateTransform::initialise()
126
mInitialisedFlag = false; //guilty until proven innocent...
127
mSourceProjection = NULL;
128
mDestinationProjection = NULL;
130
137
// XXX Warning - multiple return paths in this block!!
131
138
if ( !mSourceCRS.isValid() )
143
150
//No destination projection is set so we set the default output projection to
144
151
//be the same as input proj. This only happens on the first layer loaded
145
152
//whatever that may be...
146
mDestCRS.createFromProj4( mSourceCRS.toProj4() );
153
mDestCRS.createFromOgcWmsCrs( mSourceCRS.authid() );
149
156
// init the projections (destination and source)
158
165
mInitialisedFlag = true;
159
if ( mDestinationProjection == NULL )
166
if ( !mDestinationProjection )
161
168
mInitialisedFlag = false;
163
if ( mSourceProjection == NULL )
170
if ( !mSourceProjection )
165
172
mInitialisedFlag = false;
194
201
// If the source and destination projection are the same, set the short
195
202
// circuit flag (no transform takes place)
196
203
mShortCircuit = true;
197
QgsDebugMsg( "Source/Dest CRS equal, shortcircuit is set." );
204
QgsDebugMsgLevel( "Source/Dest CRS equal, shortcircuit is set.", 3 );
201
208
// Transform must take place
202
209
mShortCircuit = false;
203
QgsDebugMsg( "Source/Dest CRS UNequal, shortcircuit is NOt set." );
210
QgsDebugMsgLevel( "Source/Dest CRS UNequal, shortcircuit is NOt set.", 3 );
316
323
if ( mShortCircuit || !mInitialisedFlag )
319
assert( x.size() == y.size() );
326
Q_ASSERT( x.size() == y.size() );
321
328
// Apparently, if one has a std::vector, it is valid to use the
322
329
// address of the first element in the vector as a pointer to an
346
353
if ( mShortCircuit || !mInitialisedFlag )
356
if ( rect.isEmpty() )
358
QgsPoint p = transform( rect.xMinimum(), rect.yMinimum(), direction );
359
return QgsRectangle( p, p );
349
362
static const int numP = 8;
351
364
QgsRectangle bb_rect;
403
416
for ( int i = 0; i < numP * numP; i++ )
405
bb_rect.combineExtentWith( x[i], y[i] );
418
if ( qIsFinite( x[i] ) && qIsFinite( y[i] ) )
419
bb_rect.combineExtentWith( x[i], y[i] );
408
422
QgsDebugMsg( "Projected extent: " + QString(( bb_rect.toString() ).toLocal8Bit().data() ) );
454
468
if ( direction == ReverseTransform )
456
470
projResult = pj_transform( mDestinationProjection, mSourceProjection, numPoints, 0, x, y, z );
471
dir = tr( "inverse transform" );
461
assert( mSourceProjection != 0 );
462
assert( mDestinationProjection != 0 );
475
Q_ASSERT( mSourceProjection != 0 );
476
Q_ASSERT( mDestinationProjection != 0 );
463
477
projResult = pj_transform( mSourceProjection, mDestinationProjection, numPoints, 0, x, y, z );
478
dir = tr( "forward transform" );
467
481
if ( projResult != 0 )
469
483
//something bad happened....
471
QTextStream pjErr( &msg );
473
pjErr << tr( "Failed" ) << " " << dir << " " << tr( "transform of" ) << '\n';
474
486
for ( int i = 0; i < numPoints; ++i )
476
488
if ( direction == ForwardTransform )
478
pjErr << "(" << x[i] << ", " << y[i] << ")\n";
490
points += QString( "(%1, %2)\n" ).arg( x[i] ).arg( y[i] );
482
pjErr << "(" << x[i] * RAD_TO_DEG << ", " << y[i] * RAD_TO_DEG << ")\n";
494
points += QString( "(%1, %2)\n" ).arg( x[i] * RAD_TO_DEG ).arg( y[i] * RAD_TO_DEG );
486
pjErr << tr( "with error: " ) << QString::fromUtf8( pj_strerrno( projResult ) ) << '\n';
498
QString msg = tr( "%1 of\n%2\nfailed with error: %3\n" )
501
.arg( QString::fromUtf8( pj_strerrno( projResult ) ) );
488
QgsDebugMsg( "Projection failed emitting invalid transform signal: " + QString( msg.toLocal8Bit().data() ) );
503
QgsDebugMsg( "Projection failed emitting invalid transform signal: " + msg );
490
505
emit invalidTransformInput();
492
QgsLogger::warning( "Throwing exception " + QString( __FILE__ ) + QString::number( __LINE__ ) );
493
throw QgsCsException( msg );
507
QgsDebugMsg( "throwing exception" );
509
throw QgsCsException( msg );
496
512
// if the result is lat/long, convert the results from radians back
531
547
bool QgsCoordinateTransform::writeXML( QDomNode & theNode, QDomDocument & theDoc )
534
549
QDomElement myNodeElement = theNode.toElement();
535
QDomElement myTransformElement = theDoc.createElement( "coordinatetransform" );
550
QDomElement myTransformElement = theDoc.createElement( "coordinatetransform" );
537
QDomElement mySourceElement = theDoc.createElement( "sourcesrs" );
552
QDomElement mySourceElement = theDoc.createElement( "sourcesrs" );
538
553
mSourceCRS.writeXML( mySourceElement, theDoc );
539
554
myTransformElement.appendChild( mySourceElement );
541
QDomElement myDestElement = theDoc.createElement( "destinationsrs" );
556
QDomElement myDestElement = theDoc.createElement( "destinationsrs" );
542
557
mDestCRS.writeXML( myDestElement, theDoc );
543
558
myTransformElement.appendChild( myDestElement );