Skip to content
Permalink
Browse files

[FEATURE] Add "export to file" options for raster and vector layers

within the browser panel

Allows direct export of these files (e.g. to a different format,
crs, etc) without having to actually load them into a project
first.
  • Loading branch information
nyalldawson committed Oct 11, 2018
1 parent 2089887 commit 7ac521529bfbcc188bc18f9419cb6d971174bca9
@@ -52,7 +52,23 @@ Constructor for QgsRasterLayerSaveAsDialog
int maximumTileSizeX() const;
int maximumTileSizeY() const;
bool tileMode() const;

bool addToCanvas() const;
%Docstring
Returns true if the "add to canvas" checkbox is checked.

.. seealso:: :py:func:`setAddToCanvas`
%End

void setAddToCanvas( bool checked );
%Docstring
Sets whether the "add to canvas" checkbox should be ``checked``.

.. seealso:: :py:func:`addToCanvas`

.. versionadded:: 3.6
%End

QString outputFileName() const;

QString outputLayerName() const;
@@ -9,6 +9,7 @@




class QgsWindowManagerInterface
{
%Docstring
@@ -44,6 +45,40 @@ existing instance to the foreground.

Returns the dialog if shown, or None if the dialog either could not be
created or is not supported by the window manager implementation.
%End

virtual QString executeExportVectorLayerDialog( QgsVectorLayer *layer );
%Docstring
Executes the standard "Export Vector Layer" dialog for the specified ``layer``,
and performs an export using the settings accepted in the dialog.

The created vector file name is returned.

Depending on the window manager implementation the actual export of the
layer may occur in a background task, in which case calling this method
will immediately return after the dialog has been accepted, but before
the exported layer has been finalized.

.. seealso:: :py:func:`executeExportRasterLayerDialog`

.. versionadded:: 3.6
%End

virtual QString executeExportRasterLayerDialog( QgsRasterLayer *layer );
%Docstring
Executes the standard "Export Raster Layer" dialog for the specified ``layer``,
and performs an export using the settings accepted in the dialog.

The created raster file name is returned.

Depending on the window manager implementation the actual export of the
layer may occur in a background task, in which case calling this method
will immediately return after the dialog has been accepted, but before
the exported layer has been finalized.

.. seealso:: :py:func:`executeExportVectorLayerDialog`

.. versionadded:: 3.6
%End

};
@@ -7160,22 +7160,23 @@ void QgisApp::attributeTable( QgsAttributeTableFilterModel::FilterMode filter )
// the dialog will be deleted by itself on close
}

void QgisApp::saveAsRasterFile( QgsRasterLayer *rasterLayer )
QString QgisApp::saveAsRasterFile( QgsRasterLayer *rasterLayer, const bool defaultAddToCanvas )
{
if ( !rasterLayer )
rasterLayer = qobject_cast<QgsRasterLayer *>( activeLayer() );

if ( !rasterLayer )
{
return;
return QString();
}

QgsRasterLayerSaveAsDialog d( rasterLayer, rasterLayer->dataProvider(),
mMapCanvas->extent(), rasterLayer->crs(),
mMapCanvas->mapSettings().destinationCrs(),
this );
d.setAddToCanvas( defaultAddToCanvas );
if ( d.exec() == QDialog::Rejected )
return;
return QString();

QgsSettings settings;
settings.setValue( QStringLiteral( "UI/lastRasterFileDir" ), QFileInfo( d.outputFileName() ).absolutePath() );
@@ -7205,7 +7206,7 @@ void QgisApp::saveAsRasterFile( QgsRasterLayer *rasterLayer )
if ( !pipe->set( rasterLayer->dataProvider()->clone() ) )
{
QgsDebugMsg( QStringLiteral( "Cannot set pipe provider" ) );
return;
return QString();
}

QgsRasterNuller *nuller = new QgsRasterNuller();
@@ -7216,7 +7217,7 @@ void QgisApp::saveAsRasterFile( QgsRasterLayer *rasterLayer )
if ( !pipe->insert( 1, nuller ) )
{
QgsDebugMsg( QStringLiteral( "Cannot set pipe nuller" ) );
return;
return QString();
}

// add projector if necessary
@@ -7227,7 +7228,7 @@ void QgisApp::saveAsRasterFile( QgsRasterLayer *rasterLayer )
if ( !pipe->insert( 2, projector ) )
{
QgsDebugMsg( QStringLiteral( "Cannot set pipe projector" ) );
return;
return QString();
}
}
}
@@ -7240,14 +7241,14 @@ void QgisApp::saveAsRasterFile( QgsRasterLayer *rasterLayer )
if ( !projector )
{
QgsDebugMsg( QStringLiteral( "Cannot get pipe projector" ) );
return;
return QString();
}
projector->setCrs( rasterLayer->crs(), d.outputCrs() );
}

if ( !pipe->last() )
{
return;
return QString();
}
fileWriter.setCreateOptions( d.createOptions() );

@@ -7309,26 +7310,28 @@ void QgisApp::saveAsRasterFile( QgsRasterLayer *rasterLayer )
} );

QgsApplication::taskManager()->addTask( writerTask );
return d.outputFileName();
}


void QgisApp::saveAsFile( QgsMapLayer *layer, bool onlySelected )
QString QgisApp::saveAsFile( QgsMapLayer *layer, const bool onlySelected, const bool defaultToAddToMap )
{
if ( !layer )
layer = activeLayer();

if ( !layer )
return;
return QString();

QgsMapLayer::LayerType layerType = layer->type();
if ( layerType == QgsMapLayer::RasterLayer )
{
saveAsRasterFile( qobject_cast<QgsRasterLayer *>( layer ) );
return saveAsRasterFile( qobject_cast<QgsRasterLayer *>( layer ), defaultToAddToMap );
}
else if ( layerType == QgsMapLayer::VectorLayer )
{
saveAsVectorFileGeneral( qobject_cast<QgsVectorLayer *>( layer ), true, onlySelected );
return saveAsVectorFileGeneral( qobject_cast<QgsVectorLayer *>( layer ), true, onlySelected, defaultToAddToMap );
}
return QString();
}

void QgisApp::makeMemoryLayerPermanent( QgsVectorLayer *layer )
@@ -7371,7 +7374,7 @@ void QgisApp::makeMemoryLayerPermanent( QgsVectorLayer *layer )
}
};

saveAsVectorFileGeneral( layer, true, false, onSuccess, onFailure, 0, tr( "Save Scratch Layer" ) );
saveAsVectorFileGeneral( layer, true, false, true, onSuccess, onFailure, 0, tr( "Save Scratch Layer" ) );
}

void QgisApp::saveAsLayerDefinition()
@@ -7475,15 +7478,15 @@ QgisAppFieldValueConverter *QgisAppFieldValueConverter::clone() const

///@endcond

void QgisApp::saveAsVectorFileGeneral( QgsVectorLayer *vlayer, bool symbologyOption, bool onlySelected )
QString QgisApp::saveAsVectorFileGeneral( QgsVectorLayer *vlayer, bool symbologyOption, bool onlySelected, bool defaultToAddToMap )
{
if ( !vlayer )
{
vlayer = qobject_cast<QgsVectorLayer *>( activeLayer() ); // FIXME: output of multiple layers at once?
}

if ( !vlayer )
return;
return QString();

const QString layerId = vlayer->id();

@@ -7521,10 +7524,10 @@ void QgisApp::saveAsVectorFileGeneral( QgsVectorLayer *vlayer, bool symbologyOpt
}
};

saveAsVectorFileGeneral( vlayer, symbologyOption, onlySelected, onSuccess, onFailure );
return saveAsVectorFileGeneral( vlayer, symbologyOption, onlySelected, defaultToAddToMap, onSuccess, onFailure );
}

void QgisApp::saveAsVectorFileGeneral( QgsVectorLayer *vlayer, bool symbologyOption, bool onlySelected, const std::function<void( const QString &, bool, const QString &, const QString &, const QString & )> &onSuccess, const std::function<void ( int, const QString & )> &onFailure, int options, const QString &dialogTitle )
QString QgisApp::saveAsVectorFileGeneral( QgsVectorLayer *vlayer, bool symbologyOption, bool onlySelected, bool defaultToAddToMap, const std::function<void( const QString &, bool, const QString &, const QString &, const QString & )> &onSuccess, const std::function<void ( int, const QString & )> &onFailure, int options, const QString &dialogTitle )
{
QgsCoordinateReferenceSystem destCRS;

@@ -7540,11 +7543,13 @@ void QgisApp::saveAsVectorFileGeneral( QgsVectorLayer *vlayer, bool symbologyOpt
dialog->setMapCanvas( mMapCanvas );
dialog->setIncludeZ( QgsWkbTypes::hasZ( vlayer->wkbType() ) );
dialog->setOnlySelected( onlySelected );
dialog->setAddToCanvas( defaultToAddToMap );

QString vectorFilename;
if ( dialog->exec() == QDialog::Accepted )
{
QString encoding = dialog->encoding();
QString vectorFilename = dialog->filename();
vectorFilename = dialog->filename();
QString format = dialog->format();
QStringList datasourceOptions = dialog->datasourceOptions();
bool autoGeometryType = dialog->automaticGeometryType();
@@ -7612,6 +7617,7 @@ void QgisApp::saveAsVectorFileGeneral( QgsVectorLayer *vlayer, bool symbologyOpt
}

delete dialog;
return vectorFilename;
}

void QgisApp::layerProperties()
@@ -703,7 +703,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow

public slots:
//! save current vector layer
void saveAsFile( QgsMapLayer *layer = nullptr, bool onlySelected = false );
QString saveAsFile( QgsMapLayer *layer = nullptr, bool onlySelected = false, bool defaultToAddToMap = true );

/**
* Makes a memory layer permanent, by prompting users to save the layer to a disk-based (OGR)
@@ -716,7 +716,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
//! save qrl definition for the current layer
void saveAsLayerDefinition();
//! save current raster layer
void saveAsRasterFile( QgsRasterLayer *layer = nullptr );
QString saveAsRasterFile( QgsRasterLayer *layer = nullptr, bool defaultAddToCanvas = true );
//! Process the list of URIs that have been dropped in QGIS
void handleDropUriList( const QgsMimeDataUtils::UriList &lst );
//! Convenience function to open either a project or a layer file.
@@ -1841,16 +1841,16 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow

void setLayoutAtlasFeature( QgsPrintLayout *layout, QgsMapLayer *layer, const QgsFeature &feat );

void saveAsVectorFileGeneral( QgsVectorLayer *vlayer = nullptr, bool symbologyOption = true, bool onlySelected = false );
QString saveAsVectorFileGeneral( QgsVectorLayer *vlayer = nullptr, bool symbologyOption = true, bool onlySelected = false, bool defaultToAddToMap = true );

void saveAsVectorFileGeneral( QgsVectorLayer *vlayer, bool symbologyOption, bool onlySelected,
const std::function< void ( const QString &newFilename,
bool addToCanvas,
const QString &layerName,
const QString &encoding,
const QString &vectorFileName )> &onSuccess, const std::function< void ( int error, const QString &errorMessage ) > &onFailure,
int dialogOptions = QgsVectorLayerSaveAsDialog::AllOptions,
const QString &dialogTitle = QString() );
QString saveAsVectorFileGeneral( QgsVectorLayer *vlayer, bool symbologyOption, bool onlySelected, bool defaultToAddToMap,
const std::function< void ( const QString &newFilename,
bool addToCanvas,
const QString &layerName,
const QString &encoding,
const QString &vectorFileName )> &onSuccess, const std::function< void ( int error, const QString &errorMessage ) > &onFailure,
int dialogOptions = QgsVectorLayerSaveAsDialog::AllOptions,
const QString &dialogTitle = QString() );

//! Sets project properties, including map untis
void projectProperties( const QString &currentPage = QString() );
@@ -18,6 +18,7 @@
#include "qgsstyle.h"
#include "qgisapp.h"
#include "qgslayoutmanagerdialog.h"
#include "qgsrasterlayer.h"

QgsAppWindowManager::~QgsAppWindowManager()
{
@@ -46,6 +47,16 @@ QWidget *QgsAppWindowManager::openStandardDialog( QgsWindowManagerInterface::Sta
return nullptr;
}

QString QgsAppWindowManager::executeExportVectorLayerDialog( QgsVectorLayer *layer )
{
return QgisApp::instance()->saveAsFile( layer, false, false );
}

QString QgsAppWindowManager::executeExportRasterLayerDialog( QgsRasterLayer *layer )
{
return QgisApp::instance()->saveAsFile( layer, false, false );
}

QWidget *QgsAppWindowManager::openApplicationDialog( QgsAppWindowManager::ApplicationDialog dialog )
{
switch ( dialog )
@@ -41,6 +41,8 @@ class QgsAppWindowManager : public QgsWindowManagerInterface
~QgsAppWindowManager();

QWidget *openStandardDialog( QgsWindowManagerInterface::StandardDialog dialog ) override;
QString executeExportVectorLayerDialog( QgsVectorLayer *layer ) override;
QString executeExportRasterLayerDialog( QgsRasterLayer *layer ) override;

/**
* Opens an instance of a application QGIS dialog. Depending on the dialog,
@@ -861,6 +861,11 @@ bool QgsVectorLayerSaveAsDialog::addToCanvas() const
return mAddToCanvas->isChecked();
}

void QgsVectorLayerSaveAsDialog::setAddToCanvas( bool enabled )
{
mAddToCanvas->setChecked( enabled );
}

int QgsVectorLayerSaveAsDialog::symbologyExport() const
{
return mSymbologyExportComboBox->currentData().toInt();
@@ -65,8 +65,22 @@ class GUI_EXPORT QgsVectorLayerSaveAsDialog : public QDialog, private Ui::QgsVec
QgsAttributeList selectedAttributes() const;
//! Returns selected attributes that must be exported with their displayed values instead of their raw values. Added in QGIS 2.16
QgsAttributeList attributesAsDisplayedValues() const;

/**
* Returns true if the "add to canvas" checkbox is checked.
*
* \see setAddToCanvas()
*/
bool addToCanvas() const;

/**
* Sets whether the "add to canvas" checkbox should be \a checked.
*
* \see addToCanvas()
* \since QGIS 3.6
*/
void setAddToCanvas( bool checked );

/**
* Returns type of symbology export.
0: No symbology

0 comments on commit 7ac5215

Please sign in to comment.
You can’t perform that action at this time.