27 #include <QCoreApplication> 28 #include <QProgressDialog> 29 #include <QTextStream> 30 #include <QMessageBox> 33 #include <cpl_string.h> 41 double geoTransform[6];
42 globalOutputParameters( extent, width, height, geoTransform, pixelSize );
44 return initOutput( width, height, crs, geoTransform, 1, dataType, QList<bool>(), QList<double>() );
53 double geoTransform[6];
54 globalOutputParameters( extent, width, height, geoTransform, pixelSize );
56 return initOutput( width, height, crs, geoTransform, nBands, dataType, QList<bool>(), QList<double>() );
60 : mOutputUrl( outputUrl )
61 , mOutputProviderKey( QStringLiteral(
"gdal" ) )
62 , mOutputFormat( QStringLiteral(
"GTiff" ) )
68 : mOutputProviderKey( QStringLiteral(
"gdal" ) )
69 , mOutputFormat( QStringLiteral(
"GTiff" ) )
102 QgsDebugMsgLevel( QString(
"reading from %1" ).arg(
typeid( *iface ).name() ), 4 );
111 QgsDebugMsgLevel( QString(
"srcInput = %1" ).arg(
typeid( srcInput ).name() ), 4 );
114 mFeedback = feedback;
121 QFileInfo fileInfo( mOutputUrl );
122 if ( !fileInfo.exists() )
124 QDir dir = fileInfo.dir();
125 if ( !dir.mkdir( fileInfo.fileName() ) )
127 QgsDebugMsg(
"Cannot create output VRT directory " + fileInfo.fileName() +
" in " + dir.absolutePath() );
133 if ( mMode ==
Image )
135 WriterError e = writeImageRaster( &iter, nCols, nRows, outputExtent, crs, feedback );
140 WriterError e = writeDataRaster( pipe, &iter, nCols, nRows, outputExtent, crs, feedback );
180 for (
int i = 2; i <= nBands; ++i )
192 QList<bool> destHasNoDataValueList;
193 QList<double> destNoDataValueList;
194 QList<Qgis::DataType> destDataTypeList;
195 destDataTypeList.reserve( nBands );
196 destHasNoDataValueList.reserve( nBands );
197 destNoDataValueList.reserve( nBands );
199 for (
int bandNo = 1; bandNo <= nBands; bandNo++ )
204 bool destHasNoDataValue =
false;
205 double destNoDataValue = std::numeric_limits<double>::quiet_NaN();
209 if ( srcHasNoDataValue )
214 destHasNoDataValue =
true;
216 else if ( nuller && !nuller->
noData( bandNo ).isEmpty() )
219 destNoDataValue = nuller->
noData( bandNo ).value( 0 ).min();
220 destHasNoDataValue =
true;
232 srcExtent = ct.transformBoundingBox( outputExtent );
245 destNoDataValue = typeMinValue;
249 destNoDataValue = typeMaxValue;
256 destHasNoDataValue =
true;
260 if ( nuller && destHasNoDataValue )
265 QgsDebugMsgLevel( QString(
"bandNo = %1 destDataType = %2 destHasNoDataValue = %3 destNoDataValue = %4" ).arg( bandNo ).arg( destDataType ).arg( destHasNoDataValue ).arg( destNoDataValue ), 4 );
266 destDataTypeList.append( destDataType );
267 destHasNoDataValueList.append( destHasNoDataValue );
268 destNoDataValueList.append( destNoDataValue );
273 for (
int i = 1; i < nBands; i++ )
275 if ( destDataTypeList.value( i ) > destDataType )
277 destDataType = destDataTypeList.value( i );
285 double geoTransform[6];
286 globalOutputParameters( outputExtent, nCols, nRows, geoTransform, pixelSize );
289 destProvider = initOutput( nCols, nRows, crs, geoTransform, nBands, destDataType, destHasNoDataValueList, destNoDataValueList );
291 WriterError error = writeDataRaster( pipe, iter, nCols, nRows, outputExtent, crs, destDataType, destHasNoDataValueList, destNoDataValueList, destProvider, feedback );
300 destProvider =
nullptr;
308 for (
int i = 0; i < nBands; i++ )
310 double destNoDataValue;
312 destDataTypeList.replace( i, destDataType );
313 destNoDataValueList.replace( i, destNoDataValue );
315 destDataType = destDataTypeList.value( 0 );
318 destProvider = initOutput( nCols, nRows, crs, geoTransform, nBands, destDataType, destHasNoDataValueList, destNoDataValueList );
319 error = writeDataRaster( pipe, iter, nCols, nRows, outputExtent, crs, destDataType, destHasNoDataValueList, destNoDataValueList, destProvider, feedback );
328 int nCols,
int nRows,
332 const QList<bool> &destHasNoDataValueList,
333 const QList<double> &destNoDataValueList,
338 Q_UNUSED( destHasNoDataValueList );
352 QList<QgsRasterBlock *> blockList;
353 blockList.reserve( nBands );
354 for (
int i = 1; i <= nBands; ++i )
357 blockList.push_back(
nullptr );
358 if ( destProvider && destHasNoDataValueList.value( i - 1 ) )
360 destProvider->
setNoDataValue( i, destNoDataValueList.value( i - 1 ) );
370 nParts = nPartsX * nPartsY;
377 for (
int i = 1; i <= nBands; ++i )
379 if ( !iter->
readNextRasterPart( i, iterCols, iterRows, &( blockList[i - 1] ), iterLeft, iterTop ) )
384 QString vrtFilePath( mOutputUrl +
'/' + vrtFileName() );
385 writeVRT( vrtFilePath );
388 buildPyramids( vrtFilePath );
395 buildPyramids( mOutputUrl );
405 if ( feedback && fileIndex < ( nParts - 1 ) )
407 feedback->
setProgress( 100.0 * fileIndex / static_cast< double >( nParts ) );
410 for (
int i = 0; i < nBands; ++i )
419 QList<QgsRasterBlock *> destBlockList;
420 for (
int i = 1; i <= nBands; ++i )
422 if ( srcProvider && srcProvider->
dataType( i ) == destDataType )
424 destBlockList.push_back( blockList[i - 1] );
429 blockList[i - 1]->convert( destDataType );
430 destBlockList.push_back( blockList[i - 1] );
432 blockList[i - 1] =
nullptr;
438 nCols, iterCols, iterRows,
439 iterLeft, iterTop, mOutputUrl,
440 fileIndex, nBands, destDataType, crs );
442 if ( partDestProvider )
445 for (
int i = 1; i <= nBands; ++i )
447 if ( destHasNoDataValueList.value( i - 1 ) )
449 partDestProvider->
setNoDataValue( i, destNoDataValueList.value( i - 1 ) );
451 partDestProvider->
write( destBlockList[i - 1]->bits( 0 ), i, iterCols, iterRows, 0, 0 );
452 delete destBlockList[i - 1];
453 addToVRT( partFileName( fileIndex ), i, iterCols, iterRows, iterLeft, iterTop );
455 delete partDestProvider;
458 else if ( destProvider )
461 for (
int i = 1; i <= nBands; ++i )
463 destProvider->
write( destBlockList[i - 1]->bits( 0 ), i, iterCols, iterRows, iterLeft, iterTop );
464 delete destBlockList[i - 1];
496 void *redData =
qgsMalloc( mMaxTileWidth * mMaxTileHeight );
497 void *greenData =
qgsMalloc( mMaxTileWidth * mMaxTileHeight );
498 void *blueData =
qgsMalloc( mMaxTileWidth * mMaxTileHeight );
499 void *alphaData =
qgsMalloc( mMaxTileWidth * mMaxTileHeight );
500 int iterLeft = 0, iterTop = 0, iterCols = 0, iterRows = 0;
506 double geoTransform[6];
507 globalOutputParameters( outputExtent, nCols, nRows, geoTransform, pixelSize );
509 destProvider = initOutput( nCols, nRows, crs, geoTransform, 4,
Qgis::Byte );
518 nParts = nPartsX * nPartsY;
522 while ( iter->
readNextRasterPart( 1, iterCols, iterRows, &inputBlock, iterLeft, iterTop ) )
529 if ( feedback && fileIndex < ( nParts - 1 ) )
531 feedback->
setProgress( 100.0 * fileIndex / static_cast< double >( nParts ) );
546 for (
qgssize i = 0; i < nPixels; ++i )
548 QRgb c = inputBlock->
color( i );
556 double a = alpha / 255.;
557 QgsDebugMsgLevel( QString(
"red = %1 green = %2 blue = %3 alpha = %4 p = %5 a = %6" ).arg( red ).arg( green ).arg( blue ).arg( alpha ).arg( static_cast< int >( c ), 0, 16 ).arg( a ), 5 );
562 memcpy( reinterpret_cast< char * >( redData ) + i, &red, 1 );
563 memcpy( reinterpret_cast< char * >( greenData ) + i, &green, 1 );
564 memcpy( reinterpret_cast< char * >( blueData ) + i, &blue, 1 );
565 memcpy( reinterpret_cast< char * >( alphaData ) + i, &alpha, 1 );
574 nCols, iterCols, iterRows,
575 iterLeft, iterTop, mOutputUrl, fileIndex,
578 if ( partDestProvider )
581 partDestProvider->
write( redData, 1, iterCols, iterRows, 0, 0 );
582 partDestProvider->
write( greenData, 2, iterCols, iterRows, 0, 0 );
583 partDestProvider->
write( blueData, 3, iterCols, iterRows, 0, 0 );
584 partDestProvider->
write( alphaData, 4, iterCols, iterRows, 0, 0 );
586 addToVRT( partFileName( fileIndex ), 1, iterCols, iterRows, iterLeft, iterTop );
587 addToVRT( partFileName( fileIndex ), 2, iterCols, iterRows, iterLeft, iterTop );
588 addToVRT( partFileName( fileIndex ), 3, iterCols, iterRows, iterLeft, iterTop );
589 addToVRT( partFileName( fileIndex ), 4, iterCols, iterRows, iterLeft, iterTop );
590 delete partDestProvider;
593 else if ( destProvider )
595 destProvider->
write( redData, 1, iterCols, iterRows, iterLeft, iterTop );
596 destProvider->
write( greenData, 2, iterCols, iterRows, iterLeft, iterTop );
597 destProvider->
write( blueData, 3, iterCols, iterRows, iterLeft, iterTop );
598 destProvider->
write( alphaData, 4, iterCols, iterRows, iterLeft, iterTop );
618 QString vrtFilePath( mOutputUrl +
'/' + vrtFileName() );
619 writeVRT( vrtFilePath );
622 buildPyramids( vrtFilePath );
629 buildPyramids( mOutputUrl );
635 void QgsRasterFileWriter::addToVRT(
const QString &filename,
int band,
int xSize,
int ySize,
int xOffset,
int yOffset )
637 QDomElement bandElem = mVRTBands.value( band - 1 );
639 QDomElement simpleSourceElem = mVRTDocument.createElement( QStringLiteral(
"SimpleSource" ) );
642 QDomElement sourceFilenameElem = mVRTDocument.createElement( QStringLiteral(
"SourceFilename" ) );
643 sourceFilenameElem.setAttribute( QStringLiteral(
"relativeToVRT" ), QStringLiteral(
"1" ) );
644 QDomText sourceFilenameText = mVRTDocument.createTextNode( filename );
645 sourceFilenameElem.appendChild( sourceFilenameText );
646 simpleSourceElem.appendChild( sourceFilenameElem );
649 QDomElement sourceBandElem = mVRTDocument.createElement( QStringLiteral(
"SourceBand" ) );
650 QDomText sourceBandText = mVRTDocument.createTextNode( QString::number( band ) );
651 sourceBandElem.appendChild( sourceBandText );
652 simpleSourceElem.appendChild( sourceBandElem );
655 QDomElement sourcePropertiesElem = mVRTDocument.createElement( QStringLiteral(
"SourceProperties" ) );
656 sourcePropertiesElem.setAttribute( QStringLiteral(
"RasterXSize" ), xSize );
657 sourcePropertiesElem.setAttribute( QStringLiteral(
"RasterYSize" ), ySize );
658 sourcePropertiesElem.setAttribute( QStringLiteral(
"BlockXSize" ), xSize );
659 sourcePropertiesElem.setAttribute( QStringLiteral(
"BlockYSize" ), ySize );
660 sourcePropertiesElem.setAttribute( QStringLiteral(
"DataType" ), QStringLiteral(
"Byte" ) );
661 simpleSourceElem.appendChild( sourcePropertiesElem );
664 QDomElement srcRectElem = mVRTDocument.createElement( QStringLiteral(
"SrcRect" ) );
665 srcRectElem.setAttribute( QStringLiteral(
"xOff" ), QStringLiteral(
"0" ) );
666 srcRectElem.setAttribute( QStringLiteral(
"yOff" ), QStringLiteral(
"0" ) );
667 srcRectElem.setAttribute( QStringLiteral(
"xSize" ), xSize );
668 srcRectElem.setAttribute( QStringLiteral(
"ySize" ), ySize );
669 simpleSourceElem.appendChild( srcRectElem );
672 QDomElement dstRectElem = mVRTDocument.createElement( QStringLiteral(
"DstRect" ) );
673 dstRectElem.setAttribute( QStringLiteral(
"xOff" ), xOffset );
674 dstRectElem.setAttribute( QStringLiteral(
"yOff" ), yOffset );
675 dstRectElem.setAttribute( QStringLiteral(
"xSize" ), xSize );
676 dstRectElem.setAttribute( QStringLiteral(
"ySize" ), ySize );
677 simpleSourceElem.appendChild( dstRectElem );
679 bandElem.appendChild( simpleSourceElem );
683 void QgsRasterFileWriter::buildPyramids(
const QString &filename )
687 dataSet = GDALOpen( filename.toLocal8Bit().data(), GA_Update );
698 overviewList[3] = 16;
699 overviewList[4] = 32;
700 overviewList[5] = 64;
703 if ( mProgressDialog )
705 mProgressDialog->setLabelText( QObject::tr(
"Building Pyramids..." ) );
706 mProgressDialog->setValue( 0 );
707 mProgressDialog->setWindowModality( Qt::WindowModal );
708 mProgressDialog->show();
711 GDALBuildOverviews( dataSet,
"AVERAGE", 6, overviewList, 0, 0, 0, 0 );
715 void QgsRasterFileWriter::buildPyramids(
const QString &filename )
728 QList< QgsRasterPyramid> myPyramidList;
729 if ( ! mPyramidsList.isEmpty() )
731 for (
int myCounterInt = 0; myCounterInt < myPyramidList.count(); myCounterInt++ )
733 myPyramidList[myCounterInt].build =
true;
736 QgsDebugMsgLevel( QString(
"building pyramids : %1 pyramids, %2 resampling, %3 format, %4 options" ).arg( myPyramidList.count() ).arg( mPyramidsResampling ).arg( mPyramidsFormat ).arg( mPyramidsConfigOptions.count() ), 4 );
738 QString res = destProvider->
buildPyramids( myPyramidList, mPyramidsResampling,
739 mPyramidsFormat, mPyramidsConfigOptions );
745 QString title, message;
746 if ( res == QLatin1String(
"ERROR_WRITE_ACCESS" ) )
748 title = QObject::tr(
"Building Pyramids" );
749 message = QObject::tr(
"Write access denied. Adjust the file permissions and try again." );
751 else if ( res == QLatin1String(
"ERROR_WRITE_FORMAT" ) )
753 title = QObject::tr(
"Building Pyramids" );
754 message = QObject::tr(
"The file was not writable. Some formats do not " 755 "support pyramid overviews. Consult the GDAL documentation if in doubt." );
757 else if ( res == QLatin1String(
"FAILED_NOT_SUPPORTED" ) )
759 title = QObject::tr(
"Building Pyramids" );
760 message = QObject::tr(
"Building pyramid overviews is not supported on this type of raster." );
762 else if ( res == QLatin1String(
"ERROR_JPEG_COMPRESSION" ) )
764 title = QObject::tr(
"Building Pyramids" );
765 message = QObject::tr(
"Building internal pyramid overviews is not supported on raster layers with JPEG compression and your current libtiff library." );
767 else if ( res == QLatin1String(
"ERROR_VIRTUAL" ) )
769 title = QObject::tr(
"Building Pyramids" );
770 message = QObject::tr(
"Building pyramid overviews is not supported on this type of raster." );
772 QMessageBox::warning(
nullptr, title, message );
779 int QgsRasterFileWriter::pyramidsProgress(
double dfComplete,
const char *pszMessage,
void *pData )
781 Q_UNUSED( pszMessage );
782 GDALTermProgress( dfComplete, 0, 0 );
783 QProgressDialog *progressDialog =
static_cast<QProgressDialog *
>( pData );
784 if ( pData && progressDialog->wasCanceled() )
791 progressDialog->setRange( 0, 100 );
792 progressDialog->setValue( dfComplete * 100 );
798 void QgsRasterFileWriter::createVRT(
int xSize,
int ySize,
const QgsCoordinateReferenceSystem &crs,
double *geoTransform,
Qgis::DataType type,
const QList<bool> &destHasNoDataValueList,
const QList<double> &destNoDataValueList )
800 mVRTDocument.clear();
801 QDomElement VRTDatasetElem = mVRTDocument.createElement( QStringLiteral(
"VRTDataset" ) );
804 VRTDatasetElem.setAttribute( QStringLiteral(
"rasterXSize" ), xSize );
805 VRTDatasetElem.setAttribute( QStringLiteral(
"rasterYSize" ), ySize );
806 mVRTDocument.appendChild( VRTDatasetElem );
809 QDomElement SRSElem = mVRTDocument.createElement( QStringLiteral(
"SRS" ) );
810 QDomText crsText = mVRTDocument.createTextNode( crs.
toWkt() );
811 SRSElem.appendChild( crsText );
812 VRTDatasetElem.appendChild( SRSElem );
817 QDomElement geoTransformElem = mVRTDocument.createElement( QStringLiteral(
"GeoTransform" ) );
818 QString geoTransformString = QString::number( geoTransform[0] ) +
", " + QString::number( geoTransform[1] ) +
", " + QString::number( geoTransform[2] ) +
819 ", " + QString::number( geoTransform[3] ) +
", " + QString::number( geoTransform[4] ) +
", " + QString::number( geoTransform[5] );
820 QDomText geoTransformText = mVRTDocument.createTextNode( geoTransformString );
821 geoTransformElem.appendChild( geoTransformText );
822 VRTDatasetElem.appendChild( geoTransformElem );
835 QStringList colorInterp;
836 colorInterp << QStringLiteral(
"Red" ) << QStringLiteral(
"Green" ) << QStringLiteral(
"Blue" ) << QStringLiteral(
"Alpha" );
838 QMap<Qgis::DataType, QString> dataTypes;
839 dataTypes.insert(
Qgis::Byte, QStringLiteral(
"Byte" ) );
840 dataTypes.insert(
Qgis::UInt16, QStringLiteral(
"UInt16" ) );
841 dataTypes.insert(
Qgis::Int16, QStringLiteral(
"Int16" ) );
842 dataTypes.insert(
Qgis::UInt32, QStringLiteral(
"Int32" ) );
843 dataTypes.insert(
Qgis::Float32, QStringLiteral(
"Float32" ) );
844 dataTypes.insert(
Qgis::Float64, QStringLiteral(
"Float64" ) );
845 dataTypes.insert(
Qgis::CInt16, QStringLiteral(
"CInt16" ) );
846 dataTypes.insert(
Qgis::CInt32, QStringLiteral(
"CInt32" ) );
850 for (
int i = 1; i <= nBands; i++ )
852 QDomElement VRTBand = mVRTDocument.createElement( QStringLiteral(
"VRTRasterBand" ) );
854 VRTBand.setAttribute( QStringLiteral(
"band" ), QString::number( i ) );
855 QString dataType = dataTypes.value( type );
856 VRTBand.setAttribute( QStringLiteral(
"dataType" ), dataType );
858 if ( mMode ==
Image )
860 VRTBand.setAttribute( QStringLiteral(
"dataType" ), QStringLiteral(
"Byte" ) );
861 QDomElement colorInterpElement = mVRTDocument.createElement( QStringLiteral(
"ColorInterp" ) );
862 QDomText interpText = mVRTDocument.createTextNode( colorInterp.value( i - 1 ) );
863 colorInterpElement.appendChild( interpText );
864 VRTBand.appendChild( colorInterpElement );
867 if ( !destHasNoDataValueList.isEmpty() && destHasNoDataValueList.value( i - 1 ) )
869 VRTBand.setAttribute( QStringLiteral(
"NoDataValue" ), QString::number( destNoDataValueList.value( i - 1 ) ) );
872 mVRTBands.append( VRTBand );
873 VRTDatasetElem.appendChild( VRTBand );
877 bool QgsRasterFileWriter::writeVRT(
const QString &file )
879 QFile outputFile( file );
880 if ( ! outputFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
885 QTextStream outStream( &outputFile );
886 mVRTDocument.save( outStream, 2 );
891 int iterRows,
int iterLeft,
int iterTop,
const QString &
outputUrl,
int fileIndex,
int nBands,
Qgis::DataType type,
894 double mup = extent.
width() / nCols;
895 double mapLeft = extent.
xMinimum() + iterLeft * mup;
896 double mapRight = mapLeft + mup * iterCols;
897 double mapTop = extent.
yMaximum() - iterTop * mup;
898 double mapBottom = mapTop - iterRows * mup;
899 QgsRectangle mapRect( mapLeft, mapBottom, mapRight, mapTop );
901 QString outputFile =
outputUrl +
'/' + partFileName( fileIndex );
904 double geoTransform[6];
905 geoTransform[0] = mapRect.
xMinimum();
906 geoTransform[1] = mup;
907 geoTransform[2] = 0.0;
908 geoTransform[3] = mapRect.
yMaximum();
909 geoTransform[4] = 0.0;
910 geoTransform[5] = -mup;
922 const QList<bool> &destHasNoDataValueList,
const QList<double> &destNoDataValueList )
926 createVRT( nCols, nRows, crs, geoTransform, type, destHasNoDataValueList, destNoDataValueList );
934 if ( mBuildPyramidsFlag == -4 && mOutputProviderKey ==
"gdal" && mOutputFormat.toLower() ==
"gtiff" )
935 mCreateOptions <<
"COPY_SRC_OVERVIEWS=YES";
949 void QgsRasterFileWriter::globalOutputParameters(
const QgsRectangle &extent,
int nCols,
int &nRows,
950 double *geoTransform,
double &pixelSize )
952 pixelSize = extent.
width() / nCols;
957 nRows =
static_cast< double >( nCols ) / extent.
width() * extent.
height() + 0.5;
959 geoTransform[0] = extent.
xMinimum();
960 geoTransform[1] = pixelSize;
961 geoTransform[2] = 0.0;
962 geoTransform[3] = extent.
yMaximum();
963 geoTransform[4] = 0.0;
964 geoTransform[5] = -( extent.
height() / nRows );
967 QString QgsRasterFileWriter::partFileName(
int fileIndex )
970 QFileInfo outputInfo( mOutputUrl );
971 return QStringLiteral(
"%1.%2.tif" ).arg( outputInfo.fileName() ).arg( fileIndex );
974 QString QgsRasterFileWriter::vrtFileName()
976 QFileInfo outputInfo( mOutputUrl );
977 return QStringLiteral(
"%1.vrt" ).arg( outputInfo.fileName() );
982 QString ext = extension.trimmed();
986 if ( ext.startsWith(
'.' ) )
990 int const drvCount = GDALGetDriverCount();
992 for (
int i = 0; i < drvCount; ++i )
994 GDALDriverH drv = GDALGetDriver( i );
997 char **driverMetadata = GDALGetMetadata( drv,
nullptr );
998 if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_RASTER,
false ) )
1000 QString drvName = GDALGetDriverShortName( drv );
1001 QStringList driverExtensions = QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS,
nullptr ) ).split(
' ' );
1003 Q_FOREACH (
const QString &driver, driverExtensions )
1005 if ( driver.compare( ext, Qt::CaseInsensitive ) == 0 )
1016 GDALDriverH drv = GDALGetDriverByName( format.toLocal8Bit().data() );
1019 char **driverMetadata = GDALGetMetadata( drv,
nullptr );
1020 if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_RASTER,
false ) )
1022 return QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS,
nullptr ) ).split(
' ' );
1025 return QStringList();
1030 GDALDriverH drv = GDALGetDriverByName( driverName.toLocal8Bit().data() );
1033 QString drvName = GDALGetDriverLongName( drv );
1034 QString extensionsString = QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS,
nullptr ) );
1035 if ( extensionsString.isEmpty() )
1039 QStringList extensions = extensionsString.split(
' ' );
1040 QString filter = drvName +
" (";
1041 for (
const QString &ext : extensions )
1043 filter.append( QStringLiteral(
"*.%1 *.%2 " ).arg( ext.toLower(), ext.toUpper() ) );
1045 filter = filter.trimmed().append( QStringLiteral(
")" ) );
1054 QList< FilterFormatDetails > results;
1057 int const drvCount = GDALGetDriverCount();
1061 for (
int i = 0; i < drvCount; ++i )
1063 GDALDriverH drv = GDALGetDriver( i );
1066 QString drvName = GDALGetDriverShortName( drv );
1067 char **driverMetadata = GDALGetMetadata( drv,
nullptr );
1068 if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE,
false ) && CSLFetchBoolean( driverMetadata, GDAL_DCAP_RASTER,
false ) )
1071 if ( filterString.isEmpty() )
1080 if ( drvName == QLatin1String(
"GTiff" ) )
1082 tifFormat = details;
1101 results.insert( 0, tifFormat );
1111 QStringList extensions;
1113 QRegularExpression rx( QStringLiteral(
"\\*\\.([a-zA-Z0-9]*)" ) );
1117 QString ext = format.filterString;
1118 QRegularExpressionMatch match = rx.match( ext );
1119 if ( !match.hasMatch() )
1122 QString matched = match.captured( 1 );
1123 extensions << matched;
virtual int bandCount() const =0
Get 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 contains(const QgsRectangle &rect) const
Return true when rectangle contains other rectangle.
A rectangle specified with double values.
QgsRasterFileWriter(const QString &outputUrl)
Base class for processing modules.
void * qgsMalloc(size_t size)
Allocates size bytes and returns a pointer to the allocated memory.
Iterator for sequentially processing raster cells.
Writing was manually canceled.
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.
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)
#define Q_NOWARN_DEPRECATED_PUSH
DataType
Raster data types.
QgsRasterInterface * last() const
double maximumValue
The maximum cell value in the raster band.
QgsDataProvider * createProvider(const QString &providerKey, const QString &dataSource)
Creates a new instance of a provider.
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)
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.
Sixteen bit signed integer (qint16)
virtual double sourceNoDataValue(int bandNo) const
Value representing no data value.
Sixty four bit floating point (double)
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
Get source CRS.
#define QgsDebugMsgLevel(str, level)
virtual QList< QgsRasterPyramid > buildPyramidList(QList< int > overviewList=QList< int >())
Accessor for the raster layers pyramid list.
QgsRectangle extent() const override=0
Returns the extent of the layer.
double width() const
Returns the width of the rectangle.
QRgb color(int row, int column) const
Read a single color.
static int typeSize(int dataType)
Sixteen bit unsigned integer (quint16)
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...
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
Return 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)
Set 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)
Get band statistics.
#define Q_NOWARN_DEPRECATED_POP
void setMaximumTileWidth(int w)
QgsCoordinateReferenceSystem destinationCrs() const
Get destination CRS.
void setMaximumTileHeight(int h)
Internal error if a value used for 'no data' was found in input.
const QgsRasterInterface * input() const
int maximumTileHeight() const
bool isCanceled() const
Tells whether the operation has been canceled already.
static double maximumValuePossible(Qgis::DataType)
Helper function that returns the maximum possible value for a GDAL data type.
virtual bool remove()
Remove dataset.
This class represents a coordinate reference system (CRS).
QString toWkt() const
Returns a WKT representation of this CRS.
Use recommended sort order, with extremely commonly used formats listed first.
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.
void qgsFree(void *ptr)
Frees the memory space pointed to by ptr.
QString outputUrl() const
Returns the output URL for the raster.
void startRasterRead(int bandNumber, int nCols, int nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback=nullptr)
Start reading of raster band.
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
Get source / raw input, the first in pipe, usually provider.
int maximumTileWidth() const
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.