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;
505 double geoTransform[6];
506 globalOutputParameters( outputExtent, nCols, nRows, geoTransform, pixelSize );
508 std::unique_ptr< QgsRasterDataProvider > destProvider( initOutput( nCols, nRows, crs, geoTransform, 4,
Qgis::Byte ) );
517 nParts = nPartsX * nPartsY;
520 std::unique_ptr< QgsRasterBlock > inputBlock;
521 while ( iter->
readNextRasterPart( 1, iterCols, iterRows, inputBlock, iterLeft, iterTop ) )
528 if ( feedback && fileIndex < ( nParts - 1 ) )
530 feedback->
setProgress( 100.0 * fileIndex / static_cast< double >( nParts ) );
544 for (
qgssize i = 0; i < nPixels; ++i )
546 QRgb
c = inputBlock->color( i );
554 double a = alpha / 255.;
555 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 );
560 memcpy( reinterpret_cast< char * >( redData ) + i, &red, 1 );
561 memcpy( reinterpret_cast< char * >( greenData ) + i, &green, 1 );
562 memcpy( reinterpret_cast< char * >( blueData ) + i, &blue, 1 );
563 memcpy( reinterpret_cast< char * >( alphaData ) + i, &alpha, 1 );
570 std::unique_ptr< QgsRasterDataProvider > partDestProvider( createPartProvider( outputExtent,
571 nCols, iterCols, iterRows,
572 iterLeft, iterTop, mOutputUrl, fileIndex,
575 if ( partDestProvider )
578 partDestProvider->write( redData, 1, iterCols, iterRows, 0, 0 );
579 partDestProvider->write( greenData, 2, iterCols, iterRows, 0, 0 );
580 partDestProvider->write( blueData, 3, iterCols, iterRows, 0, 0 );
581 partDestProvider->write( alphaData, 4, iterCols, iterRows, 0, 0 );
583 addToVRT( partFileName( fileIndex ), 1, iterCols, iterRows, iterLeft, iterTop );
584 addToVRT( partFileName( fileIndex ), 2, iterCols, iterRows, iterLeft, iterTop );
585 addToVRT( partFileName( fileIndex ), 3, iterCols, iterRows, iterLeft, iterTop );
586 addToVRT( partFileName( fileIndex ), 4, iterCols, iterRows, iterLeft, iterTop );
589 else if ( destProvider )
591 destProvider->write( redData, 1, iterCols, iterRows, iterLeft, iterTop );
592 destProvider->write( greenData, 2, iterCols, iterRows, iterLeft, iterTop );
593 destProvider->write( blueData, 3, iterCols, iterRows, iterLeft, iterTop );
594 destProvider->write( alphaData, 4, iterCols, iterRows, iterLeft, iterTop );
599 destProvider.reset();
613 QString vrtFilePath( mOutputUrl +
'/' + vrtFileName() );
614 writeVRT( vrtFilePath );
617 buildPyramids( vrtFilePath );
624 buildPyramids( mOutputUrl );
630 void QgsRasterFileWriter::addToVRT(
const QString &filename,
int band,
int xSize,
int ySize,
int xOffset,
int yOffset )
632 QDomElement bandElem = mVRTBands.value( band - 1 );
634 QDomElement simpleSourceElem = mVRTDocument.createElement( QStringLiteral(
"SimpleSource" ) );
637 QDomElement sourceFilenameElem = mVRTDocument.createElement( QStringLiteral(
"SourceFilename" ) );
638 sourceFilenameElem.setAttribute( QStringLiteral(
"relativeToVRT" ), QStringLiteral(
"1" ) );
639 QDomText sourceFilenameText = mVRTDocument.createTextNode( filename );
640 sourceFilenameElem.appendChild( sourceFilenameText );
641 simpleSourceElem.appendChild( sourceFilenameElem );
644 QDomElement sourceBandElem = mVRTDocument.createElement( QStringLiteral(
"SourceBand" ) );
645 QDomText sourceBandText = mVRTDocument.createTextNode( QString::number( band ) );
646 sourceBandElem.appendChild( sourceBandText );
647 simpleSourceElem.appendChild( sourceBandElem );
650 QDomElement sourcePropertiesElem = mVRTDocument.createElement( QStringLiteral(
"SourceProperties" ) );
651 sourcePropertiesElem.setAttribute( QStringLiteral(
"RasterXSize" ), xSize );
652 sourcePropertiesElem.setAttribute( QStringLiteral(
"RasterYSize" ), ySize );
653 sourcePropertiesElem.setAttribute( QStringLiteral(
"BlockXSize" ), xSize );
654 sourcePropertiesElem.setAttribute( QStringLiteral(
"BlockYSize" ), ySize );
655 sourcePropertiesElem.setAttribute( QStringLiteral(
"DataType" ), QStringLiteral(
"Byte" ) );
656 simpleSourceElem.appendChild( sourcePropertiesElem );
659 QDomElement srcRectElem = mVRTDocument.createElement( QStringLiteral(
"SrcRect" ) );
660 srcRectElem.setAttribute( QStringLiteral(
"xOff" ), QStringLiteral(
"0" ) );
661 srcRectElem.setAttribute( QStringLiteral(
"yOff" ), QStringLiteral(
"0" ) );
662 srcRectElem.setAttribute( QStringLiteral(
"xSize" ), xSize );
663 srcRectElem.setAttribute( QStringLiteral(
"ySize" ), ySize );
664 simpleSourceElem.appendChild( srcRectElem );
667 QDomElement dstRectElem = mVRTDocument.createElement( QStringLiteral(
"DstRect" ) );
668 dstRectElem.setAttribute( QStringLiteral(
"xOff" ), xOffset );
669 dstRectElem.setAttribute( QStringLiteral(
"yOff" ), yOffset );
670 dstRectElem.setAttribute( QStringLiteral(
"xSize" ), xSize );
671 dstRectElem.setAttribute( QStringLiteral(
"ySize" ), ySize );
672 simpleSourceElem.appendChild( dstRectElem );
674 bandElem.appendChild( simpleSourceElem );
678 void QgsRasterFileWriter::buildPyramids(
const QString &filename )
682 dataSet = GDALOpen( filename.toLocal8Bit().data(), GA_Update );
693 overviewList[3] = 16;
694 overviewList[4] = 32;
695 overviewList[5] = 64;
698 if ( mProgressDialog )
700 mProgressDialog->setLabelText( QObject::tr(
"Building Pyramids..." ) );
701 mProgressDialog->setValue( 0 );
702 mProgressDialog->setWindowModality( Qt::WindowModal );
703 mProgressDialog->show();
706 GDALBuildOverviews( dataSet,
"AVERAGE", 6, overviewList, 0, 0, 0, 0 );
710 void QgsRasterFileWriter::buildPyramids(
const QString &filename )
724 QList< QgsRasterPyramid> myPyramidList;
725 if ( ! mPyramidsList.isEmpty() )
727 for (
int myCounterInt = 0; myCounterInt < myPyramidList.count(); myCounterInt++ )
729 myPyramidList[myCounterInt].build =
true;
732 QgsDebugMsgLevel( QString(
"building pyramids : %1 pyramids, %2 resampling, %3 format, %4 options" ).arg( myPyramidList.count() ).arg( mPyramidsResampling ).arg( mPyramidsFormat ).arg( mPyramidsConfigOptions.count() ), 4 );
734 QString res = destProvider->
buildPyramids( myPyramidList, mPyramidsResampling,
735 mPyramidsFormat, mPyramidsConfigOptions );
741 QString title, message;
742 if ( res == QLatin1String(
"ERROR_WRITE_ACCESS" ) )
744 title = QObject::tr(
"Building Pyramids" );
745 message = QObject::tr(
"Write access denied. Adjust the file permissions and try again." );
747 else if ( res == QLatin1String(
"ERROR_WRITE_FORMAT" ) )
749 title = QObject::tr(
"Building Pyramids" );
750 message = QObject::tr(
"The file was not writable. Some formats do not " 751 "support pyramid overviews. Consult the GDAL documentation if in doubt." );
753 else if ( res == QLatin1String(
"FAILED_NOT_SUPPORTED" ) )
755 title = QObject::tr(
"Building Pyramids" );
756 message = QObject::tr(
"Building pyramid overviews is not supported on this type of raster." );
758 else if ( res == QLatin1String(
"ERROR_JPEG_COMPRESSION" ) )
760 title = QObject::tr(
"Building Pyramids" );
761 message = QObject::tr(
"Building internal pyramid overviews is not supported on raster layers with JPEG compression and your current libtiff library." );
763 else if ( res == QLatin1String(
"ERROR_VIRTUAL" ) )
765 title = QObject::tr(
"Building Pyramids" );
766 message = QObject::tr(
"Building pyramid overviews is not supported on this type of raster." );
768 QMessageBox::warning(
nullptr, title, message );
775 int QgsRasterFileWriter::pyramidsProgress(
double dfComplete,
const char *pszMessage,
void *pData )
777 Q_UNUSED( pszMessage );
778 GDALTermProgress( dfComplete, 0, 0 );
779 QProgressDialog *progressDialog =
static_cast<QProgressDialog *
>( pData );
780 if ( pData && progressDialog->wasCanceled() )
787 progressDialog->setRange( 0, 100 );
788 progressDialog->setValue( dfComplete * 100 );
794 void QgsRasterFileWriter::createVRT(
int xSize,
int ySize,
const QgsCoordinateReferenceSystem &crs,
double *geoTransform,
Qgis::DataType type,
const QList<bool> &destHasNoDataValueList,
const QList<double> &destNoDataValueList )
796 mVRTDocument.clear();
797 QDomElement VRTDatasetElem = mVRTDocument.createElement( QStringLiteral(
"VRTDataset" ) );
800 VRTDatasetElem.setAttribute( QStringLiteral(
"rasterXSize" ), xSize );
801 VRTDatasetElem.setAttribute( QStringLiteral(
"rasterYSize" ), ySize );
802 mVRTDocument.appendChild( VRTDatasetElem );
805 QDomElement SRSElem = mVRTDocument.createElement( QStringLiteral(
"SRS" ) );
806 QDomText crsText = mVRTDocument.createTextNode( crs.
toWkt() );
807 SRSElem.appendChild( crsText );
808 VRTDatasetElem.appendChild( SRSElem );
813 QDomElement geoTransformElem = mVRTDocument.createElement( QStringLiteral(
"GeoTransform" ) );
814 QString geoTransformString = QString::number( geoTransform[0],
'f', 6 ) +
", " + QString::number( geoTransform[1] ) +
", " + QString::number( geoTransform[2] ) +
815 ", " + QString::number( geoTransform[3],
'f', 6 ) +
", " + QString::number( geoTransform[4] ) +
", " + QString::number( geoTransform[5] );
816 QDomText geoTransformText = mVRTDocument.createTextNode( geoTransformString );
817 geoTransformElem.appendChild( geoTransformText );
818 VRTDatasetElem.appendChild( geoTransformElem );
831 QStringList colorInterp;
832 colorInterp << QStringLiteral(
"Red" ) << QStringLiteral(
"Green" ) << QStringLiteral(
"Blue" ) << QStringLiteral(
"Alpha" );
834 QMap<Qgis::DataType, QString> dataTypes;
835 dataTypes.insert(
Qgis::Byte, QStringLiteral(
"Byte" ) );
836 dataTypes.insert(
Qgis::UInt16, QStringLiteral(
"UInt16" ) );
837 dataTypes.insert(
Qgis::Int16, QStringLiteral(
"Int16" ) );
838 dataTypes.insert(
Qgis::UInt32, QStringLiteral(
"Int32" ) );
839 dataTypes.insert(
Qgis::Float32, QStringLiteral(
"Float32" ) );
840 dataTypes.insert(
Qgis::Float64, QStringLiteral(
"Float64" ) );
841 dataTypes.insert(
Qgis::CInt16, QStringLiteral(
"CInt16" ) );
842 dataTypes.insert(
Qgis::CInt32, QStringLiteral(
"CInt32" ) );
846 for (
int i = 1; i <= nBands; i++ )
848 QDomElement VRTBand = mVRTDocument.createElement( QStringLiteral(
"VRTRasterBand" ) );
850 VRTBand.setAttribute( QStringLiteral(
"band" ), QString::number( i ) );
851 QString dataType = dataTypes.value( type );
852 VRTBand.setAttribute( QStringLiteral(
"dataType" ), dataType );
854 if ( mMode ==
Image )
856 VRTBand.setAttribute( QStringLiteral(
"dataType" ), QStringLiteral(
"Byte" ) );
857 QDomElement colorInterpElement = mVRTDocument.createElement( QStringLiteral(
"ColorInterp" ) );
858 QDomText interpText = mVRTDocument.createTextNode( colorInterp.value( i - 1 ) );
859 colorInterpElement.appendChild( interpText );
860 VRTBand.appendChild( colorInterpElement );
863 if ( !destHasNoDataValueList.isEmpty() && destHasNoDataValueList.value( i - 1 ) )
865 VRTBand.setAttribute( QStringLiteral(
"NoDataValue" ), QString::number( destNoDataValueList.value( i - 1 ) ) );
868 mVRTBands.append( VRTBand );
869 VRTDatasetElem.appendChild( VRTBand );
873 bool QgsRasterFileWriter::writeVRT(
const QString &file )
875 QFile outputFile( file );
876 if ( ! outputFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
881 QTextStream outStream( &outputFile );
882 mVRTDocument.save( outStream, 2 );
887 int iterRows,
int iterLeft,
int iterTop,
const QString &
outputUrl,
int fileIndex,
int nBands,
Qgis::DataType type,
890 double mup = extent.
width() / nCols;
891 double mapLeft = extent.
xMinimum() + iterLeft * mup;
892 double mapRight = mapLeft + mup * iterCols;
893 double mapTop = extent.
yMaximum() - iterTop * mup;
894 double mapBottom = mapTop - iterRows * mup;
895 QgsRectangle mapRect( mapLeft, mapBottom, mapRight, mapTop );
897 QString outputFile =
outputUrl +
'/' + partFileName( fileIndex );
900 double geoTransform[6];
901 geoTransform[0] = mapRect.
xMinimum();
902 geoTransform[1] = mup;
903 geoTransform[2] = 0.0;
904 geoTransform[3] = mapRect.
yMaximum();
905 geoTransform[4] = 0.0;
906 geoTransform[5] = -mup;
918 const QList<bool> &destHasNoDataValueList,
const QList<double> &destNoDataValueList )
922 createVRT( nCols, nRows, crs, geoTransform, type, destHasNoDataValueList, destNoDataValueList );
930 if ( mBuildPyramidsFlag == -4 && mOutputProviderKey ==
"gdal" && mOutputFormat.toLower() ==
"gtiff" )
931 mCreateOptions <<
"COPY_SRC_OVERVIEWS=YES";
945 void QgsRasterFileWriter::globalOutputParameters(
const QgsRectangle &extent,
int nCols,
int &nRows,
946 double *geoTransform,
double &pixelSize )
948 pixelSize = extent.
width() / nCols;
953 nRows =
static_cast< double >( nCols ) / extent.
width() * extent.
height() + 0.5;
955 geoTransform[0] = extent.
xMinimum();
956 geoTransform[1] = pixelSize;
957 geoTransform[2] = 0.0;
958 geoTransform[3] = extent.
yMaximum();
959 geoTransform[4] = 0.0;
960 geoTransform[5] = -( extent.
height() / nRows );
963 QString QgsRasterFileWriter::partFileName(
int fileIndex )
966 QFileInfo outputInfo( mOutputUrl );
967 return QStringLiteral(
"%1.%2.tif" ).arg( outputInfo.fileName() ).arg( fileIndex );
970 QString QgsRasterFileWriter::vrtFileName()
972 QFileInfo outputInfo( mOutputUrl );
973 return QStringLiteral(
"%1.vrt" ).arg( outputInfo.fileName() );
978 QString ext = extension.trimmed();
982 if ( ext.startsWith(
'.' ) )
986 int const drvCount = GDALGetDriverCount();
988 for (
int i = 0; i < drvCount; ++i )
990 GDALDriverH drv = GDALGetDriver( i );
993 char **driverMetadata = GDALGetMetadata( drv,
nullptr );
994 if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_RASTER,
false ) )
996 QString drvName = GDALGetDriverShortName( drv );
997 QStringList driverExtensions = QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS,
nullptr ) ).split(
' ' );
999 Q_FOREACH (
const QString &driver, driverExtensions )
1001 if ( driver.compare( ext, Qt::CaseInsensitive ) == 0 )
1012 GDALDriverH drv = GDALGetDriverByName( format.toLocal8Bit().data() );
1015 char **driverMetadata = GDALGetMetadata( drv,
nullptr );
1016 if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_RASTER,
false ) )
1018 return QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS,
nullptr ) ).split(
' ' );
1021 return QStringList();
1026 GDALDriverH drv = GDALGetDriverByName( driverName.toLocal8Bit().data() );
1029 QString drvName = GDALGetDriverLongName( drv );
1030 QString extensionsString = QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS,
nullptr ) );
1031 if ( extensionsString.isEmpty() )
1035 QStringList extensions = extensionsString.split(
' ' );
1036 QString filter = drvName +
" (";
1037 for (
const QString &ext : extensions )
1039 filter.append( QStringLiteral(
"*.%1 *.%2 " ).arg( ext.toLower(), ext.toUpper() ) );
1041 filter = filter.trimmed().append( QStringLiteral(
")" ) );
1050 QList< FilterFormatDetails > results;
1053 int const drvCount = GDALGetDriverCount();
1057 for (
int i = 0; i < drvCount; ++i )
1059 GDALDriverH drv = GDALGetDriver( i );
1062 QString drvName = GDALGetDriverShortName( drv );
1063 char **driverMetadata = GDALGetMetadata( drv,
nullptr );
1064 if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE,
false ) && CSLFetchBoolean( driverMetadata, GDAL_DCAP_RASTER,
false ) )
1067 if ( filterString.isEmpty() )
1076 if ( drvName == QLatin1String(
"GTiff" ) )
1078 tifFormat = details;
1097 results.insert( 0, tifFormat );
1107 QStringList extensions;
1109 QRegularExpression rx( QStringLiteral(
"\\*\\.([a-zA-Z0-9]*)" ) );
1113 QString ext = format.filterString;
1114 QRegularExpressionMatch match = rx.match( ext );
1115 if ( !match.hasMatch() )
1118 QString matched = match.captured( 1 );
1119 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 contains(const QgsRectangle &rect) const
Returns 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.
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)
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.
double width() const
Returns the width of the rectangle.
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
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.
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.
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.
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
Gets source / raw input, the first in pipe, usually provider.
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.