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 )
101 QgsDebugMsgLevel( QStringLiteral(
"reading from %1" ).arg(
typeid( *iface ).name() ), 4 );
105 QgsDebugMsg( QStringLiteral(
"iface->srcInput() == 0" ) );
110 QgsDebugMsgLevel( QStringLiteral(
"srcInput = %1" ).arg(
typeid( srcInput ).name() ), 4 );
113 mFeedback = feedback;
120 QFileInfo fileInfo( mOutputUrl );
121 if ( !fileInfo.exists() )
123 QDir dir = fileInfo.dir();
124 if ( !dir.mkdir( fileInfo.fileName() ) )
126 QgsDebugMsg(
"Cannot create output VRT directory " + fileInfo.fileName() +
" in " + dir.absolutePath() );
133 QFile pyramidFile( mOutputUrl + ( mTiledMode ?
".vrt.ovr" :
".ovr" ) );
134 if ( pyramidFile.exists() )
135 pyramidFile.remove();
136 pyramidFile.setFileName( mOutputUrl + ( mTiledMode ?
".vrt.rrd" :
".rrd" ) );
137 if ( pyramidFile.exists() )
138 pyramidFile.remove();
140 if ( mMode ==
Image )
142 WriterError e = writeImageRaster( &iter, nCols, nRows, outputExtent, crs, feedback );
147 WriterError e = writeDataRaster( pipe, &iter, nCols, nRows, outputExtent, crs, feedback );
170 QgsDebugMsg( QStringLiteral(
"Cannot get source data provider" ) );
187 for (
int i = 2; i <= nBands; ++i )
199 QList<bool> destHasNoDataValueList;
200 QList<double> destNoDataValueList;
201 QList<Qgis::DataType> destDataTypeList;
202 destDataTypeList.reserve( nBands );
203 destHasNoDataValueList.reserve( nBands );
204 destNoDataValueList.reserve( nBands );
206 const bool isGpkgOutput = mOutputProviderKey ==
"gdal" &&
207 mOutputFormat.compare( QLatin1String(
"gpkg" ), Qt::CaseInsensitive ) == 0;
209 double geoTransform[6];
210 globalOutputParameters( outputExtent, nCols, nRows, geoTransform, pixelSize );
211 const auto srcProviderExtent( srcProvider->
extent() );
213 for (
int bandNo = 1; bandNo <= nBands; bandNo++ )
218 bool destHasNoDataValue =
false;
219 double destNoDataValue = std::numeric_limits<double>::quiet_NaN();
224 if ( srcHasNoDataValue )
229 destHasNoDataValue =
true;
231 else if ( nuller && !nuller->
noData( bandNo ).isEmpty() )
234 destNoDataValue = nuller->
noData( bandNo ).value( 0 ).min();
235 destHasNoDataValue =
true;
240 else if ( !( isGpkgOutput && destDataType ==
Qgis::Byte ) )
250 outputExtentInSrcCrs = ct.transformBoundingBox( outputExtent );
252 if ( !srcProviderExtent.contains( outputExtentInSrcCrs ) &&
253 ( std::fabs( srcProviderExtent.xMinimum() - outputExtentInSrcCrs.
xMinimum() ) > geoTransform[1] / 2 ||
254 std::fabs( srcProviderExtent.xMaximum() - outputExtentInSrcCrs.
xMaximum() ) > geoTransform[1] / 2 ||
255 std::fabs( srcProviderExtent.yMinimum() - outputExtentInSrcCrs.
yMinimum() ) > std::fabs( geoTransform[5] ) / 2 ||
256 std::fabs( srcProviderExtent.yMaximum() - outputExtentInSrcCrs.
yMaximum() ) > std::fabs( geoTransform[5] ) / 2 ) )
267 destNoDataValue = typeMinValue;
271 destNoDataValue = typeMaxValue;
278 destHasNoDataValue =
true;
282 if ( nuller && destHasNoDataValue )
287 QgsDebugMsgLevel( QStringLiteral(
"bandNo = %1 destDataType = %2 destHasNoDataValue = %3 destNoDataValue = %4" ).arg( bandNo ).arg( destDataType ).arg( destHasNoDataValue ).arg( destNoDataValue ), 4 );
288 destDataTypeList.append( destDataType );
289 destHasNoDataValueList.append( destHasNoDataValue );
290 destNoDataValueList.append( destNoDataValue );
295 for (
int i = 1; i < nBands; i++ )
297 if ( destDataTypeList.value( i ) > destDataType )
299 destDataType = destDataTypeList.value( i );
305 for (
int attempt = 0; attempt < 2; attempt ++ )
309 std::unique_ptr<QgsRasterDataProvider> destProvider(
310 initOutput( nCols, nRows, crs, geoTransform, nBands, destDataType, destHasNoDataValueList, destNoDataValueList ) );
317 if ( !destProvider->isValid() )
321 if ( nCols != destProvider->xSize() || nRows != destProvider->ySize() )
323 QgsDebugMsg( QStringLiteral(
"Created raster does not have requested dimensions" ) );
326 if ( nBands != destProvider->bandCount() )
328 QgsDebugMsg( QStringLiteral(
"Created raster does not have requested band count" ) );
335 destDataType = destProvider->dataType( 1 );
339 error = writeDataRaster( pipe, iter, nCols, nRows, outputExtent, crs, destDataType, destHasNoDataValueList, destNoDataValueList, destProvider.get(), feedback );
346 destProvider->remove();
347 destProvider.reset();
355 for (
int i = 0; i < nBands; i++ )
357 double destNoDataValue;
359 destDataTypeList.replace( i, destDataType );
360 destNoDataValueList.replace( i, destNoDataValue );
362 destDataType = destDataTypeList.value( 0 );
375 static int qgsDivRoundUp(
int a,
int b )
377 return a / b + ( ( ( a % b ) != 0 ) ? 1 : 0 );
382 int nCols,
int nRows,
386 const QList<bool> &destHasNoDataValueList,
387 const QList<double> &destNoDataValueList,
392 Q_UNUSED( destHasNoDataValueList );
406 std::vector< std::unique_ptr<QgsRasterBlock> > blockList;
407 std::vector< std::unique_ptr<QgsRasterBlock> > destBlockList;
409 blockList.resize( nBands );
410 destBlockList.resize( nBands );
412 for (
int i = 1; i <= nBands; ++i )
415 if ( destProvider && destHasNoDataValueList.value( i - 1 ) )
417 destProvider->
setNoDataValue( i, destNoDataValueList.value( i - 1 ) );
427 nParts = nPartsX * nPartsY;
434 for (
int i = 1; i <= nBands; ++i )
442 QString vrtFilePath( mOutputUrl +
'/' + vrtFileName() );
443 writeVRT( vrtFilePath );
446 buildPyramids( vrtFilePath );
453 buildPyramids( mOutputUrl, destProvider );
460 blockList[i - 1].reset( block );
464 if ( feedback && fileIndex < ( nParts - 1 ) )
466 feedback->
setProgress( 100.0 * fileIndex / static_cast< double >( nParts ) );
474 for (
int i = 1; i <= nBands; ++i )
476 if ( srcProvider && srcProvider->
dataType( i ) == destDataType )
483 blockList[i - 1]->convert( destDataType );
485 destBlockList[i - 1] = std::move( blockList[i - 1] );
490 std::unique_ptr< QgsRasterDataProvider > partDestProvider( createPartProvider( outputExtent,
491 nCols, iterCols, iterRows,
492 iterLeft, iterTop, mOutputUrl,
493 fileIndex, nBands, destDataType, crs ) );
495 if ( !partDestProvider || !partDestProvider->isValid() )
501 for (
int i = 1; i <= nBands; ++i )
503 if ( destHasNoDataValueList.value( i - 1 ) )
505 partDestProvider->setNoDataValue( i, destNoDataValueList.value( i - 1 ) );
507 if ( !partDestProvider->write( destBlockList[i - 1]->bits( 0 ), i, iterCols, iterRows, 0, 0 ) )
511 addToVRT( partFileName( fileIndex ), i, iterCols, iterRows, iterLeft, iterTop );
515 else if ( destProvider )
518 for (
int i = 1; i <= nBands; ++i )
520 if ( !destProvider->
write( destBlockList[i - 1]->bits( 0 ), i, iterCols, iterRows, iterLeft, iterTop ) )
556 const size_t nMaxPixels =
static_cast<size_t>( mMaxTileWidth ) * mMaxTileHeight;
557 std::vector<unsigned char> redData( nMaxPixels );
558 std::vector<unsigned char> greenData( nMaxPixels );
559 std::vector<unsigned char> blueData( nMaxPixels );
560 std::vector<unsigned char> alphaData( nMaxPixels );
562 int iterLeft = 0, iterTop = 0, iterCols = 0, iterRows = 0;
567 double geoTransform[6];
568 globalOutputParameters( outputExtent, nCols, nRows, geoTransform, pixelSize );
570 const int nOutputBands = 4;
571 std::unique_ptr< QgsRasterDataProvider > destProvider( initOutput( nCols, nRows, crs, geoTransform, nOutputBands,
Qgis::Byte ) );
578 if ( !destProvider->isValid() )
582 if ( nCols != destProvider->xSize() || nRows != destProvider->ySize() )
584 QgsDebugMsg( QStringLiteral(
"Created raster does not have requested dimensions" ) );
587 if ( nOutputBands != destProvider->bandCount() )
589 QgsDebugMsg( QStringLiteral(
"Created raster does not have requested band count" ) );
592 if (
Qgis::Byte != destProvider->dataType( 1 ) )
594 QgsDebugMsg( QStringLiteral(
"Created raster does not have requested data type" ) );
606 nParts = nPartsX * nPartsY;
609 std::unique_ptr< QgsRasterBlock > inputBlock;
610 while ( iter->
readNextRasterPart( 1, iterCols, iterRows, inputBlock, iterLeft, iterTop ) )
617 if ( feedback && fileIndex < ( nParts - 1 ) )
619 feedback->
setProgress( 100.0 * fileIndex / static_cast< double >( nParts ) );
628 for (
qgssize i = 0; i < nPixels; ++i )
630 QRgb
c = inputBlock->color( i );
631 if ( isPremultiplied )
633 c = qUnpremultiply( c );
635 redData[i] =
static_cast<unsigned char>( qRed( c ) );
636 greenData[i] =
static_cast<unsigned char>( qGreen( c ) );
637 blueData[i] =
static_cast<unsigned char>( qBlue( c ) );
638 alphaData[i] =
static_cast<unsigned char>( qAlpha( c ) );
644 std::unique_ptr< QgsRasterDataProvider > partDestProvider( createPartProvider( outputExtent,
645 nCols, iterCols, iterRows,
646 iterLeft, iterTop, mOutputUrl, fileIndex,
649 if ( !partDestProvider || partDestProvider->isValid() )
655 if ( !partDestProvider->write( &redData[0], 1, iterCols, iterRows, 0, 0 ) ||
656 !partDestProvider->write( &greenData[0], 2, iterCols, iterRows, 0, 0 ) ||
657 !partDestProvider->write( &blueData[0], 3, iterCols, iterRows, 0, 0 ) ||
658 !partDestProvider->write( &alphaData[0], 4, iterCols, iterRows, 0, 0 ) )
663 addToVRT( partFileName( fileIndex ), 1, iterCols, iterRows, iterLeft, iterTop );
664 addToVRT( partFileName( fileIndex ), 2, iterCols, iterRows, iterLeft, iterTop );
665 addToVRT( partFileName( fileIndex ), 3, iterCols, iterRows, iterLeft, iterTop );
666 addToVRT( partFileName( fileIndex ), 4, iterCols, iterRows, iterLeft, iterTop );
668 else if ( destProvider )
670 if ( !destProvider->write( &redData[0], 1, iterCols, iterRows, iterLeft, iterTop ) ||
671 !destProvider->write( &greenData[0], 2, iterCols, iterRows, iterLeft, iterTop ) ||
672 !destProvider->write( &blueData[0], 3, iterCols, iterRows, iterLeft, iterTop ) ||
673 !destProvider->write( &alphaData[0], 4, iterCols, iterRows, iterLeft, iterTop ) )
681 destProvider.reset();
690 QString vrtFilePath( mOutputUrl +
'/' + vrtFileName() );
691 writeVRT( vrtFilePath );
694 buildPyramids( vrtFilePath );
701 buildPyramids( mOutputUrl );
707 void QgsRasterFileWriter::addToVRT(
const QString &filename,
int band,
int xSize,
int ySize,
int xOffset,
int yOffset )
709 QDomElement bandElem = mVRTBands.value( band - 1 );
711 QDomElement simpleSourceElem = mVRTDocument.createElement( QStringLiteral(
"SimpleSource" ) );
714 QDomElement sourceFilenameElem = mVRTDocument.createElement( QStringLiteral(
"SourceFilename" ) );
715 sourceFilenameElem.setAttribute( QStringLiteral(
"relativeToVRT" ), QStringLiteral(
"1" ) );
716 QDomText sourceFilenameText = mVRTDocument.createTextNode( filename );
717 sourceFilenameElem.appendChild( sourceFilenameText );
718 simpleSourceElem.appendChild( sourceFilenameElem );
721 QDomElement sourceBandElem = mVRTDocument.createElement( QStringLiteral(
"SourceBand" ) );
722 QDomText sourceBandText = mVRTDocument.createTextNode( QString::number( band ) );
723 sourceBandElem.appendChild( sourceBandText );
724 simpleSourceElem.appendChild( sourceBandElem );
727 QDomElement sourcePropertiesElem = mVRTDocument.createElement( QStringLiteral(
"SourceProperties" ) );
728 sourcePropertiesElem.setAttribute( QStringLiteral(
"RasterXSize" ), xSize );
729 sourcePropertiesElem.setAttribute( QStringLiteral(
"RasterYSize" ), ySize );
730 sourcePropertiesElem.setAttribute( QStringLiteral(
"BlockXSize" ), xSize );
731 sourcePropertiesElem.setAttribute( QStringLiteral(
"BlockYSize" ), ySize );
732 sourcePropertiesElem.setAttribute( QStringLiteral(
"DataType" ), QStringLiteral(
"Byte" ) );
733 simpleSourceElem.appendChild( sourcePropertiesElem );
736 QDomElement srcRectElem = mVRTDocument.createElement( QStringLiteral(
"SrcRect" ) );
737 srcRectElem.setAttribute( QStringLiteral(
"xOff" ), QStringLiteral(
"0" ) );
738 srcRectElem.setAttribute( QStringLiteral(
"yOff" ), QStringLiteral(
"0" ) );
739 srcRectElem.setAttribute( QStringLiteral(
"xSize" ), xSize );
740 srcRectElem.setAttribute( QStringLiteral(
"ySize" ), ySize );
741 simpleSourceElem.appendChild( srcRectElem );
744 QDomElement dstRectElem = mVRTDocument.createElement( QStringLiteral(
"DstRect" ) );
745 dstRectElem.setAttribute( QStringLiteral(
"xOff" ), xOffset );
746 dstRectElem.setAttribute( QStringLiteral(
"yOff" ), yOffset );
747 dstRectElem.setAttribute( QStringLiteral(
"xSize" ), xSize );
748 dstRectElem.setAttribute( QStringLiteral(
"ySize" ), ySize );
749 simpleSourceElem.appendChild( dstRectElem );
751 bandElem.appendChild( simpleSourceElem );
754 void QgsRasterFileWriter::buildPyramids(
const QString &filename,
QgsRasterDataProvider *destProviderIn )
763 if ( !destProvider || !destProvider->
isValid() )
773 QList< QgsRasterPyramid> myPyramidList;
774 if ( ! mPyramidsList.isEmpty() )
776 for (
int myCounterInt = 0; myCounterInt < myPyramidList.count(); myCounterInt++ )
778 myPyramidList[myCounterInt].build =
true;
781 QgsDebugMsgLevel( QStringLiteral(
"building pyramids : %1 pyramids, %2 resampling, %3 format, %4 options" ).arg( myPyramidList.count() ).arg( mPyramidsResampling ).arg( mPyramidsFormat ).arg( mPyramidsConfigOptions.count() ), 4 );
783 QString res = destProvider->
buildPyramids( myPyramidList, mPyramidsResampling,
784 mPyramidsFormat, mPyramidsConfigOptions );
790 QString title, message;
791 if ( res == QLatin1String(
"ERROR_WRITE_ACCESS" ) )
793 title = QObject::tr(
"Building Pyramids" );
794 message = QObject::tr(
"Write access denied. Adjust the file permissions and try again." );
796 else if ( res == QLatin1String(
"ERROR_WRITE_FORMAT" ) )
798 title = QObject::tr(
"Building Pyramids" );
799 message = QObject::tr(
"The file was not writable. Some formats do not " 800 "support pyramid overviews. Consult the GDAL documentation if in doubt." );
802 else if ( res == QLatin1String(
"FAILED_NOT_SUPPORTED" ) )
804 title = QObject::tr(
"Building Pyramids" );
805 message = QObject::tr(
"Building pyramid overviews is not supported on this type of raster." );
807 else if ( res == QLatin1String(
"ERROR_VIRTUAL" ) )
809 title = QObject::tr(
"Building Pyramids" );
810 message = QObject::tr(
"Building pyramid overviews is not supported on this type of raster." );
812 QMessageBox::warning(
nullptr, title, message );
815 if ( !destProviderIn )
820 int QgsRasterFileWriter::pyramidsProgress(
double dfComplete,
const char *pszMessage,
void *pData )
822 Q_UNUSED( pszMessage );
823 GDALTermProgress( dfComplete, 0, 0 );
824 QProgressDialog *progressDialog =
static_cast<QProgressDialog *
>( pData );
825 if ( pData && progressDialog->wasCanceled() )
832 progressDialog->setRange( 0, 100 );
833 progressDialog->setValue( dfComplete * 100 );
839 void QgsRasterFileWriter::createVRT(
int xSize,
int ySize,
const QgsCoordinateReferenceSystem &crs,
double *geoTransform,
Qgis::DataType type,
const QList<bool> &destHasNoDataValueList,
const QList<double> &destNoDataValueList )
841 mVRTDocument.clear();
842 QDomElement VRTDatasetElem = mVRTDocument.createElement( QStringLiteral(
"VRTDataset" ) );
845 VRTDatasetElem.setAttribute( QStringLiteral(
"rasterXSize" ), xSize );
846 VRTDatasetElem.setAttribute( QStringLiteral(
"rasterYSize" ), ySize );
847 mVRTDocument.appendChild( VRTDatasetElem );
850 QDomElement SRSElem = mVRTDocument.createElement( QStringLiteral(
"SRS" ) );
851 QDomText crsText = mVRTDocument.createTextNode( crs.
toWkt() );
852 SRSElem.appendChild( crsText );
853 VRTDatasetElem.appendChild( SRSElem );
858 QDomElement geoTransformElem = mVRTDocument.createElement( QStringLiteral(
"GeoTransform" ) );
859 QString geoTransformString = QString::number( geoTransform[0],
'f', 6 ) +
", " + QString::number( geoTransform[1] ) +
", " + QString::number( geoTransform[2] ) +
860 ", " + QString::number( geoTransform[3],
'f', 6 ) +
", " + QString::number( geoTransform[4] ) +
", " + QString::number( geoTransform[5] );
861 QDomText geoTransformText = mVRTDocument.createTextNode( geoTransformString );
862 geoTransformElem.appendChild( geoTransformText );
863 VRTDatasetElem.appendChild( geoTransformElem );
876 QStringList colorInterp;
877 colorInterp << QStringLiteral(
"Red" ) << QStringLiteral(
"Green" ) << QStringLiteral(
"Blue" ) << QStringLiteral(
"Alpha" );
879 QMap<Qgis::DataType, QString> dataTypes;
880 dataTypes.insert(
Qgis::Byte, QStringLiteral(
"Byte" ) );
881 dataTypes.insert(
Qgis::UInt16, QStringLiteral(
"UInt16" ) );
882 dataTypes.insert(
Qgis::Int16, QStringLiteral(
"Int16" ) );
883 dataTypes.insert(
Qgis::UInt32, QStringLiteral(
"Int32" ) );
884 dataTypes.insert(
Qgis::Float32, QStringLiteral(
"Float32" ) );
885 dataTypes.insert(
Qgis::Float64, QStringLiteral(
"Float64" ) );
886 dataTypes.insert(
Qgis::CInt16, QStringLiteral(
"CInt16" ) );
887 dataTypes.insert(
Qgis::CInt32, QStringLiteral(
"CInt32" ) );
891 for (
int i = 1; i <= nBands; i++ )
893 QDomElement VRTBand = mVRTDocument.createElement( QStringLiteral(
"VRTRasterBand" ) );
895 VRTBand.setAttribute( QStringLiteral(
"band" ), QString::number( i ) );
896 QString dataType = dataTypes.value( type );
897 VRTBand.setAttribute( QStringLiteral(
"dataType" ), dataType );
899 if ( mMode ==
Image )
901 VRTBand.setAttribute( QStringLiteral(
"dataType" ), QStringLiteral(
"Byte" ) );
902 QDomElement colorInterpElement = mVRTDocument.createElement( QStringLiteral(
"ColorInterp" ) );
903 QDomText interpText = mVRTDocument.createTextNode( colorInterp.value( i - 1 ) );
904 colorInterpElement.appendChild( interpText );
905 VRTBand.appendChild( colorInterpElement );
908 if ( !destHasNoDataValueList.isEmpty() && destHasNoDataValueList.value( i - 1 ) )
910 VRTBand.setAttribute( QStringLiteral(
"NoDataValue" ), QString::number( destNoDataValueList.value( i - 1 ) ) );
913 mVRTBands.append( VRTBand );
914 VRTDatasetElem.appendChild( VRTBand );
918 bool QgsRasterFileWriter::writeVRT(
const QString &file )
920 QFile outputFile( file );
921 if ( ! outputFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
926 QTextStream outStream( &outputFile );
927 mVRTDocument.save( outStream, 2 );
932 int iterRows,
int iterLeft,
int iterTop,
const QString &
outputUrl,
int fileIndex,
int nBands,
Qgis::DataType type,
935 double mup = extent.
width() / nCols;
936 double mapLeft = extent.
xMinimum() + iterLeft * mup;
937 double mapRight = mapLeft + mup * iterCols;
938 double mapTop = extent.
yMaximum() - iterTop * mup;
939 double mapBottom = mapTop - iterRows * mup;
940 QgsRectangle mapRect( mapLeft, mapBottom, mapRight, mapTop );
942 QString outputFile =
outputUrl +
'/' + partFileName( fileIndex );
945 double geoTransform[6];
946 geoTransform[0] = mapRect.
xMinimum();
947 geoTransform[1] = mup;
948 geoTransform[2] = 0.0;
949 geoTransform[3] = mapRect.
yMaximum();
950 geoTransform[4] = 0.0;
951 geoTransform[5] = -mup;
963 const QList<bool> &destHasNoDataValueList,
const QList<double> &destNoDataValueList )
967 createVRT( nCols, nRows, crs, geoTransform, type, destHasNoDataValueList, destNoDataValueList );
975 if ( mBuildPyramidsFlag == -4 && mOutputProviderKey ==
"gdal" && mOutputFormat.compare( QLatin1String(
"gtiff" ), Qt::CaseInsensitive ) == 0 )
976 mCreateOptions <<
"COPY_SRC_OVERVIEWS=YES";
983 QgsDebugMsg( QStringLiteral(
"No provider created" ) );
990 void QgsRasterFileWriter::globalOutputParameters(
const QgsRectangle &extent,
int nCols,
int &nRows,
991 double *geoTransform,
double &pixelSize )
993 pixelSize = extent.
width() / nCols;
998 nRows =
static_cast< double >( nCols ) / extent.
width() * extent.
height() + 0.5;
1000 geoTransform[0] = extent.
xMinimum();
1001 geoTransform[1] = pixelSize;
1002 geoTransform[2] = 0.0;
1003 geoTransform[3] = extent.
yMaximum();
1004 geoTransform[4] = 0.0;
1005 geoTransform[5] = -( extent.
height() / nRows );
1008 QString QgsRasterFileWriter::partFileName(
int fileIndex )
1011 QFileInfo outputInfo( mOutputUrl );
1012 return QStringLiteral(
"%1.%2.tif" ).arg( outputInfo.fileName() ).arg( fileIndex );
1015 QString QgsRasterFileWriter::vrtFileName()
1017 QFileInfo outputInfo( mOutputUrl );
1018 return QStringLiteral(
"%1.vrt" ).arg( outputInfo.fileName() );
1023 QString ext = extension.trimmed();
1024 if ( ext.isEmpty() )
1027 if ( ext.startsWith(
'.' ) )
1031 int const drvCount = GDALGetDriverCount();
1033 for (
int i = 0; i < drvCount; ++i )
1035 GDALDriverH drv = GDALGetDriver( i );
1038 char **driverMetadata = GDALGetMetadata( drv,
nullptr );
1039 if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_RASTER,
false ) )
1041 QString drvName = GDALGetDriverShortName( drv );
1042 QStringList driverExtensions = QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS,
nullptr ) ).split(
' ' );
1044 Q_FOREACH (
const QString &driver, driverExtensions )
1046 if ( driver.compare( ext, Qt::CaseInsensitive ) == 0 )
1057 GDALDriverH drv = GDALGetDriverByName( format.toLocal8Bit().data() );
1060 char **driverMetadata = GDALGetMetadata( drv,
nullptr );
1061 if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_RASTER,
false ) )
1063 return QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS,
nullptr ) ).split(
' ' );
1066 return QStringList();
1071 GDALDriverH drv = GDALGetDriverByName( driverName.toLocal8Bit().data() );
1074 QString drvName = GDALGetDriverLongName( drv );
1075 QString extensionsString = QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS,
nullptr ) );
1076 if ( extensionsString.isEmpty() )
1080 QStringList extensions = extensionsString.split(
' ' );
1081 QString filter = drvName +
" (";
1082 for (
const QString &ext : extensions )
1084 filter.append( QStringLiteral(
"*.%1 *.%2 " ).arg( ext.toLower(), ext.toUpper() ) );
1086 filter = filter.trimmed().append( QStringLiteral(
")" ) );
1095 QList< FilterFormatDetails > results;
1098 int const drvCount = GDALGetDriverCount();
1102 for (
int i = 0; i < drvCount; ++i )
1104 GDALDriverH drv = GDALGetDriver( i );
1109 QString drvName = GDALGetDriverShortName( drv );
1111 if ( filterString.isEmpty() )
1120 if ( drvName == QLatin1String(
"GTiff" ) )
1122 tifFormat = details;
1141 results.insert( 0, tifFormat );
1151 QStringList extensions;
1153 QRegularExpression rx( QStringLiteral(
"\\*\\.([a-zA-Z0-9]*)" ) );
1157 QString ext = format.filterString;
1158 QRegularExpressionMatch match = rx.match( ext );
1159 if ( !match.hasMatch() )
1162 QString matched = match.captured( 1 );
1163 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.
bool isCanceled() const
Tells whether the operation has been canceled already.
A rectangle specified with double values.
QgsCoordinateReferenceSystem sourceCrs() const
Returns the source CRS.
QgsRasterFileWriter(const QString &outputUrl)
Base class for processing modules.
QgsRasterNuller * nuller() const
Iterator for sequentially processing raster cells.
Writing was manually canceled.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination CRS.
static double minimumValuePossible(Qgis::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.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
static QString filterForDriver(const QString &driverName)
Creates a filter for an GDAL driver key.
void setProgress(double progress)
Sets the current progress for the feedback object.
Raster pipe that deals with null values.
QString toWkt() const
Returns a WKT representation of this CRS.
Thirty two bit unsigned integer (quint32)
#define Q_NOWARN_DEPRECATED_PUSH
DataType
Raster data types.
double maximumValue
The maximum cell value in the raster band.
QgsRasterInterface * last() const
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)
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.
virtual bool sourceHasNoDataValue(int bandNo) const
Returns true if source band has no data value.
QString outputUrl() const
Returns the output URL for the raster.
int maximumTileWidth() const
Returns the maximum tile width returned during iteration.
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.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double xMaximum() const
Returns the x maximum value (right side of rectangle).
#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.
int maximumTileHeight() const
Returns the minimum tile width returned during iteration.
static int typeSize(int dataType)
Sixteen bit unsigned integer (quint16)
QgsRasterProjector * projector() const
WriterError writeRaster(const QgsRasterPipe *pipe, int nCols, int nRows, const QgsRectangle &outputExtent, const QgsCoordinateReferenceSystem &crs, QgsRasterBlockFeedback *feedback=nullptr)
Write raster file.
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...
Base class for processing filters like renderers, reprojector, resampler etc.
virtual double sourceNoDataValue(int bandNo) const
Value representing no data value.
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...
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.
QgsRasterProjector implements approximate projection support for it calculates grid of points in sour...
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
#define Q_NOWARN_DEPRECATED_POP
void setMaximumTileWidth(int w)
Sets the maximum tile width returned during iteration.
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.
static double maximumValuePossible(Qgis::DataType)
Helper function that returns the maximum possible value for a GDAL data type.
QgsRasterRangeList noData(int bandNo) const
This class represents a coordinate reference system (CRS).
Use recommended sort order, with extremely commonly used formats listed first.
double minimumValue
The minimum cell value in the raster band.
virtual bool write(void *data, int band, int width, int height, int xOffset, int yOffset)
Writes into the provider datasource.
virtual const QgsRasterInterface * sourceInput() const
Gets source / raw input, the first in pipe, usually provider.
double width() const
Returns the width of the rectangle.
Feedback object tailored for raster block reading.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
void startRasterRead(int bandNumber, int nCols, int nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback=nullptr)
Start reading of raster band.
Eight bit unsigned integer (quint8)
const QgsRasterInterface * input() const
Returns the input raster interface which is being iterated over.
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.
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.