38 projector->mSrcCRS = mSrcCRS;
39 projector->mDestCRS = mDestCRS;
40 projector->mTransformContext = mTransformContext;
43 projector->mSrcDatumTransform = mSrcDatumTransform;
44 projector->mDestDatumTransform = mDestDatumTransform;
47 projector->mPrecision = mPrecision;
70 int srcDatumTransform,
71 int destDatumTransform )
76 mSrcDatumTransform = srcDatumTransform;
77 mDestDatumTransform = destDatumTransform;
85 mTransformContext = transformContext;
87 mSrcDatumTransform = -1;
88 mDestDatumTransform = -1;
94 : mApproximate( false )
95 , mInverseCt( inverseCt )
96 , mDestExtent( extent )
105 , mDestRowsPerMatrixRow( 0.0 )
106 , mDestColsPerMatrixCol( 0.0 )
110 , mSqrTolerance( 0.0 )
133 if ( mExtent.isEmpty() )
135 mExtent = provider->
extent();
140 mDestXRes = mDestExtent.
width() / ( mDestCols );
141 mDestYRes = mDestExtent.height() / ( mDestRows );
147 double myDestRes = mDestXRes < mDestYRes ? mDestXRes : mDestYRes;
148 mSqrTolerance = myDestRes * myDestRes;
156 mApproximate =
false;
161 mCPCols = mCPRows = 3;
162 for (
int i = 0; i < mCPRows; i++ )
164 QList<QgsPointXY> myRow;
168 mCPMatrix.insert( i, myRow );
170 QList<bool> myLegalRow;
171 myLegalRow.append(
bool(
false ) );
172 myLegalRow.append(
bool(
false ) );
173 myLegalRow.append(
bool(
false ) );
174 mCPLegalMatrix.insert( i, myLegalRow );
176 for (
int i = 0; i < mCPRows; i++ )
178 calcRow( i, inverseCt );
183 bool myColsOK = checkCols( inverseCt );
186 insertRows( inverseCt );
188 bool myRowsOK = checkRows( inverseCt );
191 insertCols( inverseCt );
193 if ( myColsOK && myRowsOK )
200 if ( mCPRows * mCPCols > 0.25 * mDestRows * mDestCols )
204 mApproximate =
false;
212 QgsDebugMsgLevel( QStringLiteral(
"CPMatrix size: mCPRows = %1 mCPCols = %2" ).arg( mCPRows ).arg( mCPCols ), 4 );
213 mDestRowsPerMatrixRow =
static_cast< double >( mDestRows ) / ( mCPRows - 1 );
214 mDestColsPerMatrixCol =
static_cast< double >( mDestCols ) / ( mCPCols - 1 );
224 calcHelper( 0, pHelperTop );
225 calcHelper( 1, pHelperBottom );
231 mSrcYRes = mSrcExtent.height() / mSrcRows;
232 mSrcXRes = mSrcExtent.width() / mSrcCols;
235 ProjectorData::~ProjectorData()
238 delete[] pHelperBottom;
242 void ProjectorData::calcSrcExtent()
253 mSrcExtent =
QgsRectangle( myPoint.
x(), myPoint.
y(), myPoint.
x(), myPoint.
y() );
254 for (
int i = 0; i < mCPRows; i++ )
256 for (
int j = 0; j < mCPCols ; j++ )
258 myPoint = mCPMatrix[i][j];
259 if ( mCPLegalMatrix[i][j] )
261 mSrcExtent.combineExtentWith( myPoint.
x(), myPoint.
y() );
268 mSrcExtent = mSrcExtent.intersect( mExtent );
279 if ( !mExtent.isEmpty() )
281 if ( mMaxSrcXRes > 0 )
284 double col = std::floor( ( mSrcExtent.xMinimum() - mExtent.xMinimum() ) / mMaxSrcXRes );
285 double x = mExtent.xMinimum() + col * mMaxSrcXRes;
286 mSrcExtent.setXMinimum( x );
288 col = std::ceil( ( mSrcExtent.xMaximum() - mExtent.xMinimum() ) / mMaxSrcXRes );
289 x = mExtent.xMinimum() + col * mMaxSrcXRes;
290 mSrcExtent.setXMaximum( x );
292 if ( mMaxSrcYRes > 0 )
294 double row = std::floor( ( mExtent.yMaximum() - mSrcExtent.yMaximum() ) / mMaxSrcYRes );
295 double y = mExtent.yMaximum() - row * mMaxSrcYRes;
296 mSrcExtent.setYMaximum( y );
298 row = std::ceil( ( mExtent.yMaximum() - mSrcExtent.yMinimum() ) / mMaxSrcYRes );
299 y = mExtent.yMaximum() - row * mMaxSrcYRes;
300 mSrcExtent.setYMinimum( y );
306 QString ProjectorData::cpToString()
309 for (
int i = 0; i < mCPRows; i++ )
313 for (
int j = 0; j < mCPCols; j++ )
316 myString += QLatin1String(
" " );
318 if ( mCPLegalMatrix[i][j] )
324 myString += QLatin1String(
"(-,-)" );
331 void ProjectorData::calcSrcRowsCols()
339 double myMinSize = std::numeric_limits<double>::max();
344 double myDestColsPerMatrixCell =
static_cast< double >( mDestCols ) / mCPCols;
345 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++ )
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 )
360 mySize = std::sqrt( myPointA.
sqrDist( myPointC ) ) / myDestRowsPerMatrixCell;
361 if ( mySize < myMinSize )
372 int srcXSize, srcYSize;
375 double srcXRes = srcExtent.
width() / srcXSize;
376 double srcYRes = srcExtent.
height() / srcYSize;
377 myMinSize = std::min( srcXRes, srcYRes );
381 QgsDebugMsg( QStringLiteral(
"Cannot get src extent/size" ) );
390 QgsDebugMsgLevel( QStringLiteral(
"mMaxSrcXRes = %1 mMaxSrcYRes = %2" ).arg( mMaxSrcXRes ).arg( mMaxSrcYRes ), 4 );
392 double myMinXSize = mMaxSrcXRes > myMinSize ? mMaxSrcXRes : myMinSize;
393 double myMinYSize = mMaxSrcYRes > myMinSize ? mMaxSrcYRes : myMinSize;
394 QgsDebugMsgLevel( QStringLiteral(
"myMinXSize = %1 myMinYSize = %2" ).arg( myMinXSize ).arg( myMinYSize ), 4 );
395 QgsDebugMsgLevel( QStringLiteral(
"mSrcExtent.width = %1 mSrcExtent.height = %2" ).arg( mSrcExtent.width() ).arg( mSrcExtent.height() ), 4 );
398 mSrcRows =
static_cast< int >( std::round( mSrcExtent.height() / myMinYSize ) );
399 mSrcCols =
static_cast< int >( std::round( mSrcExtent.width() / myMinXSize ) );
401 QgsDebugMsgLevel( QStringLiteral(
"mSrcRows = %1 mSrcCols = %2" ).arg( mSrcRows ).arg( mSrcCols ), 4 );
405 inline void ProjectorData::destPointOnCPMatrix(
int row,
int col,
double *theX,
double *theY )
407 *theX = mDestExtent.xMinimum() + col * mDestExtent.width() / ( mCPCols - 1 );
408 *theY = mDestExtent.yMaximum() - row * mDestExtent.height() / ( mCPRows - 1 );
411 inline int ProjectorData::matrixRow(
int destRow )
413 return static_cast< int >( std::floor( ( destRow + 0.5 ) / mDestRowsPerMatrixRow ) );
415 inline int ProjectorData::matrixCol(
int destCol )
417 return static_cast< int >( std::floor( ( destCol + 0.5 ) / mDestColsPerMatrixCol ) );
420 void ProjectorData::calcHelper(
int matrixRow,
QgsPointXY *points )
423 for (
int myDestCol = 0; myDestCol < mDestCols; myDestCol++ )
425 double myDestX = mDestExtent.xMinimum() + ( myDestCol + 0.5 ) * mDestXRes;
427 int myMatrixCol = matrixCol( myDestCol );
429 double myDestXMin, myDestYMin, myDestXMax, myDestYMax;
431 destPointOnCPMatrix( matrixRow, myMatrixCol, &myDestXMin, &myDestYMin );
432 destPointOnCPMatrix( matrixRow, myMatrixCol + 1, &myDestXMax, &myDestYMax );
434 double xfrac = ( myDestX - myDestXMin ) / ( myDestXMax - myDestXMin );
436 QgsPointXY &mySrcPoint0 = mCPMatrix[matrixRow][myMatrixCol];
437 QgsPointXY &mySrcPoint1 = mCPMatrix[matrixRow][myMatrixCol + 1];
438 double s = mySrcPoint0.
x() + ( mySrcPoint1.
x() - mySrcPoint0.
x() ) * xfrac;
439 double t = mySrcPoint0.
y() + ( mySrcPoint1.
y() - mySrcPoint0.
y() ) * xfrac;
441 points[myDestCol].
setX( s );
442 points[myDestCol].
setY( t );
446 void ProjectorData::nextHelper()
451 pHelperTop = pHelperBottom;
453 calcHelper( mHelperTopRow + 2, pHelperBottom );
457 bool ProjectorData::srcRowCol(
int destRow,
int destCol,
int *srcRow,
int *srcCol )
461 return approximateSrcRowCol( destRow, destCol, srcRow, srcCol );
465 return preciseSrcRowCol( destRow, destCol, srcRow, srcCol );
469 bool ProjectorData::preciseSrcRowCol(
int destRow,
int destCol,
int *srcRow,
int *srcCol )
473 QgsDebugMsgLevel( QStringLiteral(
"theDestRow = %1 mDestExtent.yMaximum() = %2 mDestYRes = %3" ).arg( destRow ).arg( mDestExtent.yMaximum() ).arg( mDestYRes ), 5 );
477 double x = mDestExtent.xMinimum() + ( destCol + 0.5 ) * mDestXRes;
478 double y = mDestExtent.yMaximum() - ( destRow + 0.5 ) * mDestYRes;
485 if ( mInverseCt.isValid() )
489 mInverseCt.transformInPlace( x, y, z );
501 if ( !mExtent.contains(
QgsPointXY( x, y ) ) )
506 *srcRow =
static_cast< int >( std::floor( ( mSrcExtent.yMaximum() - y ) / mSrcYRes ) );
507 *srcCol =
static_cast< int >( std::floor( ( x - mSrcExtent.xMinimum() ) / mSrcXRes ) );
509 QgsDebugMsgLevel( QStringLiteral(
"mSrcExtent.yMinimum() = %1 mSrcExtent.yMaximum() = %2 mSrcYRes = %3" ).arg( mSrcExtent.yMinimum() ).arg( mSrcExtent.yMaximum() ).arg( mSrcYRes ), 5 );
510 QgsDebugMsgLevel( QStringLiteral(
"theSrcRow = %1 srcCol = %2" ).arg( *srcRow ).arg( *srcCol ), 5 );
517 if ( *srcRow >= mSrcRows )
return false;
518 if ( *srcRow < 0 )
return false;
519 if ( *srcCol >= mSrcCols )
return false;
520 if ( *srcCol < 0 )
return false;
525 bool ProjectorData::approximateSrcRowCol(
int destRow,
int destCol,
int *srcRow,
int *srcCol )
527 int myMatrixRow = matrixRow( destRow );
528 int myMatrixCol = matrixCol( destCol );
530 if ( myMatrixRow > mHelperTopRow )
536 double myDestY = mDestExtent.yMaximum() - ( destRow + 0.5 ) * mDestYRes;
540 double myDestXMin, myDestYMin, myDestXMax, myDestYMax;
542 destPointOnCPMatrix( myMatrixRow + 1, myMatrixCol, &myDestXMin, &myDestYMin );
543 destPointOnCPMatrix( myMatrixRow, myMatrixCol + 1, &myDestXMax, &myDestYMax );
545 double yfrac = ( myDestY - myDestYMin ) / ( myDestYMax - myDestYMin );
554 double tx = myTop.
x();
555 double ty = myTop.
y();
556 double bx = myBot.
x();
557 double by = myBot.
y();
558 double mySrcX = bx + ( tx - bx ) * yfrac;
559 double mySrcY = by + ( ty - by ) * yfrac;
561 if ( !mExtent.contains(
QgsPointXY( mySrcX, mySrcY ) ) )
568 *srcRow =
static_cast< int >( std::floor( ( mSrcExtent.yMaximum() - mySrcY ) / mSrcYRes ) );
569 *srcCol =
static_cast< int >( std::floor( ( mySrcX - mSrcExtent.xMinimum() ) / mSrcXRes ) );
574 if ( *srcRow >= mSrcRows )
return false;
575 if ( *srcRow < 0 )
return false;
576 if ( *srcCol >= mSrcCols )
return false;
577 if ( *srcCol < 0 )
return false;
584 for (
int r = 0; r < mCPRows - 1; r++ )
586 QList<QgsPointXY> myRow;
587 QList<bool> myLegalRow;
588 myRow.reserve( mCPCols );
589 myLegalRow.reserve( mCPCols );
590 for (
int c = 0;
c < mCPCols; ++
c )
593 myLegalRow.append(
false );
595 QgsDebugMsgLevel( QStringLiteral(
"insert new row at %1" ).arg( 1 + r * 2 ), 3 );
596 mCPMatrix.insert( 1 + r * 2, myRow );
597 mCPLegalMatrix.insert( 1 + r * 2, myLegalRow );
599 mCPRows += mCPRows - 1;
600 for (
int r = 1; r < mCPRows - 1; r += 2 )
608 for (
int r = 0; r < mCPRows; r++ )
610 for (
int c = 0;
c < mCPCols - 1;
c++ )
613 mCPLegalMatrix[r].insert( 1 +
c * 2,
false );
616 mCPCols += mCPCols - 1;
617 for (
int c = 1;
c < mCPCols - 1;
c += 2 )
626 double myDestX, myDestY;
627 destPointOnCPMatrix( row, col, &myDestX, &myDestY );
633 mCPMatrix[row][col] = ct.
transform( myDestPoint );
634 mCPLegalMatrix[row][col] =
true;
638 mCPLegalMatrix[row][col] =
false;
645 mCPLegalMatrix[row][col] =
false;
652 for (
int i = 0; i < mCPCols; i++ )
654 calcCP( row, i, ct );
663 for (
int i = 0; i < mCPRows; i++ )
665 calcCP( i, col, ct );
678 for (
int c = 0;
c < mCPCols;
c++ )
680 for (
int r = 1; r < mCPRows - 1; r += 2 )
682 double myDestX, myDestY;
683 destPointOnCPMatrix( r,
c, &myDestX, &myDestY );
690 QgsPointXY mySrcApprox( ( mySrcPoint1.
x() + mySrcPoint3.
x() ) / 2, ( mySrcPoint1.
y() + mySrcPoint3.
y() ) / 2 );
691 if ( !mCPLegalMatrix[r - 1][
c] || !mCPLegalMatrix[r][
c] || !mCPLegalMatrix[r + 1][
c] )
699 double mySqrDist = myDestApprox.
sqrDist( myDestPoint );
700 if ( mySqrDist > mSqrTolerance )
723 for (
int r = 0; r < mCPRows; r++ )
725 for (
int c = 1;
c < mCPCols - 1;
c += 2 )
727 double myDestX, myDestY;
728 destPointOnCPMatrix( r,
c, &myDestX, &myDestY );
735 QgsPointXY mySrcApprox( ( mySrcPoint1.
x() + mySrcPoint3.
x() ) / 2, ( mySrcPoint1.
y() + mySrcPoint3.
y() ) / 2 );
736 if ( !mCPLegalMatrix[r][
c - 1] || !mCPLegalMatrix[r][
c] || !mCPLegalMatrix[r][
c + 1] )
744 double mySqrDist = myDestApprox.
sqrDist( myDestPoint );
745 if ( mySqrDist > mSqrTolerance )
769 return tr(
"Approximate" );
771 return tr(
"Exact" );
773 return QStringLiteral(
"Unknown" );
779 QgsDebugMsgLevel( QStringLiteral(
"width = %1 height = %2" ).arg( width ).arg( height ), 4 );
789 if ( ! mSrcCRS.
isValid() || ! mDestCRS.
isValid() || mSrcCRS == mDestCRS )
800 ProjectorData pd(
extent, width, height,
mInput, inverseCt, mPrecision, feedback );
805 QgsDebugMsgLevel( QStringLiteral(
"srcExtent:\n%1" ).arg( pd.srcExtent().toString() ), 4 );
806 QgsDebugMsgLevel( QStringLiteral(
"srcCols = %1 srcRows = %2" ).arg( pd.srcCols() ).arg( pd.srcRows() ), 4 );
809 if ( pd.srcRows() <= 0 || pd.srcCols() <= 0 )
815 std::unique_ptr< QgsRasterBlock > inputBlock(
mInput->
block( bandNo, pd.srcExtent(), pd.srcCols(), pd.srcRows(), feedback ) );
816 if ( !inputBlock || inputBlock->isEmpty() )
818 QgsDebugMsg( QStringLiteral(
"No raster data!" ) );
824 std::unique_ptr< QgsRasterBlock > outputBlock(
new QgsRasterBlock( inputBlock->dataType(), width, height ) );
825 if ( inputBlock->hasNoDataValue() )
827 outputBlock->setNoDataValue( inputBlock->noDataValue() );
829 if ( !outputBlock->isValid() )
831 QgsDebugMsg( QStringLiteral(
"Cannot create block" ) );
832 return outputBlock.release();
836 outputBlock->setIsNoData();
850 outputBlock->setIsNoData();
853 for (
int i = 0; i < height; ++i )
857 for (
int j = 0; j < width; ++j )
859 bool inside = pd.srcRowCol( i, j, &srcRow, &srcCol );
860 if ( !inside )
continue;
862 qgssize srcIndex =
static_cast< qgssize >( srcRow * pd.srcCols() + srcCol );
865 if ( doNoData && inputBlock->isNoData( srcRow, srcCol ) )
867 outputBlock->setIsNoData( i, j );
872 char *srcBits = inputBlock->bits( srcIndex );
873 char *destBits = outputBlock->bits( destIndex );
884 memcpy( destBits, srcBits, pixelSize );
885 outputBlock->setIsData( i, j );
889 return outputBlock.release();
893 QgsRectangle &destExtent,
int &destXSize,
int &destYSize )
895 if ( srcExtent.
isEmpty() || srcXSize <= 0 || srcYSize <= 0 )
905 return extentSize( ct, srcExtent, srcXSize, srcYSize, destExtent, destXSize, destYSize );
909 const QgsRectangle &srcExtent,
int srcXSize,
int srcYSize,
910 QgsRectangle &destExtent,
int &destXSize,
int &destYSize )
912 if ( srcExtent.
isEmpty() || srcXSize <= 0 || srcYSize <= 0 )
921 double srcXStep = srcExtent.
width() / 3;
922 double srcYStep = srcExtent.
height() / 3;
923 double srcXRes = srcExtent.
width() / srcXSize;
924 double srcYRes = srcExtent.
height() / srcYSize;
925 double destXRes = std::numeric_limits<double>::max();
926 double destYRes = std::numeric_limits<double>::max();
928 for (
int i = 0; i < 3; i++ )
930 double x = srcExtent.
xMinimum() + i * srcXStep;
931 for (
int j = 0; j < 3; j++ )
933 double y = srcExtent.
yMinimum() + j * srcYStep;
934 QgsRectangle srcRectangle( x - srcXRes / 2, y - srcYRes / 2, x + srcXRes / 2, y + srcYRes / 2 );
938 if ( destRectangle.
width() > 0 )
940 destXRes = std::min( destXRes, destRectangle.
width() );
942 if ( destRectangle.
height() > 0 )
944 destYRes = std::min( destYRes, destRectangle.
height() );
953 destXSize = std::max( 1,
static_cast< int >( destExtent.
width() / destYRes ) );
954 destYSize = std::max( 1,
static_cast< int >( destExtent.
height() / destYRes ) );
DataType
Raster data types.
@ UnknownDataType
Unknown or unspecified type.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
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.
A class to represent a 2D point.
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 SIP_HOLDGIL
Returns the squared distance between this point a specified x, y coordinate.
void setX(double x) SIP_HOLDGIL
Sets the x value of the point.
void setY(double y) SIP_HOLDGIL
Sets the y value of the point.
Feedback object tailored for raster block reading.
static bool typeIsNumeric(Qgis::DataType type)
Returns true if data type is numeric.
static int typeSize(int dataType) SIP_HOLDGIL
Returns the size in bytes for the specified dataType.
Base class for raster data providers.
virtual QgsRasterDataProvider::ProviderCapabilities providerCapabilities() const
Returns flags containing the supported capabilities of the data provider.
QgsRectangle extent() const override=0
Returns the extent of the layer.
@ ProviderHintCanPerformProviderResampling
Provider can perform resampling (to be opposed to post rendering resampling) (since QGIS 3....
Base class for processing filters like renderers, reprojector, resampler etc.
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 Qgis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number.
@ Size
Original data source size (and thus resolution) is known, it is not always available,...
virtual QgsRasterInterface * input() const
Current input.
virtual int xSize() const
Gets raster size.
virtual const QgsRasterInterface * sourceInput() const
Gets source / raw input, the first in pipe, usually provider.
virtual int bandCount() const =0
Gets number of bands.
QgsRasterInterface * mInput
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
virtual int ySize() const
virtual QgsRectangle extent() const
Gets the extent of the interface.
QgsRasterProjector implements approximate projection support for it calculates grid of points in sour...
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.
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
bool isEmpty() const
Returns true if the rectangle is empty.
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)