add raster creation options support to georeferencer (fix #47362)

This commit is contained in:
Alexander Bruy 2025-01-29 14:44:01 +00:00 committed by Nyall Dawson
parent 176890fcf5
commit 6dae454943
7 changed files with 271 additions and 93 deletions

View File

@ -78,7 +78,7 @@
const QgsSettingsEntryEnumFlag<QgsImageWarper::ResamplingMethod> *QgsGeoreferencerMainWindow::settingResamplingMethod = new QgsSettingsEntryEnumFlag<QgsImageWarper::ResamplingMethod>( QStringLiteral( "resampling-method" ), sTreeGeoreferencer, QgsImageWarper::ResamplingMethod::NearestNeighbour, QObject::tr( "Last used georeferencer resampling method" ) );
const QgsSettingsEntryString *QgsGeoreferencerMainWindow::settingCompressionMethod = new QgsSettingsEntryString( QStringLiteral( "compression-method" ), sTreeGeoreferencer, QStringLiteral( "NONE" ), QObject::tr( "Last used georeferencer compression method" ) );
const QgsSettingsEntryStringList *QgsGeoreferencerMainWindow::settingCreationOptions = new QgsSettingsEntryStringList( QStringLiteral( "creation-options" ), sTreeGeoreferencer, QStringList(), QObject::tr( "Last used georeferencer raster creation options" ) );
const QgsSettingsEntryBool *QgsGeoreferencerMainWindow::settingUseZeroForTransparent = new QgsSettingsEntryBool( QStringLiteral( "use-zero-for-transparent" ), sTreeGeoreferencer, false, QObject::tr( "Last used georeferencer use-zero-as-transparent option" ) );
@ -454,7 +454,7 @@ bool QgsGeoreferencerMainWindow::showTransformSettingsDialog()
d.setCreateWorldFileOnly( mCreateWorldFileOnly );
d.setTransformMethod( mTransformMethod );
d.setResamplingMethod( mResamplingMethod );
d.setCompressionMethod( mCompressionMethod );
d.setCreationOptions( mCreationOptions.join( ' ' ) );
d.setPdfMapFilename( mPdfOutputMapFile );
d.setPdfReportFilename( mPdfOutputFile );
d.setSaveGcpPoints( mSaveGcp );
@ -472,7 +472,7 @@ bool QgsGeoreferencerMainWindow::showTransformSettingsDialog()
mTargetCrs = d.targetCrs();
mTransformMethod = d.transformMethod();
mResamplingMethod = d.resamplingMethod();
mCompressionMethod = d.compressionMethod();
mCreationOptions = d.creationOptions();
mModifiedFileName = d.destinationFilename();
mPdfOutputMapFile = d.pdfMapFilename();
mPdfOutputFile = d.pdfReportFilename();
@ -534,7 +534,7 @@ void QgsGeoreferencerMainWindow::generateGDALScript()
int order = polynomialOrder( mTransformMethod );
if ( order != 0 )
{
gdalwarpCommand = generateGDALwarpCommand( resamplingStr, mCompressionMethod, mUseZeroForTrans, order, mUserResX, mUserResY );
gdalwarpCommand = generateGDALwarpCommand( resamplingStr, mCreationOptions, mUseZeroForTrans, order, mUserResX, mUserResY );
showGDALScript( QStringList() << translateCommand << gdalwarpCommand );
}
else
@ -1440,7 +1440,7 @@ void QgsGeoreferencerMainWindow::readSettings()
// warp options
mResamplingMethod = settingResamplingMethod->value();
mCompressionMethod = settingCompressionMethod->value();
mCreationOptions = settingCreationOptions->value();
mUseZeroForTrans = settingUseZeroForTransparent->value();
mTransformMethod = settingTransformMethod->value();
mSaveGcp = settingSaveGcps->value();
@ -1455,7 +1455,7 @@ void QgsGeoreferencerMainWindow::writeSettings()
settingTransformMethod->setValue( mTransformMethod );
settingResamplingMethod->setValue( mResamplingMethod );
settingCompressionMethod->setValue( mCompressionMethod );
settingCreationOptions->setValue( mCreationOptions );
settingUseZeroForTransparent->setValue( mUseZeroForTrans );
settingSaveGcps->setValue( mSaveGcp );
settingLoadInProject->setValue( mLoadInQgis );
@ -1597,7 +1597,7 @@ bool QgsGeoreferencerMainWindow::georeferenceRaster()
mGeorefTransform,
mResamplingMethod,
mUseZeroForTrans,
mCompressionMethod,
mCreationOptions,
mTargetCrs,
mUserResX,
mUserResY
@ -2267,7 +2267,7 @@ QString QgsGeoreferencerMainWindow::generateGDALogr2ogrCommand() const
return gdalCommand.join( QLatin1Char( ' ' ) );
}
QString QgsGeoreferencerMainWindow::generateGDALwarpCommand( const QString &resampling, const QString &compress, bool useZeroForTrans, int order, double targetResX, double targetResY )
QString QgsGeoreferencerMainWindow::generateGDALwarpCommand( const QString &resampling, const QStringList &options, bool useZeroForTrans, int order, double targetResX, double targetResY )
{
QStringList gdalCommand;
gdalCommand << QStringLiteral( "gdalwarp" ) << QStringLiteral( "-r" ) << resampling;
@ -2282,7 +2282,12 @@ QString QgsGeoreferencerMainWindow::generateGDALwarpCommand( const QString &resa
// Otherwise, use thin plate spline interpolation
gdalCommand << QStringLiteral( "-tps" );
}
gdalCommand << "-co COMPRESS=" + compress << ( useZeroForTrans ? "-dstalpha" : "" );
for ( const QString &option : options )
{
gdalCommand << QStringLiteral( "-co %1" ).arg( option );
}
gdalCommand << ( useZeroForTrans ? "-dstalpha" : "" );
if ( targetResX != 0.0 && targetResY != 0.0 )
{

View File

@ -52,6 +52,7 @@ class QgsMapLayer;
class QgsScreenHelper;
class QgsSettingsEntryBool;
class QgsSettingsEntryString;
class QgsSettingsEntryStringList;
template<class T> class QgsSettingsEntryEnumFlag;
@ -70,7 +71,7 @@ class APP_EXPORT QgsGeoreferencerMainWindow : public QMainWindow, private Ui::Qg
static inline QgsSettingsTreeNode *sTreeGeoreferencer = QgsSettingsTree::sTreeApp->createChildNode( QStringLiteral( "georeferencer" ) );
static const QgsSettingsEntryEnumFlag<QgsImageWarper::ResamplingMethod> *settingResamplingMethod;
static const QgsSettingsEntryString *settingCompressionMethod;
static const QgsSettingsEntryStringList *settingCreationOptions;
static const QgsSettingsEntryBool *settingUseZeroForTransparent;
static const QgsSettingsEntryEnumFlag<QgsGcpTransformerInterface::TransformMethod> *settingTransformMethod;
static const QgsSettingsEntryBool *settingSaveGcps;
@ -208,7 +209,7 @@ class APP_EXPORT QgsGeoreferencerMainWindow : public QMainWindow, private Ui::Qg
* For values in the range 1 to 3, the parameter "order" prescribes the degree of the interpolating polynomials to use,
* a value of -1 indicates that thin plate spline interpolation should be used for warping.
*/
QString generateGDALwarpCommand( const QString &resampling, const QString &compress, bool useZeroForTrans, int order, double targetResX, double targetResY );
QString generateGDALwarpCommand( const QString &resampling, const QStringList &options, bool useZeroForTrans, int order, double targetResX, double targetResY );
// utils
bool validate();
@ -268,7 +269,7 @@ class APP_EXPORT QgsGeoreferencerMainWindow : public QMainWindow, private Ui::Qg
QgsGcpTransformerInterface::TransformMethod mTransformMethod = QgsGcpTransformerInterface::TransformMethod::InvalidTransform;
QgsImageWarper::ResamplingMethod mResamplingMethod;
QgsGeorefTransform mGeorefTransform;
QString mCompressionMethod = QStringLiteral( "NONE" );
QStringList mCreationOptions;
bool mCreateWorldFileOnly = false;
QgsGCPList mPoints;

View File

@ -123,6 +123,72 @@ bool QgsImageWarper::createDestinationDataset( const QString &outputName, GDALDa
return true;
}
bool QgsImageWarper::createDestinationDataset( const QString &outputName, GDALDatasetH hSrcDS, gdal::dataset_unique_ptr &hDstDS, uint resX, uint resY, double *adfGeoTransform, bool useZeroAsTrans, const QStringList &options, const QgsCoordinateReferenceSystem &crs )
{
// create the output file
GDALDriverH driver = GDALGetDriverByName( "GTiff" );
if ( !driver )
{
return false;
}
char **papszOptions = nullptr;
for ( const QString &option : options )
{
QStringList tokens = option.split( '=', Qt::SkipEmptyParts );
papszOptions = CSLSetNameValue( papszOptions, tokens.at( 0 ).toUtf8().constData(), tokens.at( 1 ).toUtf8().constData() );
}
hDstDS.reset( GDALCreate( driver, outputName.toUtf8().constData(), resX, resY, GDALGetRasterCount( hSrcDS ), GDALGetRasterDataType( GDALGetRasterBand( hSrcDS, 1 ) ), papszOptions ) );
if ( !hDstDS )
{
return false;
}
if ( CE_None != GDALSetGeoTransform( hDstDS.get(), adfGeoTransform ) )
{
return false;
}
if ( crs.isValid() )
{
OGRSpatialReference oTargetSRS;
oTargetSRS.importFromWkt( crs.toWkt( Qgis::CrsWktVariant::PreferredGdal ).toUtf8().data() );
char *wkt = nullptr;
const OGRErr err = oTargetSRS.exportToWkt( &wkt );
if ( err != CE_None || GDALSetProjection( hDstDS.get(), wkt ) != CE_None )
{
CPLFree( wkt );
return false;
}
CPLFree( wkt );
}
for ( int i = 0; i < GDALGetRasterCount( hSrcDS ); ++i )
{
GDALRasterBandH hSrcBand = GDALGetRasterBand( hSrcDS, i + 1 );
GDALRasterBandH hDstBand = GDALGetRasterBand( hDstDS.get(), i + 1 );
GDALColorTableH cTable = GDALGetRasterColorTable( hSrcBand );
GDALSetRasterColorInterpretation( hDstBand, GDALGetRasterColorInterpretation( hSrcBand ) );
if ( cTable )
{
GDALSetRasterColorTable( hDstBand, cTable );
}
int success;
const double noData = GDALGetRasterNoDataValue( hSrcBand, &success );
if ( success )
{
GDALSetRasterNoDataValue( hDstBand, noData );
}
else if ( useZeroAsTrans )
{
GDALSetRasterNoDataValue( hDstBand, 0 );
}
}
return true;
}
QgsImageWarper::Result QgsImageWarper::warpFile( const QString &input, const QString &output, const QgsGeorefTransform &georefTransform, ResamplingMethod resampling, bool useZeroAsTrans, const QString &compression, const QgsCoordinateReferenceSystem &crs, QgsFeedback *feedback, double destResX, double destResY )
{
if ( !georefTransform.parametersInitialized() )
@ -208,6 +274,91 @@ QgsImageWarper::Result QgsImageWarper::warpFile( const QString &input, const QSt
: QgsImageWarper::Result::WarpFailure;
}
QgsImageWarper::Result QgsImageWarper::warpFile( const QString &input, const QString &output, const QgsGeorefTransform &georefTransform, ResamplingMethod resampling, bool useZeroAsTrans, const QStringList &options, const QgsCoordinateReferenceSystem &crs, QgsFeedback *feedback, double destResX, double destResY )
{
if ( !georefTransform.parametersInitialized() )
return QgsImageWarper::Result::InvalidParameters;
gdal::dataset_unique_ptr hSrcDS;
gdal::dataset_unique_ptr hDstDS;
gdal::warp_options_unique_ptr psWarpOptions;
if ( !openSrcDSAndGetWarpOpt( input, resampling, georefTransform.GDALTransformer(), hSrcDS, psWarpOptions ) )
{
return QgsImageWarper::Result::SourceError;
}
double adfGeoTransform[6];
int destPixels, destLines;
CPLErr eErr = GDALSuggestedWarpOutput( hSrcDS.get(), georefTransform.GDALTransformer(), georefTransform.GDALTransformerArgs(), adfGeoTransform, &destPixels, &destLines );
if ( eErr != CE_None )
{
return QgsImageWarper::Result::TransformError;
}
// If specified, override the suggested resolution with user values
if ( destResX != 0.0 || destResY != 0.0 )
{
// If only one scale has been specified, fill in the other from the GDAL suggestion
if ( destResX == 0.0 )
destResX = adfGeoTransform[1];
if ( destResY == 0.0 )
destResY = adfGeoTransform[5];
// Make sure user-specified coordinate system has canonical orientation
if ( destResX < 0.0 )
destResX = -destResX;
if ( destResY > 0.0 )
destResY = -destResY;
// Assert that the north-up convention is fulfilled by GDALSuggestedWarpOutput (should always be the case)
// Asserts are bad as they just crash out, changed to just return false. TS
if ( adfGeoTransform[0] <= 0.0 || adfGeoTransform[5] >= 0.0 )
{
QgsDebugError( QStringLiteral( "Image is not north up after GDALSuggestedWarpOutput, bailing out." ) );
return QgsImageWarper::Result::InvalidParameters;
}
// Find suggested output image extent (in georeferenced units)
const double minX = adfGeoTransform[0];
const double maxX = adfGeoTransform[0] + adfGeoTransform[1] * destPixels;
const double maxY = adfGeoTransform[3];
const double minY = adfGeoTransform[3] + adfGeoTransform[5] * destLines;
// Update line and pixel count to match extent at user-specified resolution
destPixels = ( int ) ( ( ( maxX - minX ) / destResX ) + 0.5 );
destLines = ( int ) ( ( ( minY - maxY ) / destResY ) + 0.5 );
adfGeoTransform[0] = minX;
adfGeoTransform[3] = maxY;
adfGeoTransform[1] = destResX;
adfGeoTransform[5] = destResY;
}
if ( !createDestinationDataset( output, hSrcDS.get(), hDstDS, destPixels, destLines, adfGeoTransform, useZeroAsTrans, options, crs ) )
{
return QgsImageWarper::Result::DestinationCreationError;
}
// Set GDAL callbacks for the progress dialog
psWarpOptions->pProgressArg = reinterpret_cast<void *>( feedback );
psWarpOptions->pfnProgress = updateWarpProgress;
psWarpOptions->hSrcDS = hSrcDS.get();
psWarpOptions->hDstDS = hDstDS.get();
// Create a transformer which transforms from source to destination pixels (and vice versa)
psWarpOptions->pfnTransformer = GeoToPixelTransform;
psWarpOptions->pTransformerArg = addGeoToPixelTransform( georefTransform.GDALTransformer(), georefTransform.GDALTransformerArgs(), adfGeoTransform );
// Initialize and execute the warp operation.
GDALWarpOperation oOperation;
oOperation.Initialize( psWarpOptions.get() );
eErr = oOperation.ChunkAndWarpImage( 0, 0, destPixels, destLines );
destroyGeoToPixelTransform( psWarpOptions->pTransformerArg );
return feedback->isCanceled() ? QgsImageWarper::Result::Canceled : eErr == CE_None ? QgsImageWarper::Result::Success
: QgsImageWarper::Result::WarpFailure;
}
void *QgsImageWarper::addGeoToPixelTransform( GDALTransformerFunc GDALTransformer, void *GDALTransformerArg, double *padfGeotransform ) const
{
TransformChain *chain = new TransformChain;
@ -311,14 +462,14 @@ GDALResampleAlg QgsImageWarper::toGDALResampleAlg( const QgsImageWarper::Resampl
// QgsImageWarperTask
//
QgsImageWarperTask::QgsImageWarperTask( const QString &input, const QString &output, const QgsGeorefTransform &georefTransform, QgsImageWarper::ResamplingMethod resampling, bool useZeroAsTrans, const QString &compression, const QgsCoordinateReferenceSystem &crs, double destResX, double destResY )
QgsImageWarperTask::QgsImageWarperTask( const QString &input, const QString &output, const QgsGeorefTransform &georefTransform, QgsImageWarper::ResamplingMethod resampling, bool useZeroAsTrans, const QStringList &options, const QgsCoordinateReferenceSystem &crs, double destResX, double destResY )
: QgsTask( tr( "Warping %1" ).arg( input ), QgsTask::CanCancel )
, mInput( input )
, mOutput( output )
, mTransform( qgis::down_cast<QgsGeorefTransform *>( georefTransform.clone() ) )
, mResamplingMethod( resampling )
, mUseZeroAsTrans( useZeroAsTrans )
, mCompression( compression )
, mCreationOptions( options )
, mDestinationCrs( crs )
, mDestinationResX( destResX )
, mDestinationResY( destResY )
@ -345,7 +496,7 @@ bool QgsImageWarperTask::run()
*mTransform.get(),
mResamplingMethod,
mUseZeroAsTrans,
mCompression,
mCreationOptions,
mDestinationCrs,
mFeedback.get(),
mDestinationResX,

View File

@ -76,6 +76,23 @@ class APP_EXPORT QgsImageWarper
*/
Result warpFile( const QString &input, const QString &output, const QgsGeorefTransform &georefTransform, ResamplingMethod resampling, bool useZeroAsTrans, const QString &compression, const QgsCoordinateReferenceSystem &crs, QgsFeedback *feedback, double destResX = 0.0, double destResY = 0.0 );
/**
* Warp the file specified by \a input and write the resulting raster to the file \a output.
* \param input input file name
* \param output output file name
* \param georefTransform specifies the warp transformation which should be applied to \a input.
* \param resampling specifies image resampling algorithm to use.
* \param useZeroAsTrans specifies whether to mark transparent areas with a value of "zero".
* \param options raster creation options
* \param crs output file CRS
* \param feedback optional feedback object
* \param destResX The desired horizontal resolution of the output file, in target georeferenced units. A value of zero means automatic selection.
* \param destResY The desired vertical resolution of the output file, in target georeferenced units. A value of zero means automatic selection.
*
* \since QGIS 3.42
*/
Result warpFile( const QString &input, const QString &output, const QgsGeorefTransform &georefTransform, ResamplingMethod resampling, bool useZeroAsTrans, const QStringList &options, const QgsCoordinateReferenceSystem &crs, QgsFeedback *feedback, double destResX = 0.0, double destResY = 0.0 );
private:
struct TransformChain
{
@ -102,6 +119,7 @@ class APP_EXPORT QgsImageWarper
bool openSrcDSAndGetWarpOpt( const QString &input, ResamplingMethod resampling, const GDALTransformerFunc &pfnTransform, gdal::dataset_unique_ptr &hSrcDS, gdal::warp_options_unique_ptr &psWarpOptions ) const;
bool createDestinationDataset( const QString &outputName, GDALDatasetH hSrcDS, gdal::dataset_unique_ptr &hDstDS, uint resX, uint resY, double *adfGeoTransform, bool useZeroAsTrans, const QString &compression, const QgsCoordinateReferenceSystem &crs );
bool createDestinationDataset( const QString &outputName, GDALDatasetH hSrcDS, gdal::dataset_unique_ptr &hDstDS, uint resX, uint resY, double *adfGeoTransform, bool useZeroAsTrans, const QStringList &options, const QgsCoordinateReferenceSystem &crs );
//! \brief GDAL progress callback, used to display warping progress via a QProgressDialog
static int CPL_STDCALL updateWarpProgress( double dfComplete, const char *pszMessage, void *pProgressArg );
@ -123,12 +141,12 @@ class QgsImageWarperTask : public QgsTask
* \param georefTransform specifies the warp transformation which should be applied to \a input.
* \param resampling specifies image resampling algorithm to use.
* \param useZeroAsTrans specifies whether to mark transparent areas with a value of "zero".
* \param compression image compression method
* \param options raster creation options
* \param crs output file CRS
* \param destResX The desired horizontal resolution of the output file, in target georeferenced units. A value of zero means automatic selection.
* \param destResY The desired vertical resolution of the output file, in target georeferenced units. A value of zero means automatic selection.
*/
QgsImageWarperTask( const QString &input, const QString &output, const QgsGeorefTransform &georefTransform, QgsImageWarper::ResamplingMethod resampling, bool useZeroAsTrans, const QString &compression, const QgsCoordinateReferenceSystem &crs, double destResX = 0.0, double destResY = 0.0 );
QgsImageWarperTask( const QString &input, const QString &output, const QgsGeorefTransform &georefTransform, QgsImageWarper::ResamplingMethod resampling, bool useZeroAsTrans, const QStringList &options, const QgsCoordinateReferenceSystem &crs, double destResX = 0.0, double destResY = 0.0 );
void cancel() override;
@ -146,7 +164,7 @@ class QgsImageWarperTask : public QgsTask
std::unique_ptr<QgsGeorefTransform> mTransform;
QgsImageWarper::ResamplingMethod mResamplingMethod = QgsImageWarper::ResamplingMethod::Bilinear;
bool mUseZeroAsTrans = false;
QString mCompression;
QStringList mCreationOptions;
QgsCoordinateReferenceSystem mDestinationCrs;
double mDestinationResX = 0;
double mDestinationResY = 0;

View File

@ -108,11 +108,7 @@ QgsTransformSettingsDialog::QgsTransformSettingsDialog( Qgis::LayerType type, co
cmbTransformType->addItem( tr( "Thin Plate Spline" ), static_cast<int>( QgsGcpTransformerInterface::TransformMethod::ThinPlateSpline ) );
cmbTransformType->addItem( tr( "Projective" ), static_cast<int>( QgsGcpTransformerInterface::TransformMethod::Projective ) );
// Populate CompressionComboBox
cmbCompressionComboBox->addItem( tr( "None" ), QStringLiteral( "None" ) );
cmbCompressionComboBox->addItem( tr( "LZW" ), QStringLiteral( "LZW" ) );
cmbCompressionComboBox->addItem( tr( "PACKBITS" ), QStringLiteral( "PACKBITS" ) );
cmbCompressionComboBox->addItem( tr( "DEFLATE" ), QStringLiteral( "DEFLATE" ) );
mCreationOptionsWidget->setFormat( "GTiff" );
cmbResampling->addItem( tr( "Nearest Neighbour" ), static_cast<int>( QgsImageWarper::ResamplingMethod::NearestNeighbour ) );
cmbResampling->addItem( tr( "Bilinear (2x2 Kernel)" ), static_cast<int>( QgsImageWarper::ResamplingMethod::Bilinear ) );
@ -170,14 +166,14 @@ void QgsTransformSettingsDialog::setResamplingMethod( QgsImageWarper::Resampling
cmbResampling->setCurrentIndex( cmbResampling->findData( static_cast<int>( method ) ) );
}
QString QgsTransformSettingsDialog::compressionMethod() const
QStringList QgsTransformSettingsDialog::creationOptions() const
{
return cmbCompressionComboBox->currentData().toString();
return mCreationOptionsGroupBox->isChecked() ? mCreationOptionsWidget->options() : QStringList();
}
void QgsTransformSettingsDialog::setCompressionMethod( const QString &method )
void QgsTransformSettingsDialog::setCreationOptions( const QString &options )
{
cmbCompressionComboBox->setCurrentIndex( cmbCompressionComboBox->findData( method ) );
mCreationOptionsWidget->setOptions( options );
}
QString QgsTransformSettingsDialog::destinationFilename() const
@ -280,6 +276,13 @@ void QgsTransformSettingsDialog::accept()
outputFile->setFilePath( outputFileInfo.absoluteFilePath() );
}
const QString message = mCreationOptionsWidget->validateOptions( false );
if ( !message.isNull() )
{
QMessageBox::warning( this, tr( "Creation Options" ), tr( "Invalid creation options:\n%1" ).arg( message ) );
return;
}
QDialog::accept();
}

View File

@ -73,14 +73,14 @@ class QgsTransformSettingsDialog : public QDialog, private Ui::QgsTransformSetti
void setResamplingMethod( QgsImageWarper::ResamplingMethod method );
/**
* Returns the selected compression method.
* Returns raster creation options.
*/
QString compressionMethod() const;
QStringList creationOptions() const;
/**
* Sets the selected compression \a method.
* Sets raster creation options.
*/
void setCompressionMethod( const QString &method );
void setCreationOptions( const QString &options );
/**
* Returns the destination filename.

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>438</width>
<height>702</height>
<height>646</height>
</rect>
</property>
<property name="windowTitle">
@ -17,10 +17,10 @@
<item row="9" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Help|QDialogButtonBox::StandardButton::Ok</set>
</property>
</widget>
</item>
@ -49,42 +49,6 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item row="3" column="0">
<widget class="QLabel" name="mCompressionLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Compression</string>
</property>
<property name="buddy">
<cstring>cmbCompressionComboBox</cstring>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QCheckBox" name="cbxZeroAsTrans">
<property name="text">
<string>Use 0 for transparency when needed</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="cmbCompressionComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
@ -98,9 +62,6 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QgsFileWidget" name="mRasterOutputFile" native="true"/>
</item>
<item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="mWorldFileCheckBox">
<property name="text">
@ -108,6 +69,22 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="textLabel1">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Resampling method</string>
</property>
<property name="buddy">
<cstring>cmbResampling</cstring>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QGroupBox" name="cbxUserResolution">
<property name="title">
@ -175,22 +152,34 @@
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="textLabel1">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item row="5" column="0" colspan="2">
<widget class="QCheckBox" name="cbxZeroAsTrans">
<property name="text">
<string>Resampling method</string>
<string>Use 0 for transparency when needed</string>
</property>
<property name="buddy">
<cstring>cmbResampling</cstring>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QgsFileWidget" name="mRasterOutputFile" native="true"/>
</item>
<item row="3" column="0" colspan="2">
<widget class="QgsCollapsibleGroupBox" name="mCreationOptionsGroupBox">
<property name="title">
<string>Raster creation options</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QgsRasterFormatSaveOptionsWidget" name="mCreationOptionsWidget" native="true"/>
</item>
</layout>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="cmbResampling">
<property name="currentIndex">
@ -250,12 +239,6 @@
<string>Reports</string>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="1">
<widget class="QgsFileWidget" name="mPdfMap" native="true"/>
</item>
<item row="1" column="1">
<widget class="QgsFileWidget" name="mPdfReport" native="true"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
@ -270,6 +253,12 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QgsFileWidget" name="mPdfReport" native="true"/>
</item>
<item row="0" column="1">
<widget class="QgsFileWidget" name="mPdfMap" native="true"/>
</item>
</layout>
</widget>
</item>
@ -318,7 +307,7 @@
<item row="1" column="1">
<widget class="QgsProjectionSelectionWidget" name="mCrsSelector" native="true">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
<enum>Qt::FocusPolicy::StrongFocus</enum>
</property>
</widget>
</item>
@ -328,7 +317,7 @@
<item row="8" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -365,12 +354,23 @@
<extends>QDoubleSpinBox</extends>
<header location="global">georeferencer/qgsvalidateddoublespinbox.h</header>
</customwidget>
<customwidget>
<class>QgsRasterFormatSaveOptionsWidget</class>
<extends>QWidget</extends>
<header>qgsrasterformatsaveoptionswidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsCollapsibleGroupBox</class>
<extends>QGroupBox</extends>
<header>qgscollapsiblegroupbox.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>cmbTransformType</tabstop>
<tabstop>mCrsSelector</tabstop>
<tabstop>cmbResampling</tabstop>
<tabstop>cmbCompressionComboBox</tabstop>
<tabstop>mWorldFileCheckBox</tabstop>
<tabstop>cbxZeroAsTrans</tabstop>
<tabstop>cbxUserResolution</tabstop>