29 #include <QDomElement>    30 #include <QApplication>    32 #include <QStringList>    44 QReadWriteLock QgsCoordinateTransform::sCacheLock;
    49   d = 
new QgsCoordinateTransformPrivate();
    56   if ( !d->checkValidity() )
    59   if ( !setFromCache( d->mSourceCRS, d->mDestCRS, d->mSourceDatumTransform, d->mDestinationDatumTransform ) )
    69   d = 
new QgsCoordinateTransformPrivate( source, destination, mContext );
    74   if ( !d->checkValidity() )
    77   if ( !setFromCache( d->mSourceCRS, d->mDestCRS, d->mSourceDatumTransform, d->mDestinationDatumTransform ) )
    87   d = 
new QgsCoordinateTransformPrivate( source, destination, mContext );
    93   if ( !d->checkValidity() )
    96   if ( !setFromCache( d->mSourceCRS, d->mDestCRS, d->mSourceDatumTransform, d->mDestinationDatumTransform ) )
   105   d = 
new QgsCoordinateTransformPrivate( source, destination, sourceDatumTransform, destinationDatumTransform );
   110   if ( !d->checkValidity() )
   113   if ( !setFromCache( d->mSourceCRS, d->mDestCRS, d->mSourceDatumTransform, d->mDestinationDatumTransform ) )
   121   : mContext( o.mContext )
   123   , mHasContext( o.mHasContext )
   133   mHasContext = o.mHasContext;
   135   mContext = o.mContext;
   145   if ( !d->checkValidity() )
   148   d->calculateTransforms( mContext );
   149   if ( !setFromCache( d->mSourceCRS, d->mDestCRS, d->mSourceDatumTransform, d->mDestinationDatumTransform ) )
   159   if ( !d->checkValidity() )
   162   d->calculateTransforms( mContext );
   163   if ( !setFromCache( d->mSourceCRS, d->mDestCRS, d->mSourceDatumTransform, d->mDestinationDatumTransform ) )
   177   if ( !d->checkValidity() )
   180   d->calculateTransforms( mContext );
   181   if ( !setFromCache( d->mSourceCRS, d->mDestCRS, d->mSourceDatumTransform, d->mDestinationDatumTransform ) )
   190   return d->mSourceCRS;
   200   if ( !d->mIsValid || d->mShortCircuit )
   204   double x = point.
x();
   205   double y = point.
y();
   238   if ( !d->mIsValid || d->mShortCircuit )
   262 #ifdef COORDINATE_TRANSFORM_VERBOSE   275   if ( !d->mIsValid || d->mShortCircuit )
   296   double xd = 
static_cast< double >( x ), yd = static_cast< double >( y );
   305   if ( !d->mIsValid || d->mShortCircuit )
   331   if ( !d->mIsValid || d->mShortCircuit )
   337   int nVertices = poly.size();
   339   QVector<double> x( nVertices );
   340   QVector<double> y( nVertices );
   341   QVector<double> z( nVertices );
   343   for ( 
int i = 0; i < nVertices; ++i )
   345     const QPointF &pt = poly.at( i );
   362   for ( 
int i = 0; i < nVertices; ++i )
   364     QPointF &pt = poly[i];
   371   QVector<double> &x, QVector<double> &y, QVector<double> &z,
   375   if ( !d->mIsValid || d->mShortCircuit )
   378   Q_ASSERT( x.size() == y.size() );
   399   QVector<float> &x, QVector<float> &y, QVector<float> &z,
   402   if ( !d->mIsValid || d->mShortCircuit )
   405   Q_ASSERT( x.size() == y.size() );
   415     int vectorSize = x.size();
   416     QVector<double> xd( x.size() );
   417     QVector<double> yd( y.size() );
   418     QVector<double> zd( z.size() );
   419     for ( 
int i = 0; i < vectorSize; ++i )
   428     for ( 
int i = 0; i < vectorSize; ++i )
   450   if ( !d->mIsValid || d->mShortCircuit )
   463   const int nPoints = 1000;
   464   double d = std::sqrt( ( rect.
width() * rect.
height() ) / std::pow( std::sqrt( static_cast< double >( nPoints ) ) - 1, 2.0 ) );
   465   int nXPoints = 
static_cast< int >( std::ceil( rect.
width() / d ) ) + 1;
   466   int nYPoints = 
static_cast< int >( std::ceil( rect.
height() / d ) ) + 1;
   474   QVector<double> x( nXPoints * nYPoints );
   475   QVector<double> y( nXPoints * nYPoints );
   476   QVector<double> z( nXPoints * nYPoints );
   482   double dx = rect.
width()  / 
static_cast< double >( nXPoints - 1 );
   483   double dy = rect.
height() / 
static_cast< double >( nYPoints - 1 );
   487   for ( 
int i = 0; i < nYPoints ; i++ )
   493     for ( 
int j = 0; j < nXPoints; j++ )
   495       x[( i * nXPoints ) + j] = pointX;
   496       y[( i * nXPoints ) + j] = pointY;
   498       z[( i * nXPoints ) + j] = 0.0;
   509     transformCoords( nXPoints * nYPoints, x.data(), y.data(), z.data(), direction );
   520   for ( 
int i = 0; i < nXPoints * nYPoints; i++ )
   522     if ( !std::isfinite( x[i] ) || !std::isfinite( y[i] ) )
   527     if ( handle180Crossover )
   541     throw QgsCsException( QObject::tr( 
"Could not transform bounding box to target CRS" ) );
   544   if ( handle180Crossover )
   565   if ( !d->mIsValid || d->mShortCircuit )
   568   if ( !d->mSourceCRS.isValid() )
   571                                             "The coordinates can not be reprojected. The CRS is: %1" )
   572                                .arg( d->mSourceCRS.toProj4() ), QObject::tr( 
"CRS" ) );
   575   if ( !d->mDestCRS.isValid() )
   578                                             "The coordinates can not be reprojected. The CRS is: %1" ).arg( d->mDestCRS.toProj4() ), QObject::tr( 
"CRS" ) );
   582 #ifdef COORDINATE_TRANSFORM_VERBOSE   585   QgsDebugMsg( QString( 
"[[[[[[ Number of points to transform: %1 ]]]]]]" ).arg( numPoints ) );
   590     qWarning( 
"No QgsCoordinateTransformContext context set for transform" );
   597   QPair<projPJ, projPJ> projData = d->threadLocalProjData();
   598   projPJ sourceProj = projData.first;
   599   projPJ destProj = projData.second;
   604     for ( 
int i = 0; i < numPoints; ++i )
   614     projResult = pj_transform( destProj, sourceProj, numPoints, 0, x, y, z );
   618     Q_ASSERT( sourceProj );
   619     Q_ASSERT( destProj );
   620     projResult = pj_transform( sourceProj, destProj, numPoints, 0, x, y, z );
   623   if ( projResult != 0 )
   628     for ( 
int i = 0; i < numPoints; ++i )
   632         points += QStringLiteral( 
"(%1, %2)\n" ).arg( x[i], 0, 
'f' ).arg( y[i], 0, 
'f' );
   636         points += QStringLiteral( 
"(%1, %2)\n" ).arg( x[i] * RAD_TO_DEG, 0, 
'f' ).arg( y[i] * RAD_TO_DEG, 0, 
'f' );
   640     QString dir = ( direction == 
ForwardTransform ) ? QObject::tr( 
"forward transform" ) : QObject::tr( 
"inverse transform" );
   642     char *srcdef = pj_get_def( sourceProj, 0 );
   643     char *dstdef = pj_get_def( destProj, 0 );
   645     QString msg = QObject::tr( 
"%1 of\n"   652                         QString::fromUtf8( pj_strerrno( projResult ) ) );
   657     QgsDebugMsg( 
"Projection failed emitting invalid transform signal: " + msg );
   668     for ( 
int i = 0; i < numPoints; ++i )
   674 #ifdef COORDINATE_TRANSFORM_VERBOSE   675   QgsDebugMsg( QString( 
"[[[[[[ Projected %1, %2 to %3, %4 ]]]]]]" )
   676                .arg( xorg, 0, 
'g', 15 ).arg( yorg, 0, 
'g', 15 )
   677                .arg( *x, 0, 
'g', 15 ).arg( *y, 0, 
'g', 15 ) );
   688   return !d->mIsValid || d->mShortCircuit;
   695   proj = QApplication::applicationDirPath()
   696          + 
"/share/proj/" + QString( name );
   700   return proj.toUtf8();
   708   sCacheLock.lockForRead();
   709   const QList< QgsCoordinateTransform > values = sTransforms.values( qMakePair( src.
authid(), dest.
authid() ) );
   710   for ( 
auto valIt = values.constBegin(); valIt != values.constEnd(); ++valIt )
   712     if ( ( *valIt ).sourceDatumTransformId() == srcDatumTransform &&
   713          ( *valIt ).destinationDatumTransformId() == destDatumTransform )
   718       bool hasContext = mHasContext;
   725       mHasContext = hasContext;
   735 void QgsCoordinateTransform::addToCache()
   737   if ( !d->mSourceCRS.isValid() || !d->mDestCRS.isValid() )
   740   sCacheLock.lockForWrite();
   741   sTransforms.insertMulti( qMakePair( d->mSourceCRS.authid(), d->mDestCRS.authid() ), *
this );
   747   return d->mSourceDatumTransform;
   753   d->mSourceDatumTransform = dt;
   758   return d->mDestinationDatumTransform;
   764   d->mDestinationDatumTransform = dt;
   769   sCacheLock.lockForWrite();
 
A rectangle specified with double values. 
 
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min. 
 
void setXMaximum(double x)
Set the maximum x value. 
 
A class to represent a 2D point. 
 
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning)
add a message to the instance (and create it if necessary) 
 
QgsCoordinateTransformContext transformContext() const
Returns a copy of the project's coordinate transform context, which stores various information regard...
 
#define QgsDebugMsgLevel(str, level)
 
bool isEmpty() const
Returns true if the rectangle is empty. 
 
double width() const
Returns the width of the rectangle. 
 
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
 
Reads and writes project states. 
 
Contains information about the context in which a coordinate transform is executed. 
 
double yMinimum() const
Returns the y minimum value (bottom side of rectangle). 
 
double xMaximum() const
Returns the x maximum value (right side of rectangle). 
 
void combineExtentWith(const QgsRectangle &rect)
Expand the rectangle so that covers both the original rectangle and the given rectangle. 
 
This class represents a coordinate reference system (CRS). 
 
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()). 
 
double xMinimum() const
Returns the x minimum value (left side of rectangle). 
 
double yMaximum() const
Returns the y maximum value (top side of rectangle). 
 
Custom exception class for Coordinate Reference System related exceptions. 
 
QString authid() const
Returns the authority identifier for the CRS. 
 
void setXMinimum(double x)
Set the minimum x value. 
 
double height() const
Returns the height of the rectangle. 
 
bool isValid() const
Returns whether this CRS is correctly initialized and usable.