~ubuntu-branches/ubuntu/wily/qgis/wily

« back to all changes in this revision

Viewing changes to src/core/qgscoordinatetransform.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2012-04-24 15:12:20 UTC
  • mfrom: (3.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20120424151220-r88g00af5fpn5fc3
Tags: 1.7.4+1.7.5~20120320-1
The "Sometimes they come back" release.

* Branching from Qgis tree and adapting to current Debian Policy and
  standards. The target tree is currently set to release-1.7.
  (closes: #661491, #606304, #615683, #616182, #600308)
* Policy bumped to 3.9.3.
* Moving to debhelper compatibility level 9.
* Source format is now 3.0 with quilt support.
* Merged with 2bf42287 upstream git snapshot.
* Migrated to dh_python2 instead of python-central.
  (closes: #617048)
* Snapshot in qgis.org release-1.7: c936d031
* Added an automagic creation of a lintian override for sqlite embedding.
  This is required for uploading currently.
* Added missing ${misc:Depends} to make lintian happy.
* Copyright notes updated and debian/copyright moved to format 1.0.
* More licenses notices now reported in debian/copyright. Thanks ftpmasters.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 *                                                                         *
16
16
 ***************************************************************************/
17
17
/* $Id$ */
18
 
#include <cassert>
19
18
#include "qgscoordinatetransform.h"
 
19
#include "qgsmessageoutput.h"
20
20
#include "qgslogger.h"
21
21
 
22
22
//qt includes
23
23
#include <QDomNode>
24
24
#include <QDomElement>
25
 
#include <QTextStream>
26
25
#include <QApplication>
27
 
#include "qgslogger.h"
28
26
 
29
27
extern "C"
30
28
{
34
32
// if defined shows all information about transform to stdout
35
33
// #define COORDINATE_TRANSFORM_VERBOSE
36
34
 
37
 
 
38
 
 
39
 
QgsCoordinateTransform::QgsCoordinateTransform( ) : QObject(), mSourceCRS(), mDestCRS()
40
 
 
 
35
QgsCoordinateTransform::QgsCoordinateTransform()
 
36
    : QObject()
 
37
    , mInitialisedFlag( false )
 
38
    , mSourceProjection( 0 )
 
39
    , mDestinationProjection( 0 )
41
40
{
42
41
  setFinder();
43
42
}
44
43
 
45
 
QgsCoordinateTransform::QgsCoordinateTransform( const QgsCoordinateReferenceSystem& source,
46
 
    const QgsCoordinateReferenceSystem& dest )
 
44
QgsCoordinateTransform::QgsCoordinateTransform( const QgsCoordinateReferenceSystem& source, const QgsCoordinateReferenceSystem& dest )
 
45
    : QObject()
 
46
    , mInitialisedFlag( false )
 
47
    , mSourceProjection( 0 )
 
48
    , mDestinationProjection( 0 )
47
49
{
48
50
  setFinder();
49
51
  mSourceCRS = source;
52
54
}
53
55
 
54
56
QgsCoordinateTransform::QgsCoordinateTransform( long theSourceSrsId, long theDestSrsId )
55
 
    : mSourceCRS( theSourceSrsId, QgsCoordinateReferenceSystem::InternalCrsId ),
56
 
    mDestCRS( theDestSrsId, QgsCoordinateReferenceSystem::InternalCrsId )
 
57
    : QObject()
 
58
    , mInitialisedFlag( false )
 
59
    , mSourceCRS( theSourceSrsId, QgsCoordinateReferenceSystem::InternalCrsId )
 
60
    , mDestCRS( theDestSrsId, QgsCoordinateReferenceSystem::InternalCrsId )
 
61
    , mSourceProjection( 0 )
 
62
    , mDestinationProjection( 0 )
57
63
{
58
64
  initialise();
59
65
}
60
66
 
61
 
QgsCoordinateTransform::QgsCoordinateTransform( QString theSourceCRS, QString theDestCRS ) : QObject()
62
 
 
 
67
QgsCoordinateTransform::QgsCoordinateTransform( QString theSourceCRS, QString theDestCRS )
 
68
    : QObject()
 
69
    , mInitialisedFlag( false )
 
70
    , mSourceProjection( 0 )
 
71
    , mDestinationProjection( 0 )
63
72
{
64
73
  setFinder();
65
74
  mSourceCRS.createFromWkt( theSourceCRS );
73
82
 
74
83
QgsCoordinateTransform::QgsCoordinateTransform( long theSourceSrid,
75
84
    QString theDestWkt,
76
 
    QgsCoordinateReferenceSystem::CrsType theSourceCRSType ): QObject()
 
85
    QgsCoordinateReferenceSystem::CrsType theSourceCRSType )
 
86
    : QObject()
 
87
    , mInitialisedFlag( false )
 
88
    , mSourceProjection( 0 )
 
89
    , mDestinationProjection( 0 )
77
90
{
78
91
  setFinder();
79
92
 
89
102
QgsCoordinateTransform::~QgsCoordinateTransform()
90
103
{
91
104
  // free the proj objects
92
 
  if ( mSourceProjection != 0 )
 
105
  if ( mSourceProjection )
93
106
  {
94
107
    pj_free( mSourceProjection );
95
108
  }
96
 
  if ( mDestinationProjection != 0 )
 
109
  if ( mDestinationProjection )
97
110
  {
98
111
    pj_free( mDestinationProjection );
99
112
  }
110
123
  initialise();
111
124
}
112
125
 
113
 
 
114
126
void QgsCoordinateTransform::setDestCRSID( long theCRSID )
115
127
{
116
128
  //!todo Add some logic here to determine if the srsid is a system or user one
122
134
// And probably shouldn't be a void
123
135
void QgsCoordinateTransform::initialise()
124
136
{
125
 
 
126
 
  mInitialisedFlag = false; //guilty until proven innocent...
127
 
  mSourceProjection = NULL;
128
 
  mDestinationProjection = NULL;
129
 
 
130
137
  // XXX Warning - multiple return paths in this block!!
131
138
  if ( !mSourceCRS.isValid() )
132
139
  {
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() );
147
154
  }
148
155
 
149
156
  // init the projections (destination and source)
156
163
#endif
157
164
 
158
165
  mInitialisedFlag = true;
159
 
  if ( mDestinationProjection == NULL )
 
166
  if ( !mDestinationProjection )
160
167
  {
161
168
    mInitialisedFlag = false;
162
169
  }
163
 
  if ( mSourceProjection == NULL )
 
170
  if ( !mSourceProjection )
164
171
  {
165
172
    mInitialisedFlag = false;
166
173
  }
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 );
198
205
  }
199
206
  else
200
207
  {
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 );
204
211
  }
205
212
 
206
213
}
227
234
  catch ( QgsCsException &cse )
228
235
  {
229
236
    // rethrow the exception
230
 
    QgsLogger::warning( "Throwing exception " + QString( __FILE__ ) + QString::number( __LINE__ ) );
 
237
    QgsDebugMsg( "rethrowing exception" );
231
238
    throw cse;
232
239
  }
233
240
 
244
251
  catch ( QgsCsException &cse )
245
252
  {
246
253
    // rethrow the exception
247
 
    QgsLogger::warning( "Throwing exception " + QString( __FILE__ ) + QString::number( __LINE__ ) );
 
254
    QgsDebugMsg( "rethrowing exception" );
248
255
    throw cse;
249
256
  }
250
257
}
270
277
  catch ( QgsCsException &cse )
271
278
  {
272
279
    // rethrow the exception
273
 
    QgsLogger::warning( "Throwing exception " + QString( __FILE__ ) + QString::number( __LINE__ ) );
 
280
    QgsDebugMsg( "rethrowing exception" );
274
281
    throw cse;
275
282
  }
276
283
 
304
311
  catch ( QgsCsException &cse )
305
312
  {
306
313
    // rethrow the exception
307
 
    QgsLogger::warning( "Throwing exception " + QString( __FILE__ ) + QString::number( __LINE__ ) );
 
314
    QgsDebugMsg( "rethrowing exception" );
308
315
    throw cse;
309
316
  }
310
317
}
316
323
  if ( mShortCircuit || !mInitialisedFlag )
317
324
    return;
318
325
 
319
 
  assert( x.size() == y.size() );
 
326
  Q_ASSERT( x.size() == y.size() );
320
327
 
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
330
337
  catch ( QgsCsException &cse )
331
338
  {
332
339
    // rethrow the exception
333
 
    QgsLogger::warning( "Throwing exception " + QString( __FILE__ ) + QString::number( __LINE__ ) );
 
340
    QgsDebugMsg( "rethrowing exception" );
334
341
    throw cse;
335
342
  }
336
343
}
346
353
  if ( mShortCircuit || !mInitialisedFlag )
347
354
    return rect;
348
355
 
 
356
  if ( rect.isEmpty() )
 
357
  {
 
358
    QgsPoint p = transform( rect.xMinimum(), rect.yMinimum(), direction );
 
359
    return QgsRectangle( p, p );
 
360
  }
 
361
 
349
362
  static const int numP = 8;
350
363
 
351
364
  QgsRectangle bb_rect;
394
407
  catch ( QgsCsException &cse )
395
408
  {
396
409
    // rethrow the exception
397
 
    QgsLogger::warning( "Throwing exception " + QString( __FILE__ ) + QString::number( __LINE__ ) );
 
410
    QgsDebugMsg( "rethrowing exception" );
398
411
    throw cse;
399
412
  }
400
413
 
402
415
 
403
416
  for ( int i = 0; i < numP * numP; i++ )
404
417
  {
405
 
    bb_rect.combineExtentWith( x[i], y[i] );
 
418
    if ( qIsFinite( x[i] ) && qIsFinite( y[i] ) )
 
419
      bb_rect.combineExtentWith( x[i], y[i] );
406
420
  }
407
421
 
408
422
  QgsDebugMsg( "Projected extent: " + QString(( bb_rect.toString() ).toLocal8Bit().data() ) );
454
468
  if ( direction == ReverseTransform )
455
469
  {
456
470
    projResult = pj_transform( mDestinationProjection, mSourceProjection, numPoints, 0, x, y, z );
457
 
    dir = "inverse";
 
471
    dir = tr( "inverse transform" );
458
472
  }
459
473
  else
460
474
  {
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 );
464
 
    dir = "forward";
 
478
    dir = tr( "forward transform" );
465
479
  }
466
480
 
467
481
  if ( projResult != 0 )
468
482
  {
469
483
    //something bad happened....
470
 
    QString msg;
471
 
    QTextStream pjErr( &msg );
 
484
    QString points;
472
485
 
473
 
    pjErr << tr( "Failed" ) << " " << dir << " " << tr( "transform of" ) << '\n';
474
486
    for ( int i = 0; i < numPoints; ++i )
475
487
    {
476
488
      if ( direction == ForwardTransform )
477
489
      {
478
 
        pjErr << "(" << x[i] << ", " << y[i] << ")\n";
 
490
        points += QString( "(%1, %2)\n" ).arg( x[i] ).arg( y[i] );
479
491
      }
480
492
      else
481
493
      {
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 );
483
495
      }
484
496
    }
485
497
 
486
 
    pjErr << tr( "with error: " ) << QString::fromUtf8( pj_strerrno( projResult ) ) << '\n';
 
498
    QString msg = tr( "%1 of\n%2\nfailed with error: %3\n" )
 
499
                  .arg( dir )
 
500
                  .arg( points )
 
501
                  .arg( QString::fromUtf8( pj_strerrno( projResult ) ) );
487
502
 
488
 
    QgsDebugMsg( "Projection failed emitting invalid transform signal: " + QString( msg.toLocal8Bit().data() ) );
 
503
    QgsDebugMsg( "Projection failed emitting invalid transform signal: " + msg );
489
504
 
490
505
    emit invalidTransformInput();
491
506
 
492
 
    QgsLogger::warning( "Throwing exception " + QString( __FILE__ ) + QString::number( __LINE__ ) );
493
 
    throw  QgsCsException( msg );
 
507
    QgsDebugMsg( "throwing exception" );
 
508
 
 
509
    throw QgsCsException( msg );
494
510
  }
495
511
 
496
512
  // if the result is lat/long, convert the results from radians back
530
546
 
531
547
bool QgsCoordinateTransform::writeXML( QDomNode & theNode, QDomDocument & theDoc )
532
548
{
533
 
 
534
549
  QDomElement myNodeElement = theNode.toElement();
535
 
  QDomElement myTransformElement  = theDoc.createElement( "coordinatetransform" );
 
550
  QDomElement myTransformElement = theDoc.createElement( "coordinatetransform" );
536
551
 
537
 
  QDomElement mySourceElement  = theDoc.createElement( "sourcesrs" );
 
552
  QDomElement mySourceElement = theDoc.createElement( "sourcesrs" );
538
553
  mSourceCRS.writeXML( mySourceElement, theDoc );
539
554
  myTransformElement.appendChild( mySourceElement );
540
555
 
541
 
  QDomElement myDestElement  = theDoc.createElement( "destinationsrs" );
 
556
  QDomElement myDestElement = theDoc.createElement( "destinationsrs" );
542
557
  mDestCRS.writeXML( myDestElement, theDoc );
543
558
  myTransformElement.appendChild( myDestElement );
544
559
 
559
574
 
560
575
void QgsCoordinateTransform::setFinder()
561
576
{
562
 
#ifdef WIN32
 
577
#if 0
563
578
  // Attention! It should be possible to set PROJ_LIB
564
579
  // but it can happen that it was previously set by installer
565
580
  // (version 0.7) and the old installation was deleted
572
587
  pj_set_finder( finder );
573
588
#endif
574
589
}
575