mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-20 00:06:36 -04:00
[FEATURE] Append raster layer to an existing Geopackage in the 'Save Raster Layer As' dialog. Fixes #17926
This commit is contained in:
parent
6935027ead
commit
60fa8eae07
@ -54,6 +54,7 @@ Constructor for QgsRasterLayerSaveAsDialog
|
|||||||
bool tileMode() const;
|
bool tileMode() const;
|
||||||
bool addToCanvas() const;
|
bool addToCanvas() const;
|
||||||
QString outputFileName() const;
|
QString outputFileName() const;
|
||||||
|
QString outputLayerName() const;
|
||||||
QString outputFormat() const;
|
QString outputFormat() const;
|
||||||
QgsCoordinateReferenceSystem outputCrs();
|
QgsCoordinateReferenceSystem outputCrs();
|
||||||
QStringList createOptions() const;
|
QStringList createOptions() const;
|
||||||
@ -72,6 +73,7 @@ Constructor for QgsRasterLayerSaveAsDialog
|
|||||||
public slots:
|
public slots:
|
||||||
virtual void accept();
|
virtual void accept();
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -7156,13 +7156,16 @@ void QgisApp::saveAsRasterFile( QgsRasterLayer *rasterLayer )
|
|||||||
bool tileMode = d.tileMode();
|
bool tileMode = d.tileMode();
|
||||||
bool addToCanvas = d.addToCanvas();
|
bool addToCanvas = d.addToCanvas();
|
||||||
QPointer< QgsRasterLayer > rlWeakPointer( rasterLayer );
|
QPointer< QgsRasterLayer > rlWeakPointer( rasterLayer );
|
||||||
|
QString outputLayerName = d.outputLayerName();
|
||||||
|
QString outputFormat = d.outputFormat();
|
||||||
|
|
||||||
QgsRasterFileWriterTask *writerTask = new QgsRasterFileWriterTask( fileWriter, pipe.release(), d.nColumns(), d.nRows(),
|
QgsRasterFileWriterTask *writerTask = new QgsRasterFileWriterTask( fileWriter, pipe.release(), d.nColumns(), d.nRows(),
|
||||||
d.outputRectangle(), d.outputCrs() );
|
d.outputRectangle(), d.outputCrs() );
|
||||||
|
|
||||||
// when writer is successful:
|
// when writer is successful:
|
||||||
|
|
||||||
connect( writerTask, &QgsRasterFileWriterTask::writeComplete, this, [this, tileMode, addToCanvas, rlWeakPointer ]( const QString & newFilename )
|
connect( writerTask, &QgsRasterFileWriterTask::writeComplete, this,
|
||||||
|
[this, tileMode, addToCanvas, rlWeakPointer, outputLayerName, outputFormat]( const QString & newFilename )
|
||||||
{
|
{
|
||||||
QString fileName = newFilename;
|
QString fileName = newFilename;
|
||||||
if ( tileMode )
|
if ( tileMode )
|
||||||
@ -7172,9 +7175,16 @@ void QgisApp::saveAsRasterFile( QgsRasterLayer *rasterLayer )
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( addToCanvas )
|
if ( addToCanvas )
|
||||||
|
{
|
||||||
|
if ( outputFormat == QLatin1String( "GPKG" ) && !outputLayerName.isEmpty() )
|
||||||
|
{
|
||||||
|
addRasterLayers( QStringList( QStringLiteral( "GPKG:%1:%2" ).arg( fileName, outputLayerName ) ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
addRasterLayers( QStringList( fileName ) );
|
addRasterLayers( QStringList( fileName ) );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if ( rlWeakPointer )
|
if ( rlWeakPointer )
|
||||||
emit layerSavedAs( rlWeakPointer, fileName );
|
emit layerSavedAs( rlWeakPointer, fileName );
|
||||||
|
|
||||||
@ -12811,7 +12821,17 @@ bool QgisApp::addRasterLayers( QStringList const &fileNameQStringList, bool guiW
|
|||||||
QFileInfo myFileInfo( *myIterator );
|
QFileInfo myFileInfo( *myIterator );
|
||||||
|
|
||||||
// try to create the layer
|
// try to create the layer
|
||||||
QgsRasterLayer *layer = addRasterLayerPrivate( *myIterator, myFileInfo.completeBaseName(),
|
// set the layer name to the file base name...
|
||||||
|
QString layerName = myFileInfo.completeBaseName();
|
||||||
|
|
||||||
|
// ...unless the layer uri matches "GPKG:filePath:layerName" and layerName differs from the file base name
|
||||||
|
QStringList layerUriSegments = myIterator->split( QLatin1String( ":" ) );
|
||||||
|
if ( layerUriSegments.count() == 3 && layerUriSegments[ 0 ] == QLatin1String( "GPKG" ) && layerUriSegments[ 2 ] != layerName )
|
||||||
|
{
|
||||||
|
layerName = QStringLiteral( "%1 %2" ).arg( layerName, layerUriSegments[ 2 ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsRasterLayer *layer = addRasterLayerPrivate( *myIterator, layerName,
|
||||||
QString(), guiWarning, true );
|
QString(), guiWarning, true );
|
||||||
if ( layer && layer->isValid() )
|
if ( layer && layer->isValid() )
|
||||||
{
|
{
|
||||||
|
@ -179,6 +179,12 @@ QgsRasterLayerSaveAsDialog::QgsRasterLayerSaveAsDialog( QgsRasterLayer *rasterLa
|
|||||||
QFileInfo tmplFileInfo( filePath );
|
QFileInfo tmplFileInfo( filePath );
|
||||||
settings.setValue( QStringLiteral( "UI/lastRasterFileDir" ), tmplFileInfo.absolutePath() );
|
settings.setValue( QStringLiteral( "UI/lastRasterFileDir" ), tmplFileInfo.absolutePath() );
|
||||||
|
|
||||||
|
if ( !filePath.isEmpty() && mLayerName->isEnabled() )
|
||||||
|
{
|
||||||
|
QFileInfo fileInfo( filePath );
|
||||||
|
mLayerName->setText( fileInfo.baseName() );
|
||||||
|
}
|
||||||
|
|
||||||
if ( mTileModeCheckBox->isChecked() )
|
if ( mTileModeCheckBox->isChecked() )
|
||||||
{
|
{
|
||||||
QString fileName = filePath;
|
QString fileName = filePath;
|
||||||
@ -314,6 +320,18 @@ void QgsRasterLayerSaveAsDialog::mFormatComboBox_currentIndexChanged( const QStr
|
|||||||
tr( "All files (*.*)" ) );
|
tr( "All files (*.*)" ) );
|
||||||
}
|
}
|
||||||
mFilename->setFilter( filter );
|
mFilename->setFilter( filter );
|
||||||
|
|
||||||
|
mFilename->setConfirmOverwrite( outputFormat() != QStringLiteral( "GPKG" ) );
|
||||||
|
mLayerName->setEnabled( outputFormat() == QStringLiteral( "GPKG" ) );
|
||||||
|
if ( mLayerName->isEnabled() )
|
||||||
|
{
|
||||||
|
QString layerName = QFileInfo( mFilename->filePath() ).baseName();
|
||||||
|
mLayerName->setText( layerName );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mLayerName->setText( QString() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int QgsRasterLayerSaveAsDialog::nColumns() const
|
int QgsRasterLayerSaveAsDialog::nColumns() const
|
||||||
@ -380,6 +398,19 @@ QString QgsRasterLayerSaveAsDialog::outputFileName() const
|
|||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString QgsRasterLayerSaveAsDialog::outputLayerName() const
|
||||||
|
{
|
||||||
|
if ( mLayerName->text().isEmpty() && outputFormat() == QStringLiteral( "GPKG" ) && !mTileModeCheckBox->isChecked() )
|
||||||
|
{
|
||||||
|
// Always return layer name for GeoPackages
|
||||||
|
return QFileInfo( mFilename->filePath() ).baseName();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return mLayerName->text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString QgsRasterLayerSaveAsDialog::outputFormat() const
|
QString QgsRasterLayerSaveAsDialog::outputFormat() const
|
||||||
{
|
{
|
||||||
return mFormatComboBox->currentData().toString();
|
return mFormatComboBox->currentData().toString();
|
||||||
@ -387,7 +418,35 @@ QString QgsRasterLayerSaveAsDialog::outputFormat() const
|
|||||||
|
|
||||||
QStringList QgsRasterLayerSaveAsDialog::createOptions() const
|
QStringList QgsRasterLayerSaveAsDialog::createOptions() const
|
||||||
{
|
{
|
||||||
return mCreateOptionsGroupBox->isChecked() ? mCreateOptionsWidget->options() : QStringList();
|
QStringList options = mCreateOptionsGroupBox->isChecked() ? mCreateOptionsWidget->options() : QStringList();
|
||||||
|
if ( outputFormat() == QStringLiteral( "GPKG" ) )
|
||||||
|
{
|
||||||
|
// Overwrite the GPKG table options
|
||||||
|
int indx = options.indexOf( QRegExp( "^RASTER_TABLE=.*" ) );
|
||||||
|
if ( indx > -1 )
|
||||||
|
{
|
||||||
|
options.replace( indx, QStringLiteral( "RASTER_TABLE=%1" ).arg( outputLayerName() ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
options.append( QStringLiteral( "RASTER_TABLE=%1" ).arg( outputLayerName() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only enable the append mode if the layer doesn't exist yet. For existing layers a 'confirm overwrite' dialog will be shown.
|
||||||
|
if ( !outputLayerExistsInGpkg() )
|
||||||
|
{
|
||||||
|
indx = options.indexOf( QRegExp( "^APPEND_SUBDATASET=.*", Qt::CaseInsensitive ) );
|
||||||
|
if ( indx > -1 )
|
||||||
|
{
|
||||||
|
options.replace ( indx, QStringLiteral( "APPEND_SUBDATASET=YES" ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
options.append( QStringLiteral( "APPEND_SUBDATASET=YES" ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
QgsRectangle QgsRasterLayerSaveAsDialog::outputRectangle() const
|
QgsRectangle QgsRasterLayerSaveAsDialog::outputRectangle() const
|
||||||
@ -845,6 +904,32 @@ bool QgsRasterLayerSaveAsDialog::validate() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QgsRasterLayerSaveAsDialog::outputLayerExistsInGpkg() const
|
||||||
|
{
|
||||||
|
QgsRasterLayer *layer = nullptr;
|
||||||
|
layer = new QgsRasterLayer( QStringLiteral( "GPKG:%1:%2" ).arg( outputFileName(), outputLayerName() ), "", QStringLiteral( "gdal" ) );
|
||||||
|
return layer->isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsRasterLayerSaveAsDialog::accept()
|
||||||
|
{
|
||||||
|
if ( !validate() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( outputFormat() == QStringLiteral( "GPKG" ) && outputLayerExistsInGpkg() &&
|
||||||
|
QMessageBox::warning( this, tr( "Save Raster Layer" ),
|
||||||
|
tr( "The layer %1 already exists in the target file, and overwriting layers in GeoPackage is not supported. "
|
||||||
|
"Do you want to overwrite the whole file?" ).arg( outputLayerName() ),
|
||||||
|
QMessageBox::Yes | QMessageBox::No ) == QMessageBox::No )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog::accept();
|
||||||
|
}
|
||||||
|
|
||||||
void QgsRasterLayerSaveAsDialog::showHelp()
|
void QgsRasterLayerSaveAsDialog::showHelp()
|
||||||
{
|
{
|
||||||
QgsHelp::openHelp( QStringLiteral( "managing_data_source/create_layers.html#save-layer-from-an-existing-file" ) );
|
QgsHelp::openHelp( QStringLiteral( "managing_data_source/create_layers.html#save-layer-from-an-existing-file" ) );
|
||||||
|
@ -71,6 +71,7 @@ class GUI_EXPORT QgsRasterLayerSaveAsDialog: public QDialog, private Ui::QgsRast
|
|||||||
bool tileMode() const;
|
bool tileMode() const;
|
||||||
bool addToCanvas() const;
|
bool addToCanvas() const;
|
||||||
QString outputFileName() const;
|
QString outputFileName() const;
|
||||||
|
QString outputLayerName() const;
|
||||||
QString outputFormat() const;
|
QString outputFormat() const;
|
||||||
QgsCoordinateReferenceSystem outputCrs();
|
QgsCoordinateReferenceSystem outputCrs();
|
||||||
QStringList createOptions() const;
|
QStringList createOptions() const;
|
||||||
@ -87,7 +88,7 @@ class GUI_EXPORT QgsRasterLayerSaveAsDialog: public QDialog, private Ui::QgsRast
|
|||||||
void hideOutput();
|
void hideOutput();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void accept() override { if ( validate() ) QDialog::accept(); }
|
void accept() override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void mRawModeRadioButton_toggled( bool );
|
void mRawModeRadioButton_toggled( bool );
|
||||||
@ -138,6 +139,7 @@ class GUI_EXPORT QgsRasterLayerSaveAsDialog: public QDialog, private Ui::QgsRast
|
|||||||
double noDataCellValue( int row, int column ) const;
|
double noDataCellValue( int row, int column ) const;
|
||||||
void adjustNoDataCellWidth( int row, int column );
|
void adjustNoDataCellWidth( int row, int column );
|
||||||
bool validate() const;
|
bool validate() const;
|
||||||
|
bool outputLayerExistsInGpkg() const;
|
||||||
|
|
||||||
void insertAvailableOutputFormats();
|
void insertAvailableOutputFormats();
|
||||||
};
|
};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>575</width>
|
<width>575</width>
|
||||||
<height>580</height>
|
<height>610</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -86,7 +86,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="QgsProjectionSelectionWidget" name="mCrsSelector" native="true">
|
<widget class="QgsProjectionSelectionWidget" name="mCrsSelector" native="true">
|
||||||
<property name="focusPolicy">
|
<property name="focusPolicy">
|
||||||
<enum>Qt::StrongFocus</enum>
|
<enum>Qt::StrongFocus</enum>
|
||||||
@ -118,7 +118,7 @@ datasets with maximum width and height specified below.</string>
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="4" column="0">
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
@ -147,7 +147,7 @@ datasets with maximum width and height specified below.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0" colspan="2">
|
<item row="5" column="0" colspan="2">
|
||||||
<widget class="QCheckBox" name="mAddToCanvas">
|
<widget class="QCheckBox" name="mAddToCanvas">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Add saved file to map</string>
|
<string>Add saved file to map</string>
|
||||||
@ -157,6 +157,16 @@ datasets with maximum width and height specified below.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Layer name</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLineEdit" name="mLayerName"/>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@ -716,6 +726,7 @@ datasets with maximum width and height specified below.</string>
|
|||||||
<tabstop>mFormatComboBox</tabstop>
|
<tabstop>mFormatComboBox</tabstop>
|
||||||
<tabstop>mTileModeCheckBox</tabstop>
|
<tabstop>mTileModeCheckBox</tabstop>
|
||||||
<tabstop>mFilename</tabstop>
|
<tabstop>mFilename</tabstop>
|
||||||
|
<tabstop>mLayerName</tabstop>
|
||||||
<tabstop>mCrsSelector</tabstop>
|
<tabstop>mCrsSelector</tabstop>
|
||||||
<tabstop>mAddToCanvas</tabstop>
|
<tabstop>mAddToCanvas</tabstop>
|
||||||
<tabstop>mScrollArea</tabstop>
|
<tabstop>mScrollArea</tabstop>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user