28 #include <QCoreApplication>    29 #include <QProgressDialog>    30 #include <QTextStream>    31 #include <QMessageBox>    36 #include <cpl_string.h>    44   double geoTransform[6];
    45   globalOutputParameters( extent, width, height, geoTransform, pixelSize );
    47   return initOutput( width, height, crs, geoTransform, 1, dataType, QList<bool>(), QList<double>() );
    56   double geoTransform[6];
    57   globalOutputParameters( extent, width, height, geoTransform, pixelSize );
    59   return initOutput( width, height, crs, geoTransform, nBands, dataType, QList<bool>(), QList<double>() );
    63   : mOutputUrl( outputUrl )
   110   QgsDebugMsgLevel( QStringLiteral( 
"reading from %1" ).arg( 
typeid( *iface ).name() ), 4 );
   114     QgsDebugMsg( QStringLiteral( 
"iface->srcInput() == 0" ) );
   119   QgsDebugMsgLevel( QStringLiteral( 
"srcInput = %1" ).arg( 
typeid( srcInput ).name() ), 4 );
   122   mFeedback = feedback;
   129     QFileInfo fileInfo( mOutputUrl );
   130     if ( !fileInfo.exists() )
   132       QDir dir = fileInfo.dir();
   133       if ( !dir.mkdir( fileInfo.fileName() ) )
   135         QgsDebugMsg( 
"Cannot create output VRT directory " + fileInfo.fileName() + 
" in " + dir.absolutePath() );
   142   QFile pyramidFile( mOutputUrl + ( mTiledMode ? 
".vrt.ovr" : 
".ovr" ) );
   143   if ( pyramidFile.exists() )
   144     pyramidFile.remove();
   145   pyramidFile.setFileName( mOutputUrl + ( mTiledMode ? 
".vrt.rrd" : 
".rrd" ) );
   146   if ( pyramidFile.exists() )
   147     pyramidFile.remove();
   149   if ( mMode == 
Image )
   151     WriterError e = writeImageRaster( &iter, nCols, nRows, outputExtent, crs, feedback );
   156     WriterError e = writeDataRaster( pipe, &iter, nCols, nRows, outputExtent, crs, transformContext, feedback );
   179     QgsDebugMsg( QStringLiteral( 
"Cannot get source data provider" ) );
   196   for ( 
int i = 2; i <= nBands; ++i )
   208   QList<bool> destHasNoDataValueList;
   209   QList<double> destNoDataValueList;
   210   QList<Qgis::DataType> destDataTypeList;
   211   destDataTypeList.reserve( nBands );
   212   destHasNoDataValueList.reserve( nBands );
   213   destNoDataValueList.reserve( nBands );
   215   const bool isGpkgOutput = mOutputProviderKey == 
"gdal" &&
   216                             mOutputFormat.compare( QLatin1String( 
"gpkg" ), Qt::CaseInsensitive ) == 0;
   218   double geoTransform[6];
   219   globalOutputParameters( outputExtent, nCols, nRows, geoTransform, pixelSize );
   220   const auto srcProviderExtent( srcProvider->
extent() );
   222   for ( 
int bandNo = 1; bandNo <= nBands; bandNo++ )
   227     bool destHasNoDataValue = 
false;
   228     double destNoDataValue = std::numeric_limits<double>::quiet_NaN();
   233     if ( srcHasNoDataValue )
   238       destHasNoDataValue = 
true;
   240     else if ( nuller && !nuller->
noData( bandNo ).isEmpty() )
   243       destNoDataValue = nuller->
noData( bandNo ).value( 0 ).min();
   244       destHasNoDataValue = 
true;
   249     else if ( !( isGpkgOutput && destDataType == 
Qgis::Byte ) )
   257         outputExtentInSrcCrs = ct.transformBoundingBox( outputExtent );
   259       if ( !srcProviderExtent.contains( outputExtentInSrcCrs ) &&
   260            ( std::fabs( srcProviderExtent.xMinimum() - outputExtentInSrcCrs.
xMinimum() ) > geoTransform[1] / 2 ||
   261              std::fabs( srcProviderExtent.xMaximum() - outputExtentInSrcCrs.
xMaximum() ) > geoTransform[1] / 2 ||
   262              std::fabs( srcProviderExtent.yMinimum() - outputExtentInSrcCrs.
yMinimum() ) > std::fabs( geoTransform[5] ) / 2 ||
   263              std::fabs( srcProviderExtent.yMaximum() - outputExtentInSrcCrs.
yMaximum() ) > std::fabs( geoTransform[5] ) / 2 ) )
   274           destNoDataValue = typeMinValue;
   278           destNoDataValue = typeMaxValue;
   285         destHasNoDataValue = 
true;
   289     if ( nuller && destHasNoDataValue )
   294     QgsDebugMsgLevel( QStringLiteral( 
"bandNo = %1 destDataType = %2 destHasNoDataValue = %3 destNoDataValue = %4" ).arg( bandNo ).arg( destDataType ).arg( destHasNoDataValue ).arg( destNoDataValue ), 4 );
   295     destDataTypeList.append( destDataType );
   296     destHasNoDataValueList.append( destHasNoDataValue );
   297     destNoDataValueList.append( destNoDataValue );
   302   for ( 
int i = 1; i < nBands; i++ )
   304     if ( destDataTypeList.value( i ) > destDataType )
   306       destDataType = destDataTypeList.value( i );
   312   for ( 
int attempt = 0; attempt < 2; attempt ++ )
   316     std::unique_ptr<QgsRasterDataProvider> destProvider(
   317       initOutput( nCols, nRows, crs, geoTransform, nBands, destDataType, destHasNoDataValueList, destNoDataValueList ) );
   324       if ( !destProvider->isValid() )
   326         if ( feedback && !destProvider->error().isEmpty() )
   328           feedback->
appendError( destProvider->error().summary() );
   332       if ( nCols != destProvider->xSize() || nRows != destProvider->ySize() )
   334         QgsDebugMsg( QStringLiteral( 
"Created raster does not have requested dimensions" ) );
   337           feedback->
appendError( QObject::tr( 
"Created raster does not have requested dimensions" ) );
   341       if ( nBands != destProvider->bandCount() )
   343         QgsDebugMsg( QStringLiteral( 
"Created raster does not have requested band count" ) );
   346           feedback->
appendError( QObject::tr( 
"Created raster does not have requested band count" ) );
   354         destDataType = destProvider->dataType( 1 );
   358     error = writeDataRaster( pipe, iter, nCols, nRows, outputExtent, crs, destDataType, destHasNoDataValueList, destNoDataValueList, destProvider.get(), feedback );
   365         destProvider->remove();
   366         destProvider.reset();
   374       for ( 
int i = 0; i < nBands; i++ )
   376         double destNoDataValue;
   378         destDataTypeList.replace( i, destDataType );
   379         destNoDataValueList.replace( i, destNoDataValue );
   381       destDataType = destDataTypeList.value( 0 );
   394 static int qgsDivRoundUp( 
int a, 
int b )
   396   return a / b + ( ( ( a % b ) != 0 ) ? 1 : 0 );
   401     int nCols, 
int nRows,
   405     const QList<bool> &destHasNoDataValueList,
   406     const QList<double> &destNoDataValueList,
   411   Q_UNUSED( destHasNoDataValueList )
   425   std::vector< std::unique_ptr<QgsRasterBlock> > blockList;
   426   std::vector< std::unique_ptr<QgsRasterBlock> > destBlockList;
   428   blockList.resize( nBands );
   429   destBlockList.resize( nBands );
   431   for ( 
int i = 1; i <= nBands; ++i )
   434     if ( destProvider && destHasNoDataValueList.value( i - 1 ) ) 
   436       destProvider->
setNoDataValue( i, destNoDataValueList.value( i - 1 ) );
   446     nParts = nPartsX * nPartsY;
   453     for ( 
int i = 1; i <= nBands; ++i )
   461           QString vrtFilePath( mOutputUrl + 
'/' + vrtFileName() );
   462           writeVRT( vrtFilePath );
   465             buildPyramids( vrtFilePath );
   472             buildPyramids( mOutputUrl, destProvider );
   479       blockList[i - 1].reset( block );
   483     if ( feedback && fileIndex < ( nParts - 1 ) )
   485       feedback->
setProgress( 100.0 * fileIndex / static_cast< double >( nParts ) );
   493     for ( 
int i = 1; i <= nBands; ++i )
   495       if ( srcProvider && srcProvider->
dataType( i ) == destDataType )
   502         blockList[i - 1]->convert( destDataType );
   504       destBlockList[i - 1] = std::move( blockList[i - 1] );
   509       std::unique_ptr< QgsRasterDataProvider > partDestProvider( createPartProvider( outputExtent,
   510           nCols, iterCols, iterRows,
   511           iterLeft, iterTop, mOutputUrl,
   512           fileIndex, nBands, destDataType, crs ) );
   514       if ( !partDestProvider || !partDestProvider->isValid() )
   520       for ( 
int i = 1; i <= nBands; ++i )
   522         if ( destHasNoDataValueList.value( i - 1 ) )
   524           partDestProvider->setNoDataValue( i, destNoDataValueList.value( i - 1 ) );
   526         if ( destBlockList[ i - 1 ]->isEmpty() )
   529         if ( !partDestProvider->write( destBlockList[i - 1]->bits( 0 ), i, iterCols, iterRows, 0, 0 ) )
   533         addToVRT( partFileName( fileIndex ), i, iterCols, iterRows, iterLeft, iterTop );
   537     else if ( destProvider )
   540       for ( 
int i = 1; i <= nBands; ++i )
   542         if ( destBlockList[ i - 1 ]->isEmpty() )
   545         if ( !destProvider->
write( destBlockList[i - 1]->bits( 0 ), i, iterCols, iterRows, iterLeft, iterTop ) )
   581   const size_t nMaxPixels = 
static_cast<size_t>( mMaxTileWidth ) * mMaxTileHeight;
   582   std::vector<unsigned char> redData( nMaxPixels );
   583   std::vector<unsigned char> greenData( nMaxPixels );
   584   std::vector<unsigned char> blueData( nMaxPixels );
   585   std::vector<unsigned char> alphaData( nMaxPixels );
   586   int iterLeft = 0, iterTop = 0, iterCols = 0, iterRows = 0;
   591   double geoTransform[6];
   592   globalOutputParameters( outputExtent, nCols, nRows, geoTransform, pixelSize );
   594   const int nOutputBands = 4;
   595   std::unique_ptr< QgsRasterDataProvider > destProvider( initOutput( nCols, nRows, crs, geoTransform, nOutputBands, 
Qgis::Byte ) );
   602     if ( !destProvider->isValid() )
   604       if ( feedback && !destProvider->error().isEmpty() )
   606         feedback->
appendError( destProvider->error().summary() );
   610     if ( nCols != destProvider->xSize() || nRows != destProvider->ySize() )
   612       QgsDebugMsg( QStringLiteral( 
"Created raster does not have requested dimensions" ) );
   615         feedback->
appendError( QObject::tr( 
"Created raster does not have requested dimensions" ) );
   619     if ( nOutputBands != destProvider->bandCount() )
   621       QgsDebugMsg( QStringLiteral( 
"Created raster does not have requested band count" ) );
   624         feedback->
appendError( QObject::tr( 
"Created raster does not have requested band count" ) );
   628     if ( 
Qgis::Byte != destProvider->dataType( 1 ) )
   630       QgsDebugMsg( QStringLiteral( 
"Created raster does not have requested data type" ) );
   633         feedback->
appendError( QObject::tr( 
"Created raster does not have requested data type" ) );
   646     nParts = nPartsX * nPartsY;
   649   std::unique_ptr< QgsRasterBlock > inputBlock;
   650   while ( iter->
readNextRasterPart( 1, iterCols, iterRows, inputBlock, iterLeft, iterTop ) )
   652     if ( !inputBlock || inputBlock->isEmpty() )
   657     if ( feedback && fileIndex < ( nParts - 1 ) )
   659       feedback->
setProgress( 100.0 * fileIndex / static_cast< double >( nParts ) );
   668     for ( 
qgssize i = 0; i < nPixels; ++i )
   670       QRgb 
c = inputBlock->color( i );
   671       if ( isPremultiplied )
   673         c = qUnpremultiply( c );
   675       redData[i] = 
static_cast<unsigned char>( qRed( c ) );
   676       greenData[i] = 
static_cast<unsigned char>( qGreen( c ) );
   677       blueData[i] = 
static_cast<unsigned char>( qBlue( c ) );
   678       alphaData[i] = 
static_cast<unsigned char>( qAlpha( c ) );
   684       std::unique_ptr< QgsRasterDataProvider > partDestProvider( createPartProvider( outputExtent,
   685           nCols, iterCols, iterRows,
   686           iterLeft, iterTop, mOutputUrl, fileIndex,
   689       if ( !partDestProvider || partDestProvider->isValid() )
   695       if ( !partDestProvider->write( &redData[0], 1, iterCols, iterRows, 0, 0 ) ||
   696            !partDestProvider->write( &greenData[0], 2, iterCols, iterRows, 0, 0 ) ||
   697            !partDestProvider->write( &blueData[0], 3, iterCols, iterRows, 0, 0 ) ||
   698            !partDestProvider->write( &alphaData[0], 4, iterCols, iterRows, 0, 0 ) )
   703       addToVRT( partFileName( fileIndex ), 1, iterCols, iterRows, iterLeft, iterTop );
   704       addToVRT( partFileName( fileIndex ), 2, iterCols, iterRows, iterLeft, iterTop );
   705       addToVRT( partFileName( fileIndex ), 3, iterCols, iterRows, iterLeft, iterTop );
   706       addToVRT( partFileName( fileIndex ), 4, iterCols, iterRows, iterLeft, iterTop );
   708     else if ( destProvider )
   710       if ( !destProvider->write( &redData[0], 1, iterCols, iterRows, iterLeft, iterTop ) ||
   711            !destProvider->write( &greenData[0], 2, iterCols, iterRows, iterLeft, iterTop ) ||
   712            !destProvider->write( &blueData[0], 3, iterCols, iterRows, iterLeft, iterTop ) ||
   713            !destProvider->write( &alphaData[0], 4, iterCols, iterRows, iterLeft, iterTop ) )
   721   destProvider.reset();
   730     QString vrtFilePath( mOutputUrl + 
'/' + vrtFileName() );
   731     writeVRT( vrtFilePath );
   734       buildPyramids( vrtFilePath );
   741       buildPyramids( mOutputUrl );
   747 void QgsRasterFileWriter::addToVRT( 
const QString &filename, 
int band, 
int xSize, 
int ySize, 
int xOffset, 
int yOffset )
   749   QDomElement bandElem = mVRTBands.value( band - 1 );
   751   QDomElement simpleSourceElem = mVRTDocument.createElement( QStringLiteral( 
"SimpleSource" ) );
   754   QDomElement sourceFilenameElem = mVRTDocument.createElement( QStringLiteral( 
"SourceFilename" ) );
   755   sourceFilenameElem.setAttribute( QStringLiteral( 
"relativeToVRT" ), QStringLiteral( 
"1" ) );
   756   QDomText sourceFilenameText = mVRTDocument.createTextNode( filename );
   757   sourceFilenameElem.appendChild( sourceFilenameText );
   758   simpleSourceElem.appendChild( sourceFilenameElem );
   761   QDomElement sourceBandElem = mVRTDocument.createElement( QStringLiteral( 
"SourceBand" ) );
   762   QDomText sourceBandText = mVRTDocument.createTextNode( QString::number( band ) );
   763   sourceBandElem.appendChild( sourceBandText );
   764   simpleSourceElem.appendChild( sourceBandElem );
   767   QDomElement sourcePropertiesElem = mVRTDocument.createElement( QStringLiteral( 
"SourceProperties" ) );
   768   sourcePropertiesElem.setAttribute( QStringLiteral( 
"RasterXSize" ), xSize );
   769   sourcePropertiesElem.setAttribute( QStringLiteral( 
"RasterYSize" ), ySize );
   770   sourcePropertiesElem.setAttribute( QStringLiteral( 
"BlockXSize" ), xSize );
   771   sourcePropertiesElem.setAttribute( QStringLiteral( 
"BlockYSize" ), ySize );
   772   sourcePropertiesElem.setAttribute( QStringLiteral( 
"DataType" ), QStringLiteral( 
"Byte" ) );
   773   simpleSourceElem.appendChild( sourcePropertiesElem );
   776   QDomElement srcRectElem = mVRTDocument.createElement( QStringLiteral( 
"SrcRect" ) );
   777   srcRectElem.setAttribute( QStringLiteral( 
"xOff" ), QStringLiteral( 
"0" ) );
   778   srcRectElem.setAttribute( QStringLiteral( 
"yOff" ), QStringLiteral( 
"0" ) );
   779   srcRectElem.setAttribute( QStringLiteral( 
"xSize" ), xSize );
   780   srcRectElem.setAttribute( QStringLiteral( 
"ySize" ), ySize );
   781   simpleSourceElem.appendChild( srcRectElem );
   784   QDomElement dstRectElem = mVRTDocument.createElement( QStringLiteral( 
"DstRect" ) );
   785   dstRectElem.setAttribute( QStringLiteral( 
"xOff" ), xOffset );
   786   dstRectElem.setAttribute( QStringLiteral( 
"yOff" ), yOffset );
   787   dstRectElem.setAttribute( QStringLiteral( 
"xSize" ), xSize );
   788   dstRectElem.setAttribute( QStringLiteral( 
"ySize" ), ySize );
   789   simpleSourceElem.appendChild( dstRectElem );
   791   bandElem.appendChild( simpleSourceElem );
   794 void QgsRasterFileWriter::buildPyramids( 
const QString &filename, 
QgsRasterDataProvider *destProviderIn )
   803     if ( !destProvider || !destProvider->
isValid() )
   813   QList< QgsRasterPyramid> myPyramidList;
   814   if ( ! mPyramidsList.isEmpty() )
   816   for ( 
int myCounterInt = 0; myCounterInt < myPyramidList.count(); myCounterInt++ )
   818     myPyramidList[myCounterInt].build = 
true;
   821   QgsDebugMsgLevel( QStringLiteral( 
"building pyramids : %1 pyramids, %2 resampling, %3 format, %4 options" ).arg( myPyramidList.count() ).arg( mPyramidsResampling ).arg( mPyramidsFormat ).arg( mPyramidsConfigOptions.count() ), 4 );
   823   QString res = destProvider->
buildPyramids( myPyramidList, mPyramidsResampling,
   824                 mPyramidsFormat, mPyramidsConfigOptions );
   830     QString title, message;
   831     if ( res == QLatin1String( 
"ERROR_WRITE_ACCESS" ) )
   833       title = QObject::tr( 
"Building Pyramids" );
   834       message = QObject::tr( 
"Write access denied. Adjust the file permissions and try again." );
   836     else if ( res == QLatin1String( 
"ERROR_WRITE_FORMAT" ) )
   838       title = QObject::tr( 
"Building Pyramids" );
   839       message = QObject::tr( 
"The file was not writable. Some formats do not "   840                              "support pyramid overviews. Consult the GDAL documentation if in doubt." );
   842     else if ( res == QLatin1String( 
"FAILED_NOT_SUPPORTED" ) )
   844       title = QObject::tr( 
"Building Pyramids" );
   845       message = QObject::tr( 
"Building pyramid overviews is not supported on this type of raster." );
   847     else if ( res == QLatin1String( 
"ERROR_VIRTUAL" ) )
   849       title = QObject::tr( 
"Building Pyramids" );
   850       message = QObject::tr( 
"Building pyramid overviews is not supported on this type of raster." );
   852     QMessageBox::warning( 
nullptr, title, message );
   855   if ( !destProviderIn )
   860 int QgsRasterFileWriter::pyramidsProgress( 
double dfComplete, 
const char *pszMessage, 
void *pData )
   862   Q_UNUSED( pszMessage )
   863   GDALTermProgress( dfComplete, 0, 0 );
   864   QProgressDialog *progressDialog = 
static_cast<QProgressDialog *
>( pData );
   865   if ( pData && progressDialog->wasCanceled() )
   872     progressDialog->setRange( 0, 100 );
   873     progressDialog->setValue( dfComplete * 100 );
   879 void QgsRasterFileWriter::createVRT( 
int xSize, 
int ySize, 
const QgsCoordinateReferenceSystem &crs, 
double *geoTransform, 
Qgis::DataType type, 
const QList<bool> &destHasNoDataValueList, 
const QList<double> &destNoDataValueList )
   881   mVRTDocument.clear();
   882   QDomElement VRTDatasetElem = mVRTDocument.createElement( QStringLiteral( 
"VRTDataset" ) );
   885   VRTDatasetElem.setAttribute( QStringLiteral( 
"rasterXSize" ), xSize );
   886   VRTDatasetElem.setAttribute( QStringLiteral( 
"rasterYSize" ), ySize );
   887   mVRTDocument.appendChild( VRTDatasetElem );
   890   QDomElement SRSElem = mVRTDocument.createElement( QStringLiteral( 
"SRS" ) );
   891   QDomText crsText = mVRTDocument.createTextNode( crs.
toWkt() );
   892   SRSElem.appendChild( crsText );
   893   VRTDatasetElem.appendChild( SRSElem );
   898     QDomElement geoTransformElem = mVRTDocument.createElement( QStringLiteral( 
"GeoTransform" ) );
   899     QString geoTransformString = QString::number( geoTransform[0], 
'f', 6 ) + 
", " + QString::number( geoTransform[1] ) + 
", " + QString::number( geoTransform[2] ) +
   900                                  ", "  + QString::number( geoTransform[3], 
'f', 6 ) + 
", " + QString::number( geoTransform[4] ) + 
", " + QString::number( geoTransform[5] );
   901     QDomText geoTransformText = mVRTDocument.createTextNode( geoTransformString );
   902     geoTransformElem.appendChild( geoTransformText );
   903     VRTDatasetElem.appendChild( geoTransformElem );
   916   QStringList colorInterp;
   917   colorInterp << QStringLiteral( 
"Red" ) << QStringLiteral( 
"Green" ) << QStringLiteral( 
"Blue" ) << QStringLiteral( 
"Alpha" );
   919   QMap<Qgis::DataType, QString> dataTypes;
   920   dataTypes.insert( 
Qgis::Byte, QStringLiteral( 
"Byte" ) );
   921   dataTypes.insert( 
Qgis::UInt16, QStringLiteral( 
"UInt16" ) );
   922   dataTypes.insert( 
Qgis::Int16, QStringLiteral( 
"Int16" ) );
   923   dataTypes.insert( 
Qgis::UInt32, QStringLiteral( 
"Int32" ) );
   924   dataTypes.insert( 
Qgis::Float32, QStringLiteral( 
"Float32" ) );
   925   dataTypes.insert( 
Qgis::Float64, QStringLiteral( 
"Float64" ) );
   926   dataTypes.insert( 
Qgis::CInt16, QStringLiteral( 
"CInt16" ) );
   927   dataTypes.insert( 
Qgis::CInt32, QStringLiteral( 
"CInt32" ) );
   931   for ( 
int i = 1; i <= nBands; i++ )
   933     QDomElement VRTBand = mVRTDocument.createElement( QStringLiteral( 
"VRTRasterBand" ) );
   935     VRTBand.setAttribute( QStringLiteral( 
"band" ), QString::number( i ) );
   936     QString dataType = dataTypes.value( type );
   937     VRTBand.setAttribute( QStringLiteral( 
"dataType" ), dataType );
   939     if ( mMode == 
Image )
   941       VRTBand.setAttribute( QStringLiteral( 
"dataType" ), QStringLiteral( 
"Byte" ) );
   942       QDomElement colorInterpElement = mVRTDocument.createElement( QStringLiteral( 
"ColorInterp" ) );
   943       QDomText interpText = mVRTDocument.createTextNode( colorInterp.value( i - 1 ) );
   944       colorInterpElement.appendChild( interpText );
   945       VRTBand.appendChild( colorInterpElement );
   948     if ( !destHasNoDataValueList.isEmpty() && destHasNoDataValueList.value( i - 1 ) )
   950       VRTBand.setAttribute( QStringLiteral( 
"NoDataValue" ), QString::number( destNoDataValueList.value( i - 1 ) ) );
   953     mVRTBands.append( VRTBand );
   954     VRTDatasetElem.appendChild( VRTBand );
   958 bool QgsRasterFileWriter::writeVRT( 
const QString &file )
   960   QFile outputFile( file );
   961   if ( ! outputFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
   966   QTextStream outStream( &outputFile );
   967   mVRTDocument.save( outStream, 2 );
   972     int iterRows, 
int iterLeft, 
int iterTop, 
const QString &
outputUrl, 
int fileIndex, 
int nBands, 
Qgis::DataType type,
   975   double mup = extent.
width() / nCols;
   976   double mapLeft = extent.
xMinimum() + iterLeft * mup;
   977   double mapRight = mapLeft + mup * iterCols;
   978   double mapTop = extent.
yMaximum() - iterTop * mup;
   979   double mapBottom = mapTop - iterRows * mup;
   980   QgsRectangle mapRect( mapLeft, mapBottom, mapRight, mapTop );
   982   QString outputFile = 
outputUrl + 
'/' + partFileName( fileIndex );
   985   double geoTransform[6];
   986   geoTransform[0] = mapRect.
xMinimum();
   987   geoTransform[1] = mup;
   988   geoTransform[2] = 0.0;
   989   geoTransform[3] = mapRect.
yMaximum();
   990   geoTransform[4] = 0.0;
   991   geoTransform[5] = -mup;
  1003     const QList<bool> &destHasNoDataValueList, 
const QList<double> &destNoDataValueList )
  1007     createVRT( nCols, nRows, crs, geoTransform, type, destHasNoDataValueList, destNoDataValueList );
  1015     if ( mBuildPyramidsFlag == -4 && mOutputProviderKey == 
"gdal" && mOutputFormat.compare( QLatin1String( 
"gtiff" ), Qt::CaseInsensitive ) == 0 )
  1016       mCreateOptions << 
"COPY_SRC_OVERVIEWS=YES";
  1021     if ( !destProvider )
  1023       QgsDebugMsg( QStringLiteral( 
"No provider created" ) );
  1026     return destProvider;
  1030 void QgsRasterFileWriter::globalOutputParameters( 
const QgsRectangle &extent, 
int nCols, 
int &nRows,
  1031     double *geoTransform, 
double &pixelSize )
  1033   pixelSize = extent.
width() / nCols;
  1038     nRows = 
static_cast< double >( nCols ) / extent.
width() * extent.
height() + 0.5; 
  1040   geoTransform[0] = extent.
xMinimum();
  1041   geoTransform[1] = pixelSize;
  1042   geoTransform[2] = 0.0;
  1043   geoTransform[3] = extent.
yMaximum();
  1044   geoTransform[4] = 0.0;
  1045   geoTransform[5] = -( extent.
height() / nRows );
  1048 QString QgsRasterFileWriter::partFileName( 
int fileIndex )
  1051   QFileInfo outputInfo( mOutputUrl );
  1052   return QStringLiteral( 
"%1.%2.tif" ).arg( outputInfo.fileName() ).arg( fileIndex );
  1055 QString QgsRasterFileWriter::vrtFileName()
  1057   QFileInfo outputInfo( mOutputUrl );
  1058   return QStringLiteral( 
"%1.vrt" ).arg( outputInfo.fileName() );
  1063   QString ext = extension.trimmed();
  1064   if ( ext.isEmpty() )
  1067   if ( ext.startsWith( 
'.' ) )
  1071   int const drvCount = GDALGetDriverCount();
  1073   for ( 
int i = 0; i < drvCount; ++i )
  1075     GDALDriverH drv = GDALGetDriver( i );
  1078       char **driverMetadata = GDALGetMetadata( drv, 
nullptr );
  1079       if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_RASTER, 
false ) )
  1081         QString drvName = GDALGetDriverShortName( drv );
  1082         QStringList driverExtensions = QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS, 
nullptr ) ).split( 
' ' );
  1084         const auto constDriverExtensions = driverExtensions;
  1085         for ( 
const QString &driver : constDriverExtensions )
  1087           if ( driver.compare( ext, Qt::CaseInsensitive ) == 0 )
  1098   GDALDriverH drv = GDALGetDriverByName( format.toLocal8Bit().data() );
  1101     char **driverMetadata = GDALGetMetadata( drv, 
nullptr );
  1102     if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_RASTER, 
false ) )
  1104       return QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS, 
nullptr ) ).split( 
' ' );
  1107   return QStringList();
  1112   GDALDriverH drv = GDALGetDriverByName( driverName.toLocal8Bit().data() );
  1115     QString drvName = GDALGetDriverLongName( drv );
  1116     QString extensionsString = QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS, 
nullptr ) );
  1117     if ( extensionsString.isEmpty() )
  1121     QStringList extensions = extensionsString.split( 
' ' );
  1122     QString filter = drvName + 
" (";
  1123     for ( 
const QString &ext : extensions )
  1125       filter.append( QStringLiteral( 
"*.%1 *.%2 " ).arg( ext.toLower(), ext.toUpper() ) );
  1127     filter = filter.trimmed().append( QStringLiteral( 
")" ) );
  1136   QList< FilterFormatDetails > results;
  1139   int const drvCount = GDALGetDriverCount();
  1143   for ( 
int i = 0; i < drvCount; ++i )
  1145     GDALDriverH drv = GDALGetDriver( i );
  1150         QString drvName = GDALGetDriverShortName( drv );
  1152         if ( filterString.isEmpty() )
  1161           if ( drvName == QLatin1String( 
"GTiff" ) )
  1163             tifFormat = details;
  1182       results.insert( 0, tifFormat );
  1192   QStringList extensions;
  1194   QRegularExpression rx( QStringLiteral( 
"\\*\\.([a-zA-Z0-9]*)" ) );
  1198     QString ext = format.filterString;
  1199     QRegularExpressionMatch match = rx.match( ext );
  1200     if ( !match.hasMatch() )
  1203     QString matched = match.captured( 1 );
  1204     extensions << matched;
 virtual int bandCount() const =0
Gets number of bands. 
 
QgsRasterDataProvider * createOneBandRaster(Qgis::DataType dataType, int width, int height, const QgsRectangle &extent, const QgsCoordinateReferenceSystem &crs)
Create a raster file with one band without initializing the pixel data. 
 
A rectangle specified with double values. 
 
QgsRasterFileWriter(const QString &outputUrl)
 
Base class for processing modules. 
 
Iterator for sequentially processing raster cells. 
 
Writing was manually canceled. 
 
static double minimumValuePossible(Qgis::DataType dataType)
Helper function that returns the minimum possible value for a GDAL data type. 
 
static Qgis::DataType typeWithNoDataValue(Qgis::DataType dataType, double *noDataValue)
For given data type returns wider type and sets no data value. 
 
static bool typeIsColor(Qgis::DataType type)
Returns true if data type is color. 
 
static QString filterForDriver(const QString &driverName)
Creates a filter for an GDAL driver key. 
 
static double maximumValuePossible(Qgis::DataType dataType)
Helper function that returns the maximum possible value for a GDAL data type. 
 
void setProgress(double progress)
Sets the current progress for the feedback object. 
 
QgsRasterProjector * projector() const
 
Raster pipe that deals with null values. 
 
Thirty two bit unsigned integer (quint32) 
 
DataType
Raster data types. 
 
QgsRasterInterface * last() const
 
double maximumValue
The maximum cell value in the raster band. 
 
static QStringList extensionsForFormat(const QString &format)
Returns a list of known file extensions for the given GDAL driver format. 
 
Qgis::DataType sourceDataType(int bandNo) const override=0
Returns source data type for the band specified by number, source data type may be shorter than dataT...
 
virtual bool setNoDataValue(int bandNo, double noDataValue)
Set no data value on created dataset. 
 
virtual Qgis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number. 
 
Thirty two bit floating point (float) 
 
const QgsCoordinateReferenceSystem & crs
 
virtual QString buildPyramids(const QList< QgsRasterPyramid > &pyramidList, const QString &resamplingMethod="NEAREST", QgsRaster::RasterPyramidsFormat format=QgsRaster::PyramidsGTiff, const QStringList &configOptions=QStringList(), QgsRasterBlockFeedback *feedback=nullptr)
Create pyramid overviews. 
 
static bool supportsRasterCreate(GDALDriverH driver)
Reads whether a driver supports GDALCreate() for raster purposes. 
 
Sixteen bit signed integer (qint16) 
 
virtual double sourceNoDataValue(int bandNo) const
Value representing no data value. 
 
Sixty four bit floating point (double) 
 
QgsDataProvider * createProvider(const QString &providerKey, const QString &dataSource, const QgsDataProvider::ProviderOptions &options=QgsDataProvider::ProviderOptions())
Creates a new instance of a provider. 
 
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
 
static QString driverForExtension(const QString &extension)
Returns the GDAL driver name for a specified file extension. 
 
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied. 
 
QgsRasterDataProvider * createMultiBandRaster(Qgis::DataType dataType, int width, int height, const QgsRectangle &extent, const QgsCoordinateReferenceSystem &crs, int nBands)
Create a raster file with given number of bands without initializing the pixel data. 
 
The RasterBandStats struct is a container for statistics about a single raster band. 
 
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance. 
 
static QStringList supportedFormatExtensions(RasterFormatOptions options=SortRecommended)
Returns a list of file extensions for supported formats. 
 
QgsCoordinateReferenceSystem sourceCrs() const
Returns the source CRS. 
 
#define QgsDebugMsgLevel(str, level)
 
virtual QList< QgsRasterPyramid > buildPyramidList(QList< int > overviewList=QList< int >())
Returns the raster layers pyramid list. 
 
QgsRectangle extent() const override=0
Returns the extent of the layer. 
 
virtual bool isValid() const =0
Returns true if this is a valid layer. 
 
void startRasterRead(int bandNumber, qgssize nCols, qgssize nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback=nullptr)
Start reading of raster band. 
 
double width() const
Returns the width of the rectangle. 
 
void appendError(const QString &error)
Appends an error message to the stored list of errors. 
 
static int typeSize(int dataType)
 
Sixteen bit unsigned integer (quint16) 
 
Q_DECL_DEPRECATED WriterError writeRaster(const QgsRasterPipe *pipe, int nCols, int nRows, const QgsRectangle &outputExtent, const QgsCoordinateReferenceSystem &crs, QgsRasterBlockFeedback *feedback=nullptr)
Write raster file. 
 
QgsRasterRangeList noData(int bandNo) const
 
bool readNextRasterPart(int bandNumber, int &nCols, int &nRows, QgsRasterBlock **block, int &topLeftCol, int &topLeftRow)
Fetches next part of raster data, caller takes ownership of the block and caller should delete the bl...
 
Contains information about the context in which a coordinate transform is executed. 
 
Base class for processing filters like renderers, reprojector, resampler etc. 
 
static QList< QgsRasterFileWriter::FilterFormatDetails > supportedFiltersAndFormats(RasterFormatOptions options=SortRecommended)
Returns a list or pairs, with format filter string as first element and GDAL format key as second ele...
 
virtual bool sourceHasNoDataValue(int bandNo) const
Returns true if source band has no data value. 
 
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...
 
void setOutputNoDataValue(int bandNo, double noData)
Sets the output no data value. 
 
double yMinimum() const
Returns the y minimum value (bottom side of rectangle). 
 
double xMaximum() const
Returns the x maximum value (right side of rectangle). 
 
QgsRasterProjector implements approximate projection support for it calculates grid of points in sour...
 
QgsCoordinateTransformContext transformContext() const
Returns data provider coordinate transform context. 
 
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics. 
 
void setMaximumTileWidth(int w)
Sets the maximum tile width returned during iteration. 
 
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination CRS. 
 
Setting options for creating vector data providers. 
 
void setMaximumTileHeight(int h)
Sets the minimum tile height returned during iteration. 
 
Internal error if a value used for 'no data' was found in input. 
 
const QgsRasterInterface * input() const
Returns the input raster interface which is being iterated over. 
 
int maximumTileHeight() const
Returns the minimum tile width returned during iteration. 
 
bool isCanceled() const
Tells whether the operation has been canceled already. 
 
This class represents a coordinate reference system (CRS). 
 
Use recommended sort order, with extremely commonly used formats listed first. 
 
QgsRasterDataProvider * provider() const
 
double xMinimum() const
Returns the x minimum value (left side of rectangle). 
 
double minimumValue
The minimum cell value in the raster band. 
 
QgsRasterNuller * nuller() const
 
double yMaximum() const
Returns the y maximum value (top side of rectangle). 
 
virtual bool write(void *data, int band, int width, int height, int xOffset, int yOffset)
Writes into the provider datasource. 
 
Feedback object tailored for raster block reading. 
 
QString outputUrl() const
Returns the output URL for the raster. 
 
Eight bit unsigned integer (quint8) 
 
Qgis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number. 
 
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32. 
 
virtual const QgsRasterInterface * sourceInput() const
Gets source / raw input, the first in pipe, usually provider. 
 
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS. 
 
int maximumTileWidth() const
Returns the maximum tile width returned during iteration. 
 
double height() const
Returns the height of the rectangle. 
 
Base class for raster data providers. 
 
static QgsRasterDataProvider * create(const QString &providerKey, const QString &uri, const QString &format, int nBands, Qgis::DataType type, int width, int height, double *geoTransform, const QgsCoordinateReferenceSystem &crs, const QStringList &createOptions=QStringList())
Creates a new dataset with mDataSourceURI.