Skip to content

Commit

Permalink
Geopackage: handle raster drop in the browser
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Aug 22, 2017
1 parent 13c9e1d commit 384cabd
Showing 1 changed file with 75 additions and 51 deletions.
126 changes: 75 additions & 51 deletions src/providers/ogr/qgsgeopackagedataitems.cpp
Expand Up @@ -23,10 +23,12 @@
#include "qgsvectorlayer.h" #include "qgsvectorlayer.h"
#include "qgsrasterlayer.h" #include "qgsrasterlayer.h"
#include "qgsogrprovider.h" #include "qgsogrprovider.h"
#include "qgscplerrorhandler.h"
#include "qgsnewgeopackagelayerdialog.h" #include "qgsnewgeopackagelayerdialog.h"
#include "qgsmessageoutput.h" #include "qgsmessageoutput.h"
#include "qgsvectorlayerexporter.h" #include "qgsvectorlayerexporter.h"
#include "gdal.h" #include "gdal.h"
#include "gdal_utils.h"


#include <QAction> #include <QAction>
#include <QMessageBox> #include <QMessageBox>
Expand Down Expand Up @@ -322,62 +324,75 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
return false; return false;


QString uri; QString uri;
// This sends OGR/GDAL errors to the message log
QgsCPLErrorHandler handler;


QStringList importResults; QStringList importResults;
bool hasError = false; bool hasError = false;


QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( data ); QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( data );
Q_FOREACH ( const QgsMimeDataUtils::Uri &u, lst ) Q_FOREACH ( const QgsMimeDataUtils::Uri &u, lst )
{ {
if ( u.layerType == QStringLiteral( "vector" ) ) // Check that we are not copying over self
if ( u.uri.startsWith( mPath ) )
{ {
// Check that we are not copying over self importResults.append( tr( "You cannot import layer %1 over itself!" ).arg( u.name ) );
if ( u.uri.startsWith( mPath ) ) hasError = true;
{
importResults.append( tr( "You cannot import layer %1 over itself!" ).arg( u.name ) );
hasError = true;


}
else
{
QgsMapLayer *srcLayer;
bool owner;
bool isVector = false;
QString error;
// Common checks for raster and vector
// aspatial is treated like vector
if ( u.layerType == QStringLiteral( "vector" ) )
{
// open the source layer
srcLayer = u.vectorLayer( owner, error );
isVector = true;
} }
else else
{ {
// open the source layer srcLayer = u.rasterLayer( owner, error );
bool owner; }
QString error; if ( !srcLayer )
QgsVectorLayer *srcLayer = u.vectorLayer( owner, error ); {
if ( !srcLayer ) importResults.append( tr( "%1: %2" ).arg( u.name ).arg( error ) );
{ hasError = true;
importResults.append( tr( "%1: %2" ).arg( u.name ).arg( error ) ); continue;
hasError = true; }
continue;
}


if ( srcLayer->isValid() ) if ( srcLayer->isValid() )
{ {
uri = mPath; uri = mPath;
QgsDebugMsgLevel( "URI " + uri, 3 ); QgsDebugMsgLevel( "URI " + uri, 3 );


// check if the destination layer already exists // check if the destination layer already exists
bool exists = false; bool exists = false;
// Q_FOREACH won't detach ... // Q_FOREACH won't detach ...
for ( const auto child : children() ) for ( const auto child : children() )
{
if ( child->name() == u.name )
{ {
if ( child->name() == u.name ) exists = true;
{
exists = true;
}
} }
if ( ! exists || QMessageBox::question( nullptr, tr( "Overwrite Layer" ), }
tr( "Destination layer <b>%1</b> already exists. Do you want to overwrite it?" ).arg( u.name ), QMessageBox::Yes | QMessageBox::No ) == QMessageBox::Yes ) if ( ! exists || QMessageBox::question( nullptr, tr( "Overwrite Layer" ),
tr( "Destination layer <b>%1</b> already exists. Do you want to overwrite it?" ).arg( u.name ), QMessageBox::Yes | QMessageBox::No ) == QMessageBox::Yes )
{
if ( isVector )
{ {

QgsVectorLayer *vectorSrcLayer = dynamic_cast < QgsVectorLayer * >( srcLayer );
QVariantMap options; QVariantMap options;
options.insert( QStringLiteral( "driverName" ), QStringLiteral( "GPKG" ) ); options.insert( QStringLiteral( "driverName" ), QStringLiteral( "GPKG" ) );
options.insert( QStringLiteral( "update" ), true ); options.insert( QStringLiteral( "update" ), true );
options.insert( QStringLiteral( "overwrite" ), true ); options.insert( QStringLiteral( "overwrite" ), true );
options.insert( QStringLiteral( "layerName" ), u.name ); options.insert( QStringLiteral( "layerName" ), u.name );


std::unique_ptr< QgsVectorLayerExporterTask > exportTask( new QgsVectorLayerExporterTask( srcLayer, uri, QStringLiteral( "ogr" ), srcLayer->crs(), options, owner ) ); std::unique_ptr< QgsVectorLayerExporterTask > exportTask( new QgsVectorLayerExporterTask( vectorSrcLayer, uri, QStringLiteral( "ogr" ), vectorSrcLayer->crs(), options, owner ) );

// when export is successful: // when export is successful:
connect( exportTask.get(), &QgsVectorLayerExporterTask::exportComplete, this, [ = ]() connect( exportTask.get(), &QgsVectorLayerExporterTask::exportComplete, this, [ = ]()
{ {
Expand All @@ -400,24 +415,34 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct


QgsApplication::taskManager()->addTask( exportTask.release() ); QgsApplication::taskManager()->addTask( exportTask.release() );
} }
} else // Import raster
else {
{ // In case we need it
importResults.append( tr( "%1: Not a valid layer!" ).arg( u.name ) ); // QgsRasterLayer* rasterSrcLayer = dynamic_cast < QgsRasterLayer* > ( srcLayer );
hasError = true;
} const char *args[] = { "-of", "gpkg", "-co", QStringLiteral( "RASTER_TABLE=%1" ).arg( u.name ).toUtf8().constData(), "-co", "APPEND_SUBDATASET=YES", nullptr };
} GDALTranslateOptions *psOptions = GDALTranslateOptionsNew( ( char ** )args, nullptr );
} GDALDatasetH hSrcDS = GDALOpen( u.uri.toUtf8().constData(), GA_ReadOnly );
else CPLErrorReset();
{ GDALDatasetH hOutDS = GDALTranslate( mPath.toUtf8().constData(), hSrcDS, psOptions, NULL );
// TODO: implement raster import if ( ! hOutDS )
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput(); {
output->setTitle( tr( "Import to GeoPackage database failed" ) ); importResults.append( tr( "Failed to import layer %1! See the message logs for details.\n\n" ).arg( u.name ) );
output->setMessage( tr( "Failed to import some layers!\n\n" ) + QStringLiteral( "Raster import is not yet implemented!\n" ), QgsMessageOutput::MessageText ); hasError = true;
output->showMessage();
}


} }
GDALClose( hSrcDS );
GDALTranslateOptionsFree( psOptions );
}
} // do not overwrite
}
else
{
importResults.append( tr( "%1: Not a valid layer!" ).arg( u.name ) );
hasError = true;
}
} // check for self copy
} // for each


if ( hasError ) if ( hasError )
{ {
Expand All @@ -426,7 +451,6 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
output->setMessage( tr( "Failed to import some layers!\n\n" ) + importResults.join( QStringLiteral( "\n" ) ), QgsMessageOutput::MessageText ); output->setMessage( tr( "Failed to import some layers!\n\n" ) + importResults.join( QStringLiteral( "\n" ) ), QgsMessageOutput::MessageText );
output->showMessage(); output->showMessage();
} }

return true; return true;
} }


Expand Down

0 comments on commit 384cabd

Please sign in to comment.