QGIS API Documentation  2.0.1-Dufour
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgscoordinatetransform.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  QgsCoordinateTransform.cpp - Coordinate Transforms
3  -------------------
4  begin : Dec 2004
5  copyright : (C) 2004 Tim Sutton
6  email : tim at linfiniti.com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 #include "qgscoordinatetransform.h"
18 #include "qgscrscache.h"
19 #include "qgsmessagelog.h"
20 #include "qgslogger.h"
21 
22 //qt includes
23 #include <QDomNode>
24 #include <QDomElement>
25 #include <QApplication>
26 #include <QPolygonF>
27 #include <QVector>
28 
29 extern "C"
30 {
31 #include <proj_api.h>
32 }
33 
34 // if defined shows all information about transform to stdout
35 // #define COORDINATE_TRANSFORM_VERBOSE
36 
38  : QObject()
39  , mInitialisedFlag( false )
40  , mSourceProjection( 0 )
41  , mDestinationProjection( 0 )
42 {
43  setFinder();
44 }
45 
47  : QObject()
48  , mInitialisedFlag( false )
49  , mSourceProjection( 0 )
50  , mDestinationProjection( 0 )
51 {
52  setFinder();
53  mSourceCRS = source;
54  mDestCRS = dest;
55  initialise();
56 }
57 
58 QgsCoordinateTransform::QgsCoordinateTransform( long theSourceSrsId, long theDestSrsId )
59  : QObject()
60  , mInitialisedFlag( false )
61  , mSourceCRS( theSourceSrsId, QgsCoordinateReferenceSystem::InternalCrsId )
62  , mDestCRS( theDestSrsId, QgsCoordinateReferenceSystem::InternalCrsId )
63  , mSourceProjection( 0 )
64  , mDestinationProjection( 0 )
65 {
66  initialise();
67 }
68 
69 QgsCoordinateTransform::QgsCoordinateTransform( QString theSourceCRS, QString theDestCRS )
70  : QObject()
71  , mInitialisedFlag( false )
72  , mSourceProjection( 0 )
73  , mDestinationProjection( 0 )
74 {
75  setFinder();
76  mSourceCRS.createFromWkt( theSourceCRS );
77  mDestCRS.createFromWkt( theDestCRS );
78  // initialize the coordinate system data structures
79  //XXX Who spells initialize initialise?
80  //XXX A: Its the queen's english....
81  //XXX : Long live the queen! Lets get on with the initialisation...
82  initialise();
83 }
84 
86  QString theDestWkt,
87  QgsCoordinateReferenceSystem::CrsType theSourceCRSType )
88  : QObject()
89  , mInitialisedFlag( false )
90  , mSourceProjection( 0 )
91  , mDestinationProjection( 0 )
92 {
93  setFinder();
94 
95  mSourceCRS.createFromId( theSourceSrid, theSourceCRSType );
96  mDestCRS.createFromWkt( theDestWkt );
97  // initialize the coordinate system data structures
98  //XXX Who spells initialize initialise?
99  //XXX A: Its the queen's english....
100  //XXX : Long live the queen! Lets get on with the initialisation...
101  initialise();
102 }
103 
105 {
106  // free the proj objects
107  if ( mSourceProjection )
108  {
109  pj_free( mSourceProjection );
110  }
112  {
113  pj_free( mDestinationProjection );
114  }
115 }
116 
118 {
119  mSourceCRS = theCRS;
120  initialise();
121 }
123 {
124  mDestCRS = theCRS;
125  initialise();
126 }
127 
129 {
131  mDestCRS.createFromSrsId( theCRSID );
132  initialise();
133 }
134 
135 // XXX This whole function is full of multiple return statements!!!
136 // And probably shouldn't be a void
138 {
139  // XXX Warning - multiple return paths in this block!!
140  if ( !mSourceCRS.isValid() )
141  {
142  //mSourceCRS = defaultWkt;
143  // Pass through with no projection since we have no idea what the layer
144  // coordinates are and projecting them may not be appropriate
145  mShortCircuit = true;
146  QgsDebugMsg( "SourceCRS seemed invalid!" );
147  return;
148  }
149 
150  if ( !mDestCRS.isValid() )
151  {
152  //No destination projection is set so we set the default output projection to
153  //be the same as input proj.
155  }
156 
157  // init the projections (destination and source)
158  pj_free( mDestinationProjection );
159  mDestinationProjection = pj_init_plus( mDestCRS.toProj4().toUtf8() );
160  pj_free( mSourceProjection );
161  mSourceProjection = pj_init_plus( mSourceCRS.toProj4().toUtf8() );
162 
163 #ifdef COORDINATE_TRANSFORM_VERBOSE
164  QgsDebugMsg( "From proj : " + mSourceCRS.toProj4() );
165  QgsDebugMsg( "To proj : " + mDestCRS.toProj4() );
166 #endif
167 
168  mInitialisedFlag = true;
169  if ( !mDestinationProjection )
170  {
171  mInitialisedFlag = false;
172  }
173  if ( !mSourceProjection )
174  {
175  mInitialisedFlag = false;
176  }
177 #ifdef COORDINATE_TRANSFORM_VERBOSE
178  if ( mInitialisedFlag )
179  {
180  QgsDebugMsg( "------------------------------------------------------------" );
181  QgsDebugMsg( "The OGR Coordinate transformation for this layer was set to" );
182  QgsLogger::debug<QgsCoordinateReferenceSystem>( "Input", mSourceCRS, __FILE__, __FUNCTION__, __LINE__ );
183  QgsLogger::debug<QgsCoordinateReferenceSystem>( "Output", mDestCRS, __FILE__, __FUNCTION__, __LINE__ );
184  QgsDebugMsg( "------------------------------------------------------------" );
185  }
186  else
187  {
188  QgsDebugMsg( "------------------------------------------------------------" );
189  QgsDebugMsg( "The OGR Coordinate transformation FAILED TO INITIALISE!" );
190  QgsDebugMsg( "------------------------------------------------------------" );
191  }
192 #else
193  if ( !mInitialisedFlag )
194  {
195  QgsDebugMsg( "Coordinate transformation failed to initialize!" );
196  }
197 #endif
198 
199  //XXX todo overload == operator for QgsCoordinateReferenceSystem
200  //at the moment srs.parameters contains the whole proj def...soon it wont...
201  //if (mSourceCRS->toProj4() == mDestCRS->toProj4())
202  if ( mSourceCRS == mDestCRS )
203  {
204  // If the source and destination projection are the same, set the short
205  // circuit flag (no transform takes place)
206  mShortCircuit = true;
207  QgsDebugMsgLevel( "Source/Dest CRS equal, shortcircuit is set.", 3 );
208  }
209  else
210  {
211  // Transform must take place
212  mShortCircuit = false;
213  QgsDebugMsgLevel( "Source/Dest CRS UNequal, shortcircuit is NOt set.", 3 );
214  }
215 
216 }
217 
218 //
219 //
220 // TRANSFORMERS BELOW THIS POINT .........
221 //
222 //
223 //
224 
225 
227 {
229  return thePoint;
230  // transform x
231  double x = thePoint.x();
232  double y = thePoint.y();
233  double z = 0.0;
234  try
235  {
236  transformCoords( 1, &x, &y, &z, direction );
237  }
238  catch ( QgsCsException &cse )
239  {
240  // rethrow the exception
241  QgsDebugMsg( "rethrowing exception" );
242  throw cse;
243  }
244 
245  return QgsPoint( x, y );
246 }
247 
248 
249 QgsPoint QgsCoordinateTransform::transform( const double theX, const double theY = 0, TransformDirection direction ) const
250 {
251  try
252  {
253  return transform( QgsPoint( theX, theY ), direction );
254  }
255  catch ( QgsCsException &cse )
256  {
257  // rethrow the exception
258  QgsDebugMsg( "rethrowing exception" );
259  throw cse;
260  }
261 }
262 
264 {
266  return theRect;
267  // transform x
268  double x1 = theRect.xMinimum();
269  double y1 = theRect.yMinimum();
270  double x2 = theRect.xMaximum();
271  double y2 = theRect.yMaximum();
272 
273  // Number of points to reproject------+
274  // |
275  // V
276  try
277  {
278  double z = 0.0;
279  transformCoords( 1, &x1, &y1, &z, direction );
280  transformCoords( 1, &x2, &y2, &z, direction );
281  }
282  catch ( QgsCsException &cse )
283  {
284  // rethrow the exception
285  QgsDebugMsg( "rethrowing exception" );
286  throw cse;
287  }
288 
289 #ifdef COORDINATE_TRANSFORM_VERBOSE
290  QgsDebugMsg( "Rect projection..." );
291  QgsLogger::debug( "Xmin : ", theRect.xMinimum(), 1, __FILE__, __FUNCTION__, __LINE__ );
292  QgsLogger::debug( "-->", x1, 1, __FILE__, __FUNCTION__, __LINE__ );
293  QgsLogger::debug( "Ymin : ", theRect.yMinimum(), 1, __FILE__, __FUNCTION__, __LINE__ );
294  QgsLogger::debug( "-->", y1, 1, __FILE__, __FUNCTION__, __LINE__ );
295  QgsLogger::debug( "Xmax : ", theRect.xMaximum(), 1, __FILE__, __FUNCTION__, __LINE__ );
296  QgsLogger::debug( "-->", x2, 1, __FILE__, __FUNCTION__, __LINE__ );
297  QgsLogger::debug( "Ymax : ", theRect.yMaximum(), 1, __FILE__, __FUNCTION__, __LINE__ );
298  QgsLogger::debug( "-->", y2, 1, __FILE__, __FUNCTION__, __LINE__ );
299 #endif
300  return QgsRectangle( x1, y1, x2, y2 );
301 }
302 
303 void QgsCoordinateTransform::transformInPlace( double& x, double& y, double& z,
304  TransformDirection direction ) const
305 {
307  return;
308 #ifdef QGISDEBUG
309 // QgsDebugMsg(QString("Using transform in place %1 %2").arg(__FILE__).arg(__LINE__));
310 #endif
311  // transform x
312  try
313  {
314  transformCoords( 1, &x, &y, &z, direction );
315  }
316  catch ( QgsCsException &cse )
317  {
318  // rethrow the exception
319  QgsDebugMsg( "rethrowing exception" );
320  throw cse;
321  }
322 }
323 
324 void QgsCoordinateTransform::transformPolygon( QPolygonF& poly, TransformDirection direction ) const
325 {
327  {
328  return;
329  }
330 
331  //create x, y arrays
332  int nVertices = poly.size();
333 
334  QVector<double> x( nVertices );
335  QVector<double> y( nVertices );
336  QVector<double> z( nVertices );
337 
338  for ( int i = 0; i < nVertices; ++i )
339  {
340  const QPointF& pt = poly.at( i );
341  x[i] = pt.x();
342  y[i] = pt.y();
343  z[i] = 0;
344  }
345 
346  try
347  {
348  transformCoords( nVertices, x.data(), y.data(), z.data(), direction );
349  }
350  catch ( QgsCsException &cse )
351  {
352  // rethrow the exception
353  QgsDebugMsg( "rethrowing exception" );
354  throw cse;
355  }
356 
357  for ( int i = 0; i < nVertices; ++i )
358  {
359  QPointF& pt = poly[i];
360  pt.rx() = x[i];
361  pt.ry() = y[i];
362  }
363 }
364 
366  QVector<double>& x, QVector<double>& y, QVector<double>& z,
367  TransformDirection direction ) const
368 {
370  return;
371 
372  Q_ASSERT( x.size() == y.size() );
373 
374  // Apparently, if one has a std::vector, it is valid to use the
375  // address of the first element in the vector as a pointer to an
376  // array of the vectors data, and hence easily interface with code
377  // that wants C-style arrays.
378 
379  try
380  {
381  transformCoords( x.size(), &x[0], &y[0], &z[0], direction );
382  }
383  catch ( QgsCsException &cse )
384  {
385  // rethrow the exception
386  QgsDebugMsg( "rethrowing exception" );
387  throw cse;
388  }
389 }
390 
391 #ifdef QT_ARCH_ARM
392 void QgsCoordinateTransform::transformInPlace( qreal& x, qreal& y, double& z,
393  TransformDirection direction ) const
394 {
395  double xd = (double) x, yd = (double) y;
396  transformInPlace(xd, yd, z, direction);
397  x=xd;
398  y=yd;
399 }
400 #endif
401 
402 #ifdef ANDROID
403 void QgsCoordinateTransform::transformInPlace( float& x, float& y, float& z,
404  TransformDirection direction ) const
405 {
407  return;
408 #ifdef QGISDEBUG
409 // QgsDebugMsg(QString("Using transform in place %1 %2").arg(__FILE__).arg(__LINE__));
410 #endif
411  // transform x
412  try
413  {
414  double xd = x;
415  double yd = y;
416  double zd = z;
417  transformCoords( 1, &xd, &yd, &zd, direction );
418  x = xd;
419  y = yd;
420  z = zd;
421  }
422  catch ( QgsCsException &cse )
423  {
424  // rethrow the exception
425  QgsDebugMsg( "rethrowing exception" );
426  throw cse;
427  }
428 }
429 
431  QVector<float>& x, QVector<float>& y, QVector<float>& z,
432  TransformDirection direction ) const
433 {
435  return;
436 
437  Q_ASSERT( x.size() == y.size() );
438 
439  // Apparently, if one has a std::vector, it is valid to use the
440  // address of the first element in the vector as a pointer to an
441  // array of the vectors data, and hence easily interface with code
442  // that wants C-style arrays.
443 
444  try
445  {
446  //copy everything to double vectors since proj needs double
447  int vectorSize = x.size();
448  QVector<double> xd( x.size() );
449  QVector<double> yd( y.size() );
450  QVector<double> zd( z.size() );
451  for ( int i = 0; i < vectorSize; ++i )
452  {
453  xd[i] = x[i];
454  yd[i] = y[i];
455  zd[i] = z[i];
456  }
457  transformCoords( x.size(), &xd[0], &yd[0], &zd[0], direction );
458 
459  //copy back
460  for ( int i = 0; i < vectorSize; ++i )
461  {
462  x[i] = xd[i];
463  y[i] = yd[i];
464  z[i] = zd[i];
465  }
466  }
467  catch ( QgsCsException &cse )
468  {
469  // rethrow the exception
470  QgsDebugMsg( "rethrowing exception" );
471  throw cse;
472  }
473 }
474 #endif //ANDROID
475 
476 
478 {
479  // Calculate the bounding box of a QgsRectangle in the source CRS
480  // when projected to the destination CRS (or the inverse).
481  // This is done by looking at a number of points spread evenly
482  // across the rectangle
483 
485  return rect;
486 
487  if ( rect.isEmpty() )
488  {
489  QgsPoint p = transform( rect.xMinimum(), rect.yMinimum(), direction );
490  return QgsRectangle( p, p );
491  }
492 
493  static const int numP = 8;
494 
495  QgsRectangle bb_rect;
496  bb_rect.setMinimal();
497 
498  // We're interfacing with C-style vectors in the
499  // end, so let's do C-style vectors here too.
500 
501  double x[numP * numP];
502  double y[numP * numP];
503  double z[numP * numP];
504 
505  QgsDebugMsg( "Entering transformBoundingBox..." );
506 
507  // Populate the vectors
508 
509  double dx = rect.width() / ( double )( numP - 1 );
510  double dy = rect.height() / ( double )( numP - 1 );
511 
512  double pointY = rect.yMinimum();
513 
514  for ( int i = 0; i < numP ; i++ )
515  {
516 
517  // Start at right edge
518  double pointX = rect.xMinimum();
519 
520  for ( int j = 0; j < numP; j++ )
521  {
522  x[( i*numP ) + j] = pointX;
523  y[( i*numP ) + j] = pointY;
524  // and the height...
525  z[( i*numP ) + j] = 0.0;
526  // QgsDebugMsg(QString("BBox coord: (%1, %2)").arg(x[(i*numP) + j]).arg(y[(i*numP) + j]));
527  pointX += dx;
528  }
529  pointY += dy;
530  }
531 
532  // Do transformation. Any exception generated must
533  // be handled in above layers.
534  try
535  {
536  transformCoords( numP * numP, x, y, z, direction );
537  }
538  catch ( QgsCsException &cse )
539  {
540  // rethrow the exception
541  QgsDebugMsg( "rethrowing exception" );
542  throw cse;
543  }
544 
545  // Calculate the bounding box and use that for the extent
546 
547  for ( int i = 0; i < numP * numP; i++ )
548  {
549  if ( qIsFinite( x[i] ) && qIsFinite( y[i] ) )
550  bb_rect.combineExtentWith( x[i], y[i] );
551  }
552 
553  QgsDebugMsg( "Projected extent: " + bb_rect.toString() );
554 
555  if ( bb_rect.isEmpty() )
556  {
557  QgsDebugMsg( "Original extent: " + rect.toString() );
558  }
559 
560  return bb_rect;
561 }
562 
563 void QgsCoordinateTransform::transformCoords( const int& numPoints, double *x, double *y, double *z, TransformDirection direction ) const
564 {
565  // Refuse to transform the points if the srs's are invalid
566  if ( !mSourceCRS.isValid() )
567  {
568  QgsMessageLog::logMessage( tr( "The source spatial reference system (CRS) is not valid. "
569  "The coordinates can not be reprojected. The CRS is: %1" )
570  .arg( mSourceCRS.toProj4() ), tr( "CRS" ) );
571  return;
572  }
573  if ( !mDestCRS.isValid() )
574  {
575  QgsMessageLog::logMessage( tr( "The destination spatial reference system (CRS) is not valid. "
576  "The coordinates can not be reprojected. The CRS is: %1" ).arg( mDestCRS.toProj4() ), tr( "CRS" ) );
577  return;
578  }
579 
580 #ifdef COORDINATE_TRANSFORM_VERBOSE
581  double xorg = *x;
582  double yorg = *y;
583  QgsDebugMsg( QString( "[[[[[[ Number of points to transform: %1 ]]]]]]" ).arg( numPoints ) );
584 #endif
585 
586  // use proj4 to do the transform
587  QString dir;
588  // if the source/destination projection is lat/long, convert the points to radians
589  // prior to transforming
590  if (( pj_is_latlong( mDestinationProjection ) && ( direction == ReverseTransform ) )
591  || ( pj_is_latlong( mSourceProjection ) && ( direction == ForwardTransform ) ) )
592  {
593  for ( int i = 0; i < numPoints; ++i )
594  {
595  x[i] *= DEG_TO_RAD;
596  y[i] *= DEG_TO_RAD;
597  z[i] *= DEG_TO_RAD;
598  }
599 
600  }
601  int projResult;
602  if ( direction == ReverseTransform )
603  {
604  projResult = pj_transform( mDestinationProjection, mSourceProjection, numPoints, 0, x, y, z );
605  dir = tr( "inverse transform" );
606  }
607  else
608  {
609  Q_ASSERT( mSourceProjection != 0 );
610  Q_ASSERT( mDestinationProjection != 0 );
611  projResult = pj_transform( mSourceProjection, mDestinationProjection, numPoints, 0, x, y, z );
612  dir = tr( "forward transform" );
613  }
614 
615  if ( projResult != 0 )
616  {
617  //something bad happened....
618  QString points;
619 
620  for ( int i = 0; i < numPoints; ++i )
621  {
622  if ( direction == ForwardTransform )
623  {
624  points += QString( "(%1, %2)\n" ).arg( x[i], 0, 'f' ).arg( y[i], 0, 'f' );
625  }
626  else
627  {
628  points += QString( "(%1, %2)\n" ).arg( x[i] * RAD_TO_DEG, 0, 'f' ).arg( y[i] * RAD_TO_DEG, 0, 'f' );
629  }
630  }
631 
632  QString msg = tr( "%1 of\n"
633  "%2"
634  "PROJ.4: %3 +to %4\n"
635  "Error: %5" )
636  .arg( dir )
637  .arg( points )
638  .arg( mSourceCRS.toProj4() ).arg( mDestCRS.toProj4() )
639  .arg( QString::fromUtf8( pj_strerrno( projResult ) ) );
640 
641  QgsDebugMsg( "Projection failed emitting invalid transform signal: " + msg );
642 
643  emit invalidTransformInput();
644 
645  QgsDebugMsg( "throwing exception" );
646 
647  throw QgsCsException( msg );
648  }
649 
650  // if the result is lat/long, convert the results from radians back
651  // to degrees
652  if (( pj_is_latlong( mDestinationProjection ) && ( direction == ForwardTransform ) )
653  || ( pj_is_latlong( mSourceProjection ) && ( direction == ReverseTransform ) ) )
654  {
655  for ( int i = 0; i < numPoints; ++i )
656  {
657  x[i] *= RAD_TO_DEG;
658  y[i] *= RAD_TO_DEG;
659  z[i] *= RAD_TO_DEG;
660  }
661  }
662 #ifdef COORDINATE_TRANSFORM_VERBOSE
663  QgsDebugMsg( QString( "[[[[[[ Projected %1, %2 to %3, %4 ]]]]]]" )
664  .arg( xorg, 0, 'g', 15 ).arg( yorg, 0, 'g', 15 )
665  .arg( *x, 0, 'g', 15 ).arg( *y, 0, 'g', 15 ) );
666 #endif
667 }
668 
669 bool QgsCoordinateTransform::readXML( QDomNode & theNode )
670 {
671 
672  QgsDebugMsg( "Reading Coordinate Transform from xml ------------------------!" );
673 
674  QDomNode mySrcNode = theNode.namedItem( "sourcesrs" );
675  mSourceCRS.readXML( mySrcNode );
676 
677  QDomNode myDestNode = theNode.namedItem( "destinationsrs" );
678  mDestCRS.readXML( myDestNode );
679 
680  initialise();
681 
682  return true;
683 }
684 
685 bool QgsCoordinateTransform::writeXML( QDomNode & theNode, QDomDocument & theDoc )
686 {
687  QDomElement myNodeElement = theNode.toElement();
688  QDomElement myTransformElement = theDoc.createElement( "coordinatetransform" );
689 
690  QDomElement mySourceElement = theDoc.createElement( "sourcesrs" );
691  mSourceCRS.writeXML( mySourceElement, theDoc );
692  myTransformElement.appendChild( mySourceElement );
693 
694  QDomElement myDestElement = theDoc.createElement( "destinationsrs" );
695  mDestCRS.writeXML( myDestElement, theDoc );
696  myTransformElement.appendChild( myDestElement );
697 
698  myNodeElement.appendChild( myTransformElement );
699 
700  return true;
701 }
702 
703 const char *finder( const char *name )
704 {
705  QString proj;
706 #ifdef WIN32
707  proj = QApplication::applicationDirPath()
708  + "/share/proj/" + QString( name );
709 #else
710  Q_UNUSED( name );
711 #endif
712  return proj.toUtf8();
713 }
714 
716 {
717 #if 0
718  // Attention! It should be possible to set PROJ_LIB
719  // but it can happen that it was previously set by installer
720  // (version 0.7) and the old installation was deleted
721 
722  // Another problem: PROJ checks if pj_finder was set before
723  // PROJ_LIB environment variable. pj_finder is probably set in
724  // GRASS gproj library when plugin is loaded, consequently
725  // PROJ_LIB is ignored
726 
727  pj_set_finder( finder );
728 #endif
729 }
void transformCoords(const int &numPoint, double *x, double *y, double *z, TransformDirection direction=ForwardTransform) const
A rectangle specified with double values.
Definition: qgsrectangle.h:35
const QgsCoordinateReferenceSystem & crsByAuthId(const QString &authid)
Returns the CRS for authid, e.g.
bool isEmpty() const
test if rectangle is empty
void setMinimal()
Set a rectangle so that min corner is at max.
void invalidTransformInput() const
Signal when an invalid pj_transform() has occured.
void transformPolygon(QPolygonF &poly, TransformDirection direction=ForwardTransform) const
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:185
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
void setSourceCrs(const QgsCoordinateReferenceSystem &theCRS)
TransformDirection
Enum used to indicate the direction (forward or inverse) of the transform.
bool readXML(QDomNode &theNode)
bool createFromId(const long theId, CrsType theType=PostgisCrsId)
void initialise()
initialise is used to actually create the Transformer instance
double x() const
Definition: qgspoint.h:110
static void logMessage(QString message, QString tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
QgsCoordinateReferenceSystem mSourceCRS
void transformInPlace(double &x, double &y, double &z, TransformDirection direction=ForwardTransform) const
void combineExtentWith(QgsRectangle *rect)
expand the rectangle so that covers both the original rectangle and the given rectangle ...
bool writeXML(QDomNode &theNode, QDomDocument &theDoc)
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:190
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:175
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:37
QgsPoint transform(const QgsPoint p, TransformDirection direction=ForwardTransform) const
A class to represent a point geometry.
Definition: qgspoint.h:63
void setDestCRSID(long theCRSID)
QgsCoordinateReferenceSystem mDestCRS
static void debug(const QString &msg, int debuglevel=1, const char *file=NULL, const char *function=NULL, int line=-1)
Goes to qDebug.
Definition: qgslogger.cpp:33
void setDestCRS(const QgsCoordinateReferenceSystem &theCRS)
bool writeXML(QDomNode &theNode, QDomDocument &theDoc) const
QgsRectangle transformBoundingBox(const QgsRectangle theRect, TransformDirection direction=ForwardTransform) const
Class for storing a coordinate reference system (CRS)
double y() const
Definition: qgspoint.h:118
Custom exception class for Coordinate Reference System related exceptions.
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:195
QString toString(bool automaticPrecision=false) const
returns string representation of form xmin,ymin xmax,ymax
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:180
static QgsCRSCache * instance()
Definition: qgscrscache.cpp:84
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:200
const char * finder(const char *name)
QString toProj4() const
Get the Proj Proj4 string representation of this srs.
#define tr(sourceText)