26#include "moc_qgsrasterprojector.cpp"
41 projector->mSrcCRS = mSrcCRS;
42 projector->mDestCRS = mDestCRS;
43 projector->mTransformContext = mTransformContext;
46 projector->mSrcDatumTransform = mSrcDatumTransform;
47 projector->mDestDatumTransform = mDestDatumTransform;
50 projector->mPrecision = mPrecision;
73 int srcDatumTransform,
74 int destDatumTransform )
79 mSrcDatumTransform = srcDatumTransform;
80 mDestDatumTransform = destDatumTransform;
88 mTransformContext = transformContext;
90 mSrcDatumTransform = -1;
91 mDestDatumTransform = -1;
97 : mInverseCt( inverseCt )
98 , mDestExtent( extent )
107 QgsRasterDataProvider *provider =
dynamic_cast<QgsRasterDataProvider *
>(
input->sourceInput() );
121 if ( mExtent.isEmpty() )
123 mExtent = provider->
extent();
128 mDestXRes = mDestExtent.width() / ( mDestCols );
129 mDestYRes = mDestExtent.height() / ( mDestRows );
135 const double myDestRes = mDestXRes < mDestYRes ? mDestXRes : mDestYRes;
136 mSqrTolerance = myDestRes * myDestRes;
144 mApproximate =
false;
149 mCPCols = mCPRows = 3;
157 if ( std::fabs( -mDestExtent.yMinimum() - mDestExtent.yMaximum() ) / height < 0.5 * mDestYRes )
160 for (
int i = 0; i < mCPRows; i++ )
162 QList<QgsPointXY> myRow;
163 myRow.append( QgsPointXY() );
164 myRow.append( QgsPointXY() );
165 myRow.append( QgsPointXY() );
166 mCPMatrix.insert( i, myRow );
168 QList<bool> myLegalRow;
169 myLegalRow.append(
bool(
false ) );
170 myLegalRow.append(
bool(
false ) );
171 myLegalRow.append(
bool(
false ) );
172 mCPLegalMatrix.insert( i, myLegalRow );
174 for (
int i = 0; i < mCPRows; i++ )
176 calcRow( i, inverseCt );
181 const bool myColsOK = checkCols( inverseCt );
184 insertRows( inverseCt );
186 const bool myRowsOK = checkRows( inverseCt );
189 insertCols( inverseCt );
191 if ( myColsOK && myRowsOK )
198 if ( mCPRows * mCPCols > 0.25 * mDestRows * mDestCols )
202 mApproximate =
false;
210 QgsDebugMsgLevel( QStringLiteral(
"CPMatrix size: mCPRows = %1 mCPCols = %2" ).arg( mCPRows ).arg( mCPCols ), 4 );
211 mDestRowsPerMatrixRow =
static_cast< double >( mDestRows ) / ( mCPRows - 1 );
212 mDestColsPerMatrixCol =
static_cast< double >( mDestCols ) / ( mCPCols - 1 );
220 pHelperTop =
new QgsPointXY[mDestCols];
221 pHelperBottom =
new QgsPointXY[mDestCols];
222 calcHelper( 0, pHelperTop );
223 calcHelper( 1, pHelperBottom );
229 mSrcYRes = mSrcExtent.height() / mSrcRows;
230 mSrcXRes = mSrcExtent.width() / mSrcCols;
233ProjectorData::~ProjectorData()
236 delete[] pHelperBottom;
240void ProjectorData::calcSrcExtent()
251 mSrcExtent =
QgsRectangle( myPoint.
x(), myPoint.
y(), myPoint.
x(), myPoint.
y() );
252 for (
int i = 0; i < mCPRows; i++ )
254 for (
int j = 0; j < mCPCols ; j++ )
256 myPoint = mCPMatrix[i][j];
257 if ( mCPLegalMatrix[i][j] )
259 mSrcExtent.combineExtentWith( myPoint.
x(), myPoint.
y() );
266 mSrcExtent = mSrcExtent.intersect( mExtent );
277 if ( !mExtent.isEmpty() )
279 if ( mMaxSrcXRes > 0 )
282 double col = std::floor( ( mSrcExtent.xMinimum() - mExtent.xMinimum() ) / mMaxSrcXRes );
283 double x = mExtent.xMinimum() + col * mMaxSrcXRes;
284 mSrcExtent.setXMinimum( x );
286 col = std::ceil( ( mSrcExtent.xMaximum() - mExtent.xMinimum() ) / mMaxSrcXRes );
287 x = mExtent.xMinimum() + col * mMaxSrcXRes;
288 mSrcExtent.setXMaximum( x );
290 if ( mMaxSrcYRes > 0 )
292 double row = std::floor( ( mExtent.yMaximum() - mSrcExtent.yMaximum() ) / mMaxSrcYRes );
293 double y = mExtent.yMaximum() - row * mMaxSrcYRes;
294 mSrcExtent.setYMaximum( y );
296 row = std::ceil( ( mExtent.yMaximum() - mSrcExtent.yMinimum() ) / mMaxSrcYRes );
297 y = mExtent.yMaximum() - row * mMaxSrcYRes;
298 mSrcExtent.setYMinimum( y );
304QString ProjectorData::cpToString()
const
307 for (
int i = 0; i < mCPRows; i++ )
311 for (
int j = 0; j < mCPCols; j++ )
314 myString += QLatin1String(
" " );
316 if ( mCPLegalMatrix[i][j] )
322 myString += QLatin1String(
"(-,-)" );
329void ProjectorData::calcSrcRowsCols()
337 double myMinSize = std::numeric_limits<double>::max();
341 double myMaxSize = 0;
344 const double myDestColsPerMatrixCell =
static_cast< double >( mDestCols ) / mCPCols;
345 const double myDestRowsPerMatrixCell =
static_cast< double >( mDestRows ) / mCPRows;
346 QgsDebugMsgLevel( QStringLiteral(
"myDestColsPerMatrixCell = %1 myDestRowsPerMatrixCell = %2" ).arg( myDestColsPerMatrixCell ).arg( myDestRowsPerMatrixCell ), 4 );
347 for (
int i = 0; i < mCPRows - 1; i++ )
349 for (
int j = 0; j < mCPCols - 1; j++ )
352 const QgsPointXY myPointB = mCPMatrix[i][j + 1];
353 const QgsPointXY myPointC = mCPMatrix[i + 1][j];
354 if ( mCPLegalMatrix[i][j] && mCPLegalMatrix[i][j + 1] && mCPLegalMatrix[i + 1][j] )
356 double mySize = std::sqrt( myPointA.
sqrDist( myPointB ) ) / myDestColsPerMatrixCell;
357 if ( mySize < myMinSize )
359 if ( mySize > myMaxSize )
362 mySize = std::sqrt( myPointA.
sqrDist( myPointC ) ) / myDestRowsPerMatrixCell;
363 if ( mySize < myMinSize )
365 if ( mySize > myMaxSize )
373 if ( myMinSize < 0.1 * myMaxSize )
374 myMinSize = 0.1 * myMaxSize;
381 int srcXSize, srcYSize;
384 const double srcXRes = srcExtent.
width() / srcXSize;
385 const double srcYRes = srcExtent.
height() / srcYSize;
386 myMinSize = std::min( srcXRes, srcYRes );
390 QgsDebugError( QStringLiteral(
"Cannot get src extent/size" ) );
399 QgsDebugMsgLevel( QStringLiteral(
"mMaxSrcXRes = %1 mMaxSrcYRes = %2" ).arg( mMaxSrcXRes ).arg( mMaxSrcYRes ), 4 );
401 const double myMinXSize = mMaxSrcXRes > myMinSize ? mMaxSrcXRes : myMinSize;
402 const double myMinYSize = mMaxSrcYRes > myMinSize ? mMaxSrcYRes : myMinSize;
403 QgsDebugMsgLevel( QStringLiteral(
"myMinXSize = %1 myMinYSize = %2" ).arg( myMinXSize ).arg( myMinYSize ), 4 );
404 QgsDebugMsgLevel( QStringLiteral(
"mSrcExtent.width = %1 mSrcExtent.height = %2" ).arg( mSrcExtent.width() ).arg( mSrcExtent.height() ), 4 );
409 double dblSrcRows = mSrcExtent.height() / myMinYSize;
410 if ( dblSrcRows > mDestRows * 10 )
411 mSrcRows = mDestRows * 10;
413 mSrcRows =
static_cast< int >( std::round( dblSrcRows ) );
415 double dblSrcCols = mSrcExtent.width() / myMinXSize;
416 if ( dblSrcCols > mDestCols * 10 )
417 mSrcCols = mDestCols * 10;
419 mSrcCols =
static_cast< int >( std::round( dblSrcCols ) );
421 QgsDebugMsgLevel( QStringLiteral(
"mSrcRows = %1 mSrcCols = %2" ).arg( mSrcRows ).arg( mSrcCols ), 4 );
425inline void ProjectorData::destPointOnCPMatrix(
int row,
int col,
double *theX,
double *theY )
const
427 *theX = mDestExtent.xMinimum() + col * mDestExtent.width() / ( mCPCols - 1 );
428 *theY = mDestExtent.yMaximum() - row * mDestExtent.height() / ( mCPRows - 1 );
431inline int ProjectorData::matrixRow(
int destRow )
const
433 return static_cast< int >( std::floor( ( destRow + 0.5 ) / mDestRowsPerMatrixRow ) );
435inline int ProjectorData::matrixCol(
int destCol )
const
437 return static_cast< int >( std::floor( ( destCol + 0.5 ) / mDestColsPerMatrixCol ) );
440void ProjectorData::calcHelper(
int matrixRow,
QgsPointXY *points )
443 for (
int myDestCol = 0; myDestCol < mDestCols; myDestCol++ )
445 const double myDestX = mDestExtent.xMinimum() + ( myDestCol + 0.5 ) * mDestXRes;
447 const int myMatrixCol = matrixCol( myDestCol );
449 double myDestXMin, myDestYMin, myDestXMax, myDestYMax;
451 destPointOnCPMatrix( matrixRow, myMatrixCol, &myDestXMin, &myDestYMin );
452 destPointOnCPMatrix( matrixRow, myMatrixCol + 1, &myDestXMax, &myDestYMax );
454 const double xfrac = ( myDestX - myDestXMin ) / ( myDestXMax - myDestXMin );
456 const QgsPointXY &mySrcPoint0 = mCPMatrix[matrixRow][myMatrixCol];
457 const QgsPointXY &mySrcPoint1 = mCPMatrix[matrixRow][myMatrixCol + 1];
458 const double s = mySrcPoint0.
x() + ( mySrcPoint1.
x() - mySrcPoint0.
x() ) * xfrac;
459 const double t = mySrcPoint0.
y() + ( mySrcPoint1.
y() - mySrcPoint0.
y() ) * xfrac;
461 points[myDestCol].
setX( s );
462 points[myDestCol].
setY( t );
466void ProjectorData::nextHelper()
471 pHelperTop = pHelperBottom;
473 calcHelper( mHelperTopRow + 2, pHelperBottom );
477bool ProjectorData::srcRowCol(
int destRow,
int destCol,
int *srcRow,
int *srcCol )
481 return approximateSrcRowCol( destRow, destCol, srcRow, srcCol );
485 return preciseSrcRowCol( destRow, destCol, srcRow, srcCol );
489bool ProjectorData::preciseSrcRowCol(
int destRow,
int destCol,
int *srcRow,
int *srcCol )
493 QgsDebugMsgLevel( QStringLiteral(
"theDestRow = %1 mDestExtent.yMaximum() = %2 mDestYRes = %3" ).arg( destRow ).arg( mDestExtent.yMaximum() ).arg( mDestYRes ), 5 );
497 double x = mDestExtent.xMinimum() + ( destCol + 0.5 ) * mDestXRes;
498 double y = mDestExtent.yMaximum() - ( destRow + 0.5 ) * mDestYRes;
505 if ( mInverseCt.isValid() )
509 mInverseCt.transformInPlace( x, y, z );
521 if ( !mExtent.contains( x, y ) )
526 *srcRow =
static_cast< int >( std::floor( ( mSrcExtent.yMaximum() - y ) / mSrcYRes ) );
527 *srcCol =
static_cast< int >( std::floor( ( x - mSrcExtent.xMinimum() ) / mSrcXRes ) );
529 QgsDebugMsgLevel( QStringLiteral(
"mSrcExtent.yMinimum() = %1 mSrcExtent.yMaximum() = %2 mSrcYRes = %3" ).arg( mSrcExtent.yMinimum() ).arg( mSrcExtent.yMaximum() ).arg( mSrcYRes ), 5 );
530 QgsDebugMsgLevel( QStringLiteral(
"theSrcRow = %1 srcCol = %2" ).arg( *srcRow ).arg( *srcCol ), 5 );
537 if ( *srcRow >= mSrcRows )
return false;
538 if ( *srcRow < 0 )
return false;
539 if ( *srcCol >= mSrcCols )
return false;
540 if ( *srcCol < 0 )
return false;
545bool ProjectorData::approximateSrcRowCol(
int destRow,
int destCol,
int *srcRow,
int *srcCol )
547 const int myMatrixRow = matrixRow( destRow );
548 const int myMatrixCol = matrixCol( destCol );
550 if ( myMatrixRow > mHelperTopRow )
556 const double myDestY = mDestExtent.yMaximum() - ( destRow + 0.5 ) * mDestYRes;
560 double myDestXMin, myDestYMin, myDestXMax, myDestYMax;
562 destPointOnCPMatrix( myMatrixRow + 1, myMatrixCol, &myDestXMin, &myDestYMin );
563 destPointOnCPMatrix( myMatrixRow, myMatrixCol + 1, &myDestXMax, &myDestYMax );
565 const double yfrac = ( myDestY - myDestYMin ) / ( myDestYMax - myDestYMin );
567 const QgsPointXY &myTop = pHelperTop[destCol];
568 const QgsPointXY &myBot = pHelperBottom[destCol];
574 const double tx = myTop.
x();
575 const double ty = myTop.
y();
576 const double bx = myBot.
x();
577 const double by = myBot.
y();
578 const double mySrcX = bx + ( tx - bx ) * yfrac;
579 const double mySrcY = by + ( ty - by ) * yfrac;
581 if ( !mExtent.contains( mySrcX, mySrcY ) )
588 *srcRow =
static_cast< int >( std::floor( ( mSrcExtent.yMaximum() - mySrcY ) / mSrcYRes ) );
589 *srcCol =
static_cast< int >( std::floor( ( mySrcX - mSrcExtent.xMinimum() ) / mSrcXRes ) );
594 if ( *srcRow >= mSrcRows )
return false;
595 if ( *srcRow < 0 )
return false;
596 if ( *srcCol >= mSrcCols )
return false;
597 if ( *srcCol < 0 )
return false;
604 for (
int r = 0; r < mCPRows - 1; r++ )
606 QList<QgsPointXY> myRow;
607 QList<bool> myLegalRow;
608 myRow.reserve( mCPCols );
609 myLegalRow.reserve( mCPCols );
610 for (
int c = 0;
c < mCPCols; ++
c )
613 myLegalRow.append(
false );
615 QgsDebugMsgLevel( QStringLiteral(
"insert new row at %1" ).arg( 1 + r * 2 ), 3 );
616 mCPMatrix.insert( 1 + r * 2, myRow );
617 mCPLegalMatrix.insert( 1 + r * 2, myLegalRow );
619 mCPRows += mCPRows - 1;
620 for (
int r = 1; r < mCPRows - 1; r += 2 )
628 for (
int r = 0; r < mCPRows; r++ )
630 for (
int c = 0;
c < mCPCols - 1;
c++ )
633 mCPLegalMatrix[r].insert( 1 +
c * 2,
false );
636 mCPCols += mCPCols - 1;
637 for (
int c = 1;
c < mCPCols - 1;
c += 2 )
646 double myDestX, myDestY;
647 destPointOnCPMatrix( row, col, &myDestX, &myDestY );
648 const QgsPointXY myDestPoint( myDestX, myDestY );
653 mCPMatrix[row][col] = ct.
transform( myDestPoint );
654 mCPLegalMatrix[row][col] =
true;
658 mCPLegalMatrix[row][col] =
false;
665 mCPLegalMatrix[row][col] =
false;
672 for (
int i = 0; i < mCPCols; i++ )
674 calcCP( row, i, ct );
683 for (
int i = 0; i < mCPRows; i++ )
685 calcCP( i, col, ct );
698 for (
int c = 0;
c < mCPCols;
c++ )
700 for (
int r = 1; r < mCPRows - 1; r += 2 )
702 double myDestX, myDestY;
703 destPointOnCPMatrix( r,
c, &myDestX, &myDestY );
704 const QgsPointXY myDestPoint( myDestX, myDestY );
706 const QgsPointXY mySrcPoint1 = mCPMatrix[r - 1][
c];
708 const QgsPointXY mySrcPoint3 = mCPMatrix[r + 1][
c];
710 const QgsPointXY mySrcApprox( ( mySrcPoint1.
x() + mySrcPoint3.
x() ) / 2, ( mySrcPoint1.
y() + mySrcPoint3.
y() ) / 2 );
711 if ( !mCPLegalMatrix[r - 1][
c] || !mCPLegalMatrix[r][
c] || !mCPLegalMatrix[r + 1][
c] )
719 const double mySqrDist = myDestApprox.
sqrDist( myDestPoint );
720 if ( mySqrDist > mSqrTolerance )
743 for (
int r = 0; r < mCPRows; r++ )
745 for (
int c = 1;
c < mCPCols - 1;
c += 2 )
747 double myDestX, myDestY;
748 destPointOnCPMatrix( r,
c, &myDestX, &myDestY );
750 const QgsPointXY myDestPoint( myDestX, myDestY );
751 const QgsPointXY mySrcPoint1 = mCPMatrix[r][
c - 1];
753 const QgsPointXY mySrcPoint3 = mCPMatrix[r][
c + 1];
755 const QgsPointXY mySrcApprox( ( mySrcPoint1.
x() + mySrcPoint3.
x() ) / 2, ( mySrcPoint1.
y() + mySrcPoint3.
y() ) / 2 );
756 if ( !mCPLegalMatrix[r][
c - 1] || !mCPLegalMatrix[r][
c] || !mCPLegalMatrix[r][
c + 1] )
764 const double mySqrDist = myDestApprox.
sqrDist( myDestPoint );
765 if ( mySqrDist > mSqrTolerance )
789 return tr(
"Approximate" );
791 return tr(
"Exact" );
793 return QStringLiteral(
"Unknown" );
799 QgsDebugMsgLevel( QStringLiteral(
"width = %1 height = %2" ).arg( width ).arg( height ), 4 );
809 if ( ! mSrcCRS.isValid() || ! mDestCRS.isValid() || mSrcCRS == mDestCRS )
812 return mInput->block( bandNo,
extent, width, height, feedback );
820 ProjectorData pd(
extent, width, height,
mInput, inverseCt, mPrecision, feedback );
825 QgsDebugMsgLevel( QStringLiteral(
"srcExtent:\n%1" ).arg( pd.srcExtent().toString() ), 4 );
826 QgsDebugMsgLevel( QStringLiteral(
"srcCols = %1 srcRows = %2" ).arg( pd.srcCols() ).arg( pd.srcRows() ), 4 );
829 if ( pd.srcRows() <= 0 || pd.srcCols() <= 0 )
835 std::unique_ptr< QgsRasterBlock > inputBlock(
mInput->block( bandNo, pd.srcExtent(), pd.srcCols(), pd.srcRows(), feedback ) );
845 auto outputBlock = std::make_unique< QgsRasterBlock >(
input->dataType(), width, height );
848 if (
input->hasNoDataValue() )
855 return outputBlock.release();
874 for (
int i = 0; i < height; ++i )
878 for (
int j = 0; j < width; ++j )
880 const bool inside = pd.srcRowCol( i, j, &srcRow, &srcCol );
881 if ( !inside )
continue;
883 const qgssize srcIndex =
static_cast< qgssize >( srcRow ) * pd.srcCols() + srcCol;
886 if ( doNoData &&
input->isNoData( srcRow, srcCol ) )
891 const qgssize destIndex =
static_cast< qgssize >( i ) * width + j;
892 const char *srcBits =
input->constBits( srcIndex );
893 char *destBits = output->
bits( destIndex );
904 memcpy( destBits, srcBits, pixelSize );
909 return outputBlock.release();
913 QgsRectangle &destExtent,
int &destXSize,
int &destYSize )
915 if ( srcExtent.
isEmpty() || srcXSize <= 0 || srcYSize <= 0 )
925 return extentSize( ct, srcExtent, srcXSize, srcYSize, destExtent, destXSize, destYSize );
929 const QgsRectangle &srcExtent,
int srcXSize,
int srcYSize,
930 QgsRectangle &destExtent,
int &destXSize,
int &destYSize )
932 if ( srcExtent.
isEmpty() || srcXSize <= 0 || srcYSize <= 0 )
944 constexpr int steps = 3;
945 const double srcXStep = srcExtent.
width() / steps;
946 const double srcYStep = srcExtent.
height() / steps;
947 const double srcXRes = srcExtent.
width() / srcXSize;
948 const double srcYRes = srcExtent.
height() / srcYSize;
949 double destXRes = std::numeric_limits<double>::max();
950 double destYRes = std::numeric_limits<double>::max();
954 for (
int i = 0; i < steps; i++ )
956 const double x = srcExtent.
xMinimum() + i * srcXStep;
957 for (
int j = 0; j < steps; j++ )
959 const double y = srcExtent.
yMinimum() + j * srcYStep;
960 const QgsRectangle srcRectangle( x - srcXRes / 2, y - srcYRes / 2, x + srcXRes / 2, y + srcYRes / 2 );
964 if ( destRectangle.
width() > 0 )
966 destXRes = std::min( destXRes, destRectangle.
width() );
967 if ( destRectangle.
width() > maxXRes )
968 maxXRes = destRectangle.
width();
970 if ( destRectangle.
height() > 0 )
972 destYRes = std::min( destYRes, destRectangle.
height() );
973 if ( destRectangle.
height() > maxYRes )
974 maxYRes = destRectangle.
height();
987 if ( destXRes < 0.1 * maxXRes )
989 destXRes = 0.1 * maxXRes;
991 if ( destYRes < 0.1 * maxYRes )
993 destYRes = 0.1 * maxYRes;
995 if ( destXRes == 0 || destExtent.
width() / destXRes > std::numeric_limits<int>::max() )
997 if ( destYRes == 0 || destExtent.
height() / destYRes > std::numeric_limits<int>::max() )
1000 destXSize = std::max( 1,
static_cast< int >( destExtent.
width() / destXRes ) );
1001 destYSize = std::max( 1,
static_cast< int >( destExtent.
height() / destYRes ) );
@ ProviderHintCanPerformProviderResampling
Provider can perform resampling (to be opposed to post rendering resampling).
@ Size
Original data source size (and thus resolution) is known, it is not always available,...
DataType
Raster data types.
@ UnknownDataType
Unknown or unspecified type.
@ Reverse
Reverse/inverse transform (from destination to source).
Represents a coordinate reference system (CRS).
Contains information about the context in which a coordinate transform is executed.
Custom exception class for Coordinate Reference System related exceptions.
bool isCanceled() const
Tells whether the operation has been canceled already.
QString toString(int precision=-1) const
Returns a string representation of the point (x, y) with a preset precision.
double sqrDist(double x, double y) const
Returns the squared distance between this point a specified x, y coordinate.
void setY(double y)
Sets the y value of the point.
void setX(double x)
Sets the x value of the point.
Feedback object tailored for raster block reading.
bool isValid() const
Returns true if the block is valid (correctly filled with data).
static bool typeIsNumeric(Qgis::DataType type)
Returns true if a data type is numeric.
char * bits(int row, int column)
Returns a pointer to block data.
static int typeSize(Qgis::DataType dataType)
Returns the size in bytes for the specified dataType.
void setIsData(int row, int column)
Remove no data flag on pixel.
void setNoDataValue(double noDataValue)
Sets cell value that will be considered as "no data".
bool setIsNoData(int row, int column)
Set no data on pixel.
QgsRectangle extent() const override=0
Returns the extent of the layer.
virtual Qgis::RasterProviderCapabilities providerCapabilities() const
Returns flags containing the supported capabilities of the data provider.
Base class for processing filters like renderers, reprojector, resampler etc.
virtual Qgis::RasterInterfaceCapabilities capabilities() const
Returns the capabilities supported by the interface.
virtual int xSize() const
Gets raster size.
QgsRasterInterface(QgsRasterInterface *input=nullptr)
QgsRasterInterface * mInput
virtual int ySize() const
virtual QgsRectangle extent() const
Gets the extent of the interface.
virtual QgsRasterInterface * input() const
Current input.
QgsRasterProjector * clone() const override
Clone itself, create deep copy.
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)
Qgis::DataType dataType(int bandNo) const override
Returns data type for the band specified by number.
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
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.
Precision
Precision defines if each pixel is reprojected or approximate reprojection based on an approximation ...
@ Exact
Exact, precise but slow.
@ Approximate
Approximate (default), fast but possibly inaccurate.
Precision precision() const
int bandCount() const override
Gets number of bands.
Q_DECL_DEPRECATED void setCrs(const QgsCoordinateReferenceSystem &srcCRS, const QgsCoordinateReferenceSystem &destCRS, int srcDatumTransform=-1, int destDatumTransform=-1)
Sets the source and destination CRS.
A rectangle specified with double values.
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
#define Q_NOWARN_DEPRECATED_POP
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...
#define Q_NOWARN_DEPRECATED_PUSH
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)