Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 3 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 24 additions & 19 deletions src/app/georeferencer/qgsgeorefmainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,27 +76,27 @@
#include "qgssettingsentryenumflag.h"
#include "qgslayoutexporter.h"

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 QgsSettingsEntryEnumFlag<QgsImageWarper::ResamplingMethod> *QgsGeoreferencerMainWindow::settingResamplingMethod = new QgsSettingsEntryEnumFlag<QgsImageWarper::ResamplingMethod>( QStringLiteral( "resampling-method" ), sTreeGeoreferencer, QgsImageWarper::ResamplingMethod::NearestNeighbour, QStringLiteral( "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(), QStringLiteral( "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" ) );
const QgsSettingsEntryBool *QgsGeoreferencerMainWindow::settingUseZeroForTransparent = new QgsSettingsEntryBool( QStringLiteral( "use-zero-for-transparent" ), sTreeGeoreferencer, false, QStringLiteral( "Last used georeferencer use-zero-as-transparent option" ) );

const QgsSettingsEntryEnumFlag<QgsGcpTransformerInterface::TransformMethod> *QgsGeoreferencerMainWindow::settingTransformMethod = new QgsSettingsEntryEnumFlag<QgsGcpTransformerInterface::TransformMethod>( QStringLiteral( "transform-method" ), sTreeGeoreferencer, QgsGcpTransformerInterface::TransformMethod::Linear, QObject::tr( "Last used georeferencer transform method" ) );
const QgsSettingsEntryEnumFlag<QgsGcpTransformerInterface::TransformMethod> *QgsGeoreferencerMainWindow::settingTransformMethod = new QgsSettingsEntryEnumFlag<QgsGcpTransformerInterface::TransformMethod>( QStringLiteral( "transform-method" ), sTreeGeoreferencer, QgsGcpTransformerInterface::TransformMethod::Linear, QStringLiteral( "Last used georeferencer transform method" ) );

const QgsSettingsEntryBool *QgsGeoreferencerMainWindow::settingSaveGcps = new QgsSettingsEntryBool( QStringLiteral( "save-gcp-points" ), sTreeGeoreferencer, false, QObject::tr( "Whether georeferencer should automatically save .points files" ) );
const QgsSettingsEntryBool *QgsGeoreferencerMainWindow::settingSaveGcps = new QgsSettingsEntryBool( QStringLiteral( "save-gcp-points" ), sTreeGeoreferencer, false, QStringLiteral( "Whether georeferencer should automatically save .points files" ) );

const QgsSettingsEntryBool *QgsGeoreferencerMainWindow::settingLoadInProject = new QgsSettingsEntryBool( QStringLiteral( "load-result-in-project" ), sTreeGeoreferencer, true, QObject::tr( "Whether georeferencer should automatically load results into the current project" ) );
const QgsSettingsEntryBool *QgsGeoreferencerMainWindow::settingLoadInProject = new QgsSettingsEntryBool( QStringLiteral( "load-result-in-project" ), sTreeGeoreferencer, true, QStringLiteral( "Whether georeferencer should automatically load results into the current project" ) );

const QgsSettingsEntryString *QgsGeoreferencerMainWindow::settingLastSourceFolder = new QgsSettingsEntryString( QStringLiteral( "last-source-folder" ), sTreeGeoreferencer, QString(), QObject::tr( "Last used folder for georeferencer source files" ) );
const QgsSettingsEntryString *QgsGeoreferencerMainWindow::settingLastSourceFolder = new QgsSettingsEntryString( QStringLiteral( "last-source-folder" ), sTreeGeoreferencer, QString(), QStringLiteral( "Last used folder for georeferencer source files" ) );

const QgsSettingsEntryString *QgsGeoreferencerMainWindow::settingLastRasterFileFilter = new QgsSettingsEntryString( QStringLiteral( "last-raster-file-filter" ), sTreeGeoreferencer, QString(), QObject::tr( "Last used raster file filter for georeferencer source files" ) );
const QgsSettingsEntryString *QgsGeoreferencerMainWindow::settingLastRasterFileFilter = new QgsSettingsEntryString( QStringLiteral( "last-raster-file-filter" ), sTreeGeoreferencer, QString(), QStringLiteral( "Last used raster file filter for georeferencer source files" ) );

const QgsSettingsEntryString *QgsGeoreferencerMainWindow::settingLastTargetCrs = new QgsSettingsEntryString( QStringLiteral( "last-target-crs" ), sTreeGeoreferencer, QString(), QObject::tr( "Last used georeferencer target CRS" ) );
const QgsSettingsEntryString *QgsGeoreferencerMainWindow::settingLastTargetCrs = new QgsSettingsEntryString( QStringLiteral( "last-target-crs" ), sTreeGeoreferencer, QString(), QStringLiteral( "Last used georeferencer target CRS" ) );

const QgsSettingsEntryBool *QgsGeoreferencerMainWindow::settingSnappingEnabled = new QgsSettingsEntryBool( QStringLiteral( "snapping-enabled" ), sTreeGeoreferencer, false, QObject::tr( "Snapping enabled." ) );
const QgsSettingsEntryBool *QgsGeoreferencerMainWindow::settingSnappingEnabled = new QgsSettingsEntryBool( QStringLiteral( "snapping-enabled" ), sTreeGeoreferencer, false, QStringLiteral( "Snapping enabled." ) );

const QgsSettingsEntryEnumFlag<Qgis::SnappingTypes> *QgsGeoreferencerMainWindow::settingSnappingTypes = new QgsSettingsEntryEnumFlag<Qgis::SnappingTypes>( QStringLiteral( "snapping-types" ), sTreeGeoreferencer, Qgis::SnappingType::Vertex, QObject::tr( "Snapping types." ) );
const QgsSettingsEntryEnumFlag<Qgis::SnappingTypes> *QgsGeoreferencerMainWindow::settingSnappingTypes = new QgsSettingsEntryEnumFlag<Qgis::SnappingTypes>( QStringLiteral( "snapping-types" ), sTreeGeoreferencer, Qgis::SnappingType::Vertex, QStringLiteral( "Snapping types." ) );


QgsGeorefDockWidget::QgsGeorefDockWidget( const QString &title, QWidget *parent, Qt::WindowFlags flags )
Expand Down Expand Up @@ -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 );
Expand All @@ -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();
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand All @@ -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 );
Expand Down Expand Up @@ -1597,7 +1597,7 @@ bool QgsGeoreferencerMainWindow::georeferenceRaster()
mGeorefTransform,
mResamplingMethod,
mUseZeroForTrans,
mCompressionMethod,
mCreationOptions,
mTargetCrs,
mUserResX,
mUserResY
Expand Down Expand Up @@ -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;
Expand All @@ -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 )
{
Expand Down
7 changes: 4 additions & 3 deletions src/app/georeferencer/qgsgeorefmainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class QgsMapLayer;
class QgsScreenHelper;
class QgsSettingsEntryBool;
class QgsSettingsEntryString;
class QgsSettingsEntryStringList;
template<class T> class QgsSettingsEntryEnumFlag;


Expand All @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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;
Expand Down
18 changes: 11 additions & 7 deletions src/app/georeferencer/qgsimagewarper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ bool QgsImageWarper::openSrcDSAndGetWarpOpt( const QString &input, ResamplingMet
return true;
}

bool QgsImageWarper::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 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" );
Expand All @@ -70,7 +70,11 @@ bool QgsImageWarper::createDestinationDataset( const QString &outputName, GDALDa
return false;
}
char **papszOptions = nullptr;
papszOptions = CSLSetNameValue( papszOptions, "COMPRESS", compression.toLatin1() );
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 )
{
Expand Down Expand Up @@ -123,7 +127,7 @@ bool QgsImageWarper::createDestinationDataset( const QString &outputName, GDALDa
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 )
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;
Expand Down Expand Up @@ -181,7 +185,7 @@ QgsImageWarper::Result QgsImageWarper::warpFile( const QString &input, const QSt
adfGeoTransform[5] = destResY;
}

if ( !createDestinationDataset( output, hSrcDS.get(), hDstDS, destPixels, destLines, adfGeoTransform, useZeroAsTrans, compression, crs ) )
if ( !createDestinationDataset( output, hSrcDS.get(), hDstDS, destPixels, destLines, adfGeoTransform, useZeroAsTrans, options, crs ) )
{
return QgsImageWarper::Result::DestinationCreationError;
}
Expand Down Expand Up @@ -311,14 +315,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 )
Expand All @@ -345,7 +349,7 @@ bool QgsImageWarperTask::run()
*mTransform.get(),
mResamplingMethod,
mUseZeroAsTrans,
mCompression,
mCreationOptions,
mDestinationCrs,
mFeedback.get(),
mDestinationResX,
Expand Down
Loading
Loading