37   projector->mSrcCRS = mSrcCRS;
    38   projector->mDestCRS = mDestCRS;
    39   projector->mSrcDatumTransform = mSrcDatumTransform;
    40   projector->mDestDatumTransform = mDestDatumTransform;
    41   projector->mPrecision = mPrecision;
    67   mSrcDatumTransform = srcDatumTransform;
    68   mDestDatumTransform = destDatumTransform;
    73   : mApproximate( 
false )
    74   , mInverseCt( inverseCt )
    75   , mDestExtent( extent )
    84   , mDestRowsPerMatrixRow( 0.0 )
    85   , mDestColsPerMatrixCol( 0.0 )
    89   , mSqrTolerance( 0.0 )
   107       if ( mExtent.isEmpty() )
   109         mExtent = provider->
extent();
   114   mDestXRes = mDestExtent.
width() / ( mDestCols );
   115   mDestYRes = mDestExtent.height() / ( mDestRows );
   121   double myDestRes = mDestXRes < mDestYRes ? mDestXRes : mDestYRes;
   122   mSqrTolerance = myDestRes * myDestRes;
   130     mApproximate = 
false;
   135   mCPCols = mCPRows = 3;
   136   for ( 
int i = 0; i < mCPRows; i++ )
   138     QList<QgsPointXY> myRow;
   142     mCPMatrix.insert( i, myRow );
   144     QList<bool> myLegalRow;
   145     myLegalRow.append( 
bool( 
false ) );
   146     myLegalRow.append( 
bool( 
false ) );
   147     myLegalRow.append( 
bool( 
false ) );
   148     mCPLegalMatrix.insert( i, myLegalRow );
   150   for ( 
int i = 0; i < mCPRows; i++ )
   152     calcRow( i, inverseCt );
   157     bool myColsOK = checkCols( inverseCt );
   160       insertRows( inverseCt );
   162     bool myRowsOK = checkRows( inverseCt );
   165       insertCols( inverseCt );
   167     if ( myColsOK && myRowsOK )
   174     if ( mCPRows * mCPCols > 0.25 * mDestRows * mDestCols )
   178       mApproximate = 
false;
   182   QgsDebugMsgLevel( QString( 
"CPMatrix size: mCPRows = %1 mCPCols = %2" ).arg( mCPRows ).arg( mCPCols ), 4 );
   183   mDestRowsPerMatrixRow = 
static_cast< float >( mDestRows ) / ( mCPRows - 1 );
   184   mDestColsPerMatrixCol = 
static_cast< float >( mDestCols ) / ( mCPCols - 1 );
   192   calcHelper( 0, pHelperTop );
   193   calcHelper( 1, pHelperBottom );
   199   mSrcYRes = mSrcExtent.height() / mSrcRows;
   200   mSrcXRes = mSrcExtent.width() / mSrcCols;
   203 ProjectorData::~ProjectorData()
   206   delete[] pHelperBottom;
   210 void ProjectorData::calcSrcExtent()
   221   mSrcExtent = 
QgsRectangle( myPoint.
x(), myPoint.
y(), myPoint.
x(), myPoint.
y() );
   222   for ( 
int i = 0; i < mCPRows; i++ )
   224     for ( 
int j = 0; j < mCPCols ; j++ )
   226       myPoint = mCPMatrix[i][j];
   227       if ( mCPLegalMatrix[i][j] )
   229         mSrcExtent.combineExtentWith( myPoint.
x(), myPoint.
y() );
   236   mSrcExtent = mSrcExtent.intersect( mExtent );
   247   if ( !mExtent.isEmpty() )
   249     if ( mMaxSrcXRes > 0 )
   252       double col = std::floor( ( mSrcExtent.xMinimum() - mExtent.xMinimum() ) / mMaxSrcXRes );
   253       double x = mExtent.xMinimum() + col * mMaxSrcXRes;
   254       mSrcExtent.setXMinimum( x );
   256       col = std::ceil( ( mSrcExtent.xMaximum() - mExtent.xMinimum() ) / mMaxSrcXRes );
   257       x = mExtent.xMinimum() + col * mMaxSrcXRes;
   258       mSrcExtent.setXMaximum( x );
   260     if ( mMaxSrcYRes > 0 )
   262       double row = std::floor( ( mExtent.yMaximum() - mSrcExtent.yMaximum() ) / mMaxSrcYRes );
   263       double y = mExtent.yMaximum() - row * mMaxSrcYRes;
   264       mSrcExtent.setYMaximum( y );
   266       row = std::ceil( ( mExtent.yMaximum() - mSrcExtent.yMinimum() ) / mMaxSrcYRes );
   267       y = mExtent.yMaximum() - row * mMaxSrcYRes;
   268       mSrcExtent.setYMinimum( y );
   274 QString ProjectorData::cpToString()
   277   for ( 
int i = 0; i < mCPRows; i++ )
   281     for ( 
int j = 0; j < mCPCols; j++ )
   284         myString += QLatin1String( 
"  " );
   286       if ( mCPLegalMatrix[i][j] )
   292         myString += QLatin1String( 
"(-,-)" );
   299 void ProjectorData::calcSrcRowsCols()
   307   double myMinSize = std::numeric_limits<double>::max();
   312     double myDestColsPerMatrixCell = 
static_cast< double >( mDestCols ) / mCPCols;
   313     double myDestRowsPerMatrixCell = 
static_cast< double >( mDestRows ) / mCPRows;
   314     QgsDebugMsgLevel( QString( 
"myDestColsPerMatrixCell = %1 myDestRowsPerMatrixCell = %2" ).arg( myDestColsPerMatrixCell ).arg( myDestRowsPerMatrixCell ), 4 );
   315     for ( 
int i = 0; i < mCPRows - 1; i++ )
   317       for ( 
int j = 0; j < mCPCols - 1; j++ )
   322         if ( mCPLegalMatrix[i][j] && mCPLegalMatrix[i][j + 1] && mCPLegalMatrix[i + 1][j] )
   324           double mySize = std::sqrt( myPointA.
sqrDist( myPointB ) ) / myDestColsPerMatrixCell;
   325           if ( mySize < myMinSize )
   328           mySize = std::sqrt( myPointA.
sqrDist( myPointC ) ) / myDestRowsPerMatrixCell;
   329           if ( mySize < myMinSize )
   340     int srcXSize, srcYSize;
   343       double srcXRes = srcExtent.
width() / srcXSize;
   344       double srcYRes = srcExtent.
height() / srcYSize;
   345       myMinSize = std::min( srcXRes, srcYRes );
   358   QgsDebugMsgLevel( QString( 
"mMaxSrcXRes = %1 mMaxSrcYRes = %2" ).arg( mMaxSrcXRes ).arg( mMaxSrcYRes ), 4 );
   360   double myMinXSize = mMaxSrcXRes > myMinSize ? mMaxSrcXRes : myMinSize;
   361   double myMinYSize = mMaxSrcYRes > myMinSize ? mMaxSrcYRes : myMinSize;
   362   QgsDebugMsgLevel( QString( 
"myMinXSize = %1 myMinYSize = %2" ).arg( myMinXSize ).arg( myMinYSize ), 4 );
   363   QgsDebugMsgLevel( QString( 
"mSrcExtent.width = %1 mSrcExtent.height = %2" ).arg( mSrcExtent.width() ).arg( mSrcExtent.height() ), 4 );
   366   mSrcRows = 
static_cast< int >( std::round( mSrcExtent.height() / myMinYSize ) );
   367   mSrcCols = 
static_cast< int >( std::round( mSrcExtent.width() / myMinXSize ) );
   369   QgsDebugMsgLevel( QString( 
"mSrcRows = %1 mSrcCols = %2" ).arg( mSrcRows ).arg( mSrcCols ), 4 );
   373 inline void ProjectorData::destPointOnCPMatrix( 
int row, 
int col, 
double *theX, 
double *theY )
   375   *theX = mDestExtent.xMinimum() + col * mDestExtent.width() / ( mCPCols - 1 );
   376   *theY = mDestExtent.yMaximum() - row * mDestExtent.height() / ( mCPRows - 1 );
   379 inline int ProjectorData::matrixRow( 
int destRow )
   381   return static_cast< int >( std::floor( ( destRow + 0.5 ) / mDestRowsPerMatrixRow ) );
   383 inline int ProjectorData::matrixCol( 
int destCol )
   385   return static_cast< int >( std::floor( ( destCol + 0.5 ) / mDestColsPerMatrixCol ) );
   388 void ProjectorData::calcHelper( 
int matrixRow, 
QgsPointXY *points )
   391   for ( 
int myDestCol = 0; myDestCol < mDestCols; myDestCol++ )
   393     double myDestX = mDestExtent.xMinimum() + ( myDestCol + 0.5 ) * mDestXRes;
   395     int myMatrixCol = matrixCol( myDestCol );
   397     double myDestXMin, myDestYMin, myDestXMax, myDestYMax;
   399     destPointOnCPMatrix( matrixRow, myMatrixCol, &myDestXMin, &myDestYMin );
   400     destPointOnCPMatrix( matrixRow, myMatrixCol + 1, &myDestXMax, &myDestYMax );
   402     double xfrac = ( myDestX - myDestXMin ) / ( myDestXMax - myDestXMin );
   404     QgsPointXY &mySrcPoint0 = mCPMatrix[matrixRow][myMatrixCol];
   405     QgsPointXY &mySrcPoint1 = mCPMatrix[matrixRow][myMatrixCol + 1];
   406     double s = mySrcPoint0.
x() + ( mySrcPoint1.
x() - mySrcPoint0.
x() ) * xfrac;
   407     double t = mySrcPoint0.
y() + ( mySrcPoint1.
y() - mySrcPoint0.
y() ) * xfrac;
   409     points[myDestCol].
setX( s );
   410     points[myDestCol].
setY( t );
   414 void ProjectorData::nextHelper()
   419   pHelperTop = pHelperBottom;
   421   calcHelper( mHelperTopRow + 2, pHelperBottom );
   425 bool ProjectorData::srcRowCol( 
int destRow, 
int destCol, 
int *srcRow, 
int *srcCol )
   429     return approximateSrcRowCol( destRow, destCol, srcRow, srcCol );
   433     return preciseSrcRowCol( destRow, destCol, srcRow, srcCol );
   437 bool ProjectorData::preciseSrcRowCol( 
int destRow, 
int destCol, 
int *srcRow, 
int *srcCol )
   441   QgsDebugMsgLevel( QString( 
"theDestRow = %1 mDestExtent.yMaximum() = %2 mDestYRes = %3" ).arg( destRow ).arg( mDestExtent.yMaximum() ).arg( mDestYRes ), 5 );
   445   double x = mDestExtent.xMinimum() + ( destCol + 0.5 ) * mDestXRes;
   446   double y = mDestExtent.yMaximum() - ( destRow + 0.5 ) * mDestYRes;
   453   if ( mInverseCt.isValid() )
   455     mInverseCt.transformInPlace( x, y, z );
   462   if ( !mExtent.contains( 
QgsPointXY( x, y ) ) )
   467   *srcRow = 
static_cast< int >( std::floor( ( mSrcExtent.yMaximum() - y ) / mSrcYRes ) );
   468   *srcCol = 
static_cast< int >( std::floor( ( x - mSrcExtent.xMinimum() ) / mSrcXRes ) );
   470   QgsDebugMsgLevel( QString( 
"mSrcExtent.yMinimum() = %1 mSrcExtent.yMaximum() = %2 mSrcYRes = %3" ).arg( mSrcExtent.yMinimum() ).arg( mSrcExtent.yMaximum() ).arg( mSrcYRes ), 5 );
   471   QgsDebugMsgLevel( QString( 
"theSrcRow = %1 srcCol = %2" ).arg( *srcRow ).arg( *srcCol ), 5 );
   478   if ( *srcRow >= mSrcRows ) 
return false;
   479   if ( *srcRow < 0 ) 
return false;
   480   if ( *srcCol >= mSrcCols ) 
return false;
   481   if ( *srcCol < 0 ) 
return false;
   486 bool ProjectorData::approximateSrcRowCol( 
int destRow, 
int destCol, 
int *srcRow, 
int *srcCol )
   488   int myMatrixRow = matrixRow( destRow );
   489   int myMatrixCol = matrixCol( destCol );
   491   if ( myMatrixRow > mHelperTopRow )
   497   double myDestY = mDestExtent.yMaximum() - ( destRow + 0.5 ) * mDestYRes;
   501   double myDestXMin, myDestYMin, myDestXMax, myDestYMax;
   503   destPointOnCPMatrix( myMatrixRow + 1, myMatrixCol, &myDestXMin, &myDestYMin );
   504   destPointOnCPMatrix( myMatrixRow, myMatrixCol + 1, &myDestXMax, &myDestYMax );
   506   double yfrac = ( myDestY - myDestYMin ) / ( myDestYMax - myDestYMin );
   515   double tx = myTop.
x();
   516   double ty = myTop.
y();
   517   double bx = myBot.
x();
   518   double by = myBot.
y();
   519   double mySrcX = bx + ( tx - bx ) * yfrac;
   520   double mySrcY = by + ( ty - by ) * yfrac;
   522   if ( !mExtent.contains( 
QgsPointXY( mySrcX, mySrcY ) ) )
   529   *srcRow = 
static_cast< int >( std::floor( ( mSrcExtent.yMaximum() - mySrcY ) / mSrcYRes ) );
   530   *srcCol = 
static_cast< int >( std::floor( ( mySrcX - mSrcExtent.xMinimum() ) / mSrcXRes ) );
   535   if ( *srcRow >= mSrcRows ) 
return false;
   536   if ( *srcRow < 0 ) 
return false;
   537   if ( *srcCol >= mSrcCols ) 
return false;
   538   if ( *srcCol < 0 ) 
return false;
   545   for ( 
int r = 0; r < mCPRows - 1; r++ )
   547     QList<QgsPointXY> myRow;
   548     QList<bool> myLegalRow;
   549     myRow.reserve( mCPCols );
   550     myLegalRow.reserve( mCPCols );
   551     for ( 
int c = 0; 
c < mCPCols; ++
c )
   554       myLegalRow.append( 
false );
   557     mCPMatrix.insert( 1 + r * 2, myRow );
   558     mCPLegalMatrix.insert( 1 + r * 2, myLegalRow );
   560   mCPRows += mCPRows - 1;
   561   for ( 
int r = 1; r < mCPRows - 1; r += 2 )
   569   for ( 
int r = 0; r < mCPRows; r++ )
   571     for ( 
int c = 0; 
c < mCPCols - 1; 
c++ )
   574       mCPLegalMatrix[r].insert( 1 + 
c * 2, 
false );
   577   mCPCols += mCPCols - 1;
   578   for ( 
int c = 1; 
c < mCPCols - 1; 
c += 2 )
   587   double myDestX, myDestY;
   588   destPointOnCPMatrix( row, col, &myDestX, &myDestY );
   594       mCPMatrix[row][col] = ct.
transform( myDestPoint );
   595       mCPLegalMatrix[row][col] = 
true;
   599       mCPLegalMatrix[row][col] = 
false;
   606     mCPLegalMatrix[row][col] = 
false;
   613   for ( 
int i = 0; i < mCPCols; i++ )
   615     calcCP( row, i, ct );
   624   for ( 
int i = 0; i < mCPRows; i++ )
   626     calcCP( i, col, ct );
   639   for ( 
int c = 0; 
c < mCPCols; 
c++ )
   641     for ( 
int r = 1; r < mCPRows - 1; r += 2 )
   643       double myDestX, myDestY;
   644       destPointOnCPMatrix( r, 
c, &myDestX, &myDestY );
   651       QgsPointXY mySrcApprox( ( mySrcPoint1.
x() + mySrcPoint3.
x() ) / 2, ( mySrcPoint1.
y() + mySrcPoint3.
y() ) / 2 );
   652       if ( !mCPLegalMatrix[r - 1][
c] || !mCPLegalMatrix[r][
c] || !mCPLegalMatrix[r + 1][
c] )
   660         double mySqrDist = myDestApprox.
sqrDist( myDestPoint );
   661         if ( mySqrDist > mSqrTolerance )
   684   for ( 
int r = 0; r < mCPRows; r++ )
   686     for ( 
int c = 1; 
c < mCPCols - 1; 
c += 2 )
   688       double myDestX, myDestY;
   689       destPointOnCPMatrix( r, 
c, &myDestX, &myDestY );
   696       QgsPointXY mySrcApprox( ( mySrcPoint1.
x() + mySrcPoint3.
x() ) / 2, ( mySrcPoint1.
y() + mySrcPoint3.
y() ) / 2 );
   697       if ( !mCPLegalMatrix[r][
c - 1] || !mCPLegalMatrix[r][
c] || !mCPLegalMatrix[r][
c + 1] )
   705         double mySqrDist = myDestApprox.
sqrDist( myDestPoint );
   706         if ( mySqrDist > mSqrTolerance )
   730       return tr( 
"Approximate" );
   732       return tr( 
"Exact" );
   734   return QStringLiteral( 
"Unknown" );
   740   QgsDebugMsgLevel( QString( 
"width = %1 height = %2" ).arg( width ).arg( height ), 4 );
   750   if ( ! mSrcCRS.
isValid() || ! mDestCRS.
isValid() || mSrcCRS == mDestCRS )
   753     return mInput->
block( bandNo, extent, width, height, feedback );
   758   ProjectorData pd( extent, width, height, 
mInput, inverseCt, mPrecision );
   760   QgsDebugMsgLevel( QString( 
"srcExtent:\n%1" ).arg( pd.srcExtent().toString() ), 4 );
   761   QgsDebugMsgLevel( QString( 
"srcCols = %1 srcRows = %2" ).arg( pd.srcCols() ).arg( pd.srcRows() ), 4 );
   764   if ( pd.srcRows() <= 0 || pd.srcCols() <= 0 )
   770   std::unique_ptr< QgsRasterBlock > inputBlock( 
mInput->
block( bandNo, pd.srcExtent(), pd.srcCols(), pd.srcRows(), feedback ) );
   771   if ( !inputBlock || inputBlock->isEmpty() )
   779   std::unique_ptr< QgsRasterBlock > outputBlock( 
new QgsRasterBlock( inputBlock->dataType(), width, height ) );
   780   if ( inputBlock->hasNoDataValue() )
   782     outputBlock->setNoDataValue( inputBlock->noDataValue() );
   784   if ( !outputBlock->isValid() )
   787     return outputBlock.release();
   791   outputBlock->setIsNoData();
   805   outputBlock->setIsNoData();
   808   for ( 
int i = 0; i < height; ++i )
   812     for ( 
int j = 0; j < width; ++j )
   814       bool inside = pd.srcRowCol( i, j, &srcRow, &srcCol );
   815       if ( !inside ) 
continue; 
   817       qgssize srcIndex = 
static_cast< qgssize >( srcRow ) * pd.srcCols() + srcCol;
   820       if ( doNoData && inputBlock->isNoData( srcRow, srcCol ) )
   822         outputBlock->setIsNoData( i, j );
   827       char *srcBits = inputBlock->bits( srcIndex );
   828       char *destBits = outputBlock->bits( destIndex );
   839       memcpy( destBits, srcBits, pixelSize );
   840       outputBlock->setIsData( i, j );
   844   return outputBlock.release();
   848     QgsRectangle &destExtent, 
int &destXSize, 
int &destYSize )
   850   if ( srcExtent.
isEmpty() || srcXSize <= 0 || srcYSize <= 0 )
   856   return extentSize( ct, srcExtent, srcXSize, srcYSize, destExtent, destXSize, destYSize );
   860                                      const QgsRectangle &srcExtent, 
int srcXSize, 
int srcYSize,
   861                                      QgsRectangle &destExtent, 
int &destXSize, 
int &destYSize )
   863   if ( srcExtent.
isEmpty() || srcXSize <= 0 || srcYSize <= 0 )
   872   double srcXStep = srcExtent.
width() / 3;
   873   double srcYStep = srcExtent.
height() / 3;
   874   double srcXRes = srcExtent.
width() / srcXSize;
   875   double srcYRes = srcExtent.
height() / srcYSize;
   876   double destXRes = std::numeric_limits<double>::max();
   877   double destYRes = std::numeric_limits<double>::max();
   879   for ( 
int i = 0; i < 3; i++ )
   881     double x = srcExtent.
xMinimum() + i * srcXStep;
   882     for ( 
int j = 0; j < 3; j++ )
   884       double y = srcExtent.
yMinimum() + j * srcYStep;
   885       QgsRectangle srcRectangle( x - srcXRes / 2, y - srcYRes / 2, x + srcXRes / 2, y + srcYRes / 2 );
   887       if ( destRectangle.
width() > 0 )
   889         destXRes = std::min( destXRes, destRectangle.
width() );
   891       if ( destRectangle.
height() > 0 )
   893         destYRes = std::min( destYRes, destRectangle.
height() );
   897   destXSize = std::max( 1, static_cast< int >( destExtent.
width() / destYRes ) );
   898   destYSize = std::max( 1, static_cast< int >( destExtent.
height() / destYRes ) );
 virtual int bandCount() const =0
Gets number of bands. 
 
A rectangle specified with double values. 
 
Precision precision() const
 
Approximate (default), fast but possibly inaccurate. 
 
virtual QgsRectangle extent() const
Gets the extent of the interface. 
 
A class to represent a 2D point. 
 
static bool typeIsNumeric(Qgis::DataType type)
Returns true if data type is numeric. 
 
virtual QgsRasterInterface * input() const
Current input. 
 
DataType
Raster data types. 
 
virtual int ySize() const
 
QString toString(int precision=-1) const
Returns a string representation of the point (x, y) with a preset precision. 
 
virtual Qgis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number. 
 
void setCrs(const QgsCoordinateReferenceSystem &srcCRS, const QgsCoordinateReferenceSystem &destCRS, int srcDatumTransform=-1, int destDatumTransform=-1)
Sets the source and destination CRS. 
 
double sqrDist(double x, double y) const
Returns the squared distance between this point a specified x, y coordinate. 
 
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
 
Qgis::DataType dataType(int bandNo) const override
Returns data type for the band specified by number. 
 
#define QgsDebugMsgLevel(str, level)
 
bool isEmpty() const
Returns true if the rectangle is empty. 
 
virtual QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr)=0
Read block of data using given extent and size. 
 
virtual int capabilities() const
Returns a bitmask containing the supported capabilities. 
 
QgsRectangle extent() const override=0
Returns the extent of the layer. 
 
double width() const
Returns the width of the rectangle. 
 
void setY(double y)
Sets the y value of the point. 
 
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
 
Unknown or unspecified type. 
 
static int typeSize(int dataType)
 
Base class for processing filters like renderers, reprojector, resampler etc. 
 
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size. 
 
void setX(double x)
Sets the x value of the point. 
 
unsigned long long qgssize
Qgssize is used instead of size_t, because size_t is stdlib type, unknown by SIP, and it would be har...
 
double yMinimum() const
Returns the y minimum value (bottom side of rectangle). 
 
static bool extentSize(const QgsCoordinateTransform &ct, const QgsRectangle &srcExtent, int srcXSize, int srcYSize, QgsRectangle &destExtent, int &destXSize, int &destYSize)
Calculate destination extent and size from source extent and size. 
 
QgsRasterProjector implements approximate projection support for it calculates grid of points in sour...
 
QgsRasterProjector * clone() const override
Clone itself, create deep copy. 
 
Precision
Precision defines if each pixel is reprojected or approximate reprojection based on an approximation ...
 
bool isCanceled() const
Tells whether the operation has been canceled already. 
 
This class represents a coordinate reference system (CRS). 
 
double xMinimum() const
Returns the x minimum value (left side of rectangle). 
 
Custom exception class for Coordinate Reference System related exceptions. 
 
QgsRasterInterface * mInput
 
Feedback object tailored for raster block reading. 
 
virtual int xSize() const
Gets raster size. 
 
bool destExtentSize(const QgsRectangle &srcExtent, int srcXSize, int srcYSize, QgsRectangle &destExtent, int &destXSize, int &destYSize)
Calculate destination extent and size from source extent and size. 
 
static QString precisionLabel(Precision precision)
 
virtual const QgsRasterInterface * sourceInput() const
Gets source / raw input, the first in pipe, usually provider. 
 
double height() const
Returns the height of the rectangle. 
 
int bandCount() const override
Gets number of bands. 
 
Base class for raster data providers. 
 
bool isValid() const
Returns whether this CRS is correctly initialized and usable.