Skip to content

Commit 384cabd

Browse files
committed
Geopackage: handle raster drop in the browser
1 parent 13c9e1d commit 384cabd

File tree

1 file changed

+75
-51
lines changed

1 file changed

+75
-51
lines changed

src/providers/ogr/qgsgeopackagedataitems.cpp

+75-51
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@
2323
#include "qgsvectorlayer.h"
2424
#include "qgsrasterlayer.h"
2525
#include "qgsogrprovider.h"
26+
#include "qgscplerrorhandler.h"
2627
#include "qgsnewgeopackagelayerdialog.h"
2728
#include "qgsmessageoutput.h"
2829
#include "qgsvectorlayerexporter.h"
2930
#include "gdal.h"
31+
#include "gdal_utils.h"
3032

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

324326
QString uri;
327+
// This sends OGR/GDAL errors to the message log
328+
QgsCPLErrorHandler handler;
325329

326330
QStringList importResults;
327331
bool hasError = false;
328332

329333
QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( data );
330334
Q_FOREACH ( const QgsMimeDataUtils::Uri &u, lst )
331335
{
332-
if ( u.layerType == QStringLiteral( "vector" ) )
336+
// Check that we are not copying over self
337+
if ( u.uri.startsWith( mPath ) )
333338
{
334-
// Check that we are not copying over self
335-
if ( u.uri.startsWith( mPath ) )
336-
{
337-
importResults.append( tr( "You cannot import layer %1 over itself!" ).arg( u.name ) );
338-
hasError = true;
339+
importResults.append( tr( "You cannot import layer %1 over itself!" ).arg( u.name ) );
340+
hasError = true;
339341

342+
}
343+
else
344+
{
345+
QgsMapLayer *srcLayer;
346+
bool owner;
347+
bool isVector = false;
348+
QString error;
349+
// Common checks for raster and vector
350+
// aspatial is treated like vector
351+
if ( u.layerType == QStringLiteral( "vector" ) )
352+
{
353+
// open the source layer
354+
srcLayer = u.vectorLayer( owner, error );
355+
isVector = true;
340356
}
341357
else
342358
{
343-
// open the source layer
344-
bool owner;
345-
QString error;
346-
QgsVectorLayer *srcLayer = u.vectorLayer( owner, error );
347-
if ( !srcLayer )
348-
{
349-
importResults.append( tr( "%1: %2" ).arg( u.name ).arg( error ) );
350-
hasError = true;
351-
continue;
352-
}
359+
srcLayer = u.rasterLayer( owner, error );
360+
}
361+
if ( !srcLayer )
362+
{
363+
importResults.append( tr( "%1: %2" ).arg( u.name ).arg( error ) );
364+
hasError = true;
365+
continue;
366+
}
353367

354-
if ( srcLayer->isValid() )
355-
{
356-
uri = mPath;
357-
QgsDebugMsgLevel( "URI " + uri, 3 );
368+
if ( srcLayer->isValid() )
369+
{
370+
uri = mPath;
371+
QgsDebugMsgLevel( "URI " + uri, 3 );
358372

359-
// check if the destination layer already exists
360-
bool exists = false;
361-
// Q_FOREACH won't detach ...
362-
for ( const auto child : children() )
373+
// check if the destination layer already exists
374+
bool exists = false;
375+
// Q_FOREACH won't detach ...
376+
for ( const auto child : children() )
377+
{
378+
if ( child->name() == u.name )
363379
{
364-
if ( child->name() == u.name )
365-
{
366-
exists = true;
367-
}
380+
exists = true;
368381
}
369-
if ( ! exists || QMessageBox::question( nullptr, tr( "Overwrite Layer" ),
370-
tr( "Destination layer <b>%1</b> already exists. Do you want to overwrite it?" ).arg( u.name ), QMessageBox::Yes | QMessageBox::No ) == QMessageBox::Yes )
382+
}
383+
if ( ! exists || QMessageBox::question( nullptr, tr( "Overwrite Layer" ),
384+
tr( "Destination layer <b>%1</b> already exists. Do you want to overwrite it?" ).arg( u.name ), QMessageBox::Yes | QMessageBox::No ) == QMessageBox::Yes )
385+
{
386+
if ( isVector )
371387
{
372-
388+
QgsVectorLayer *vectorSrcLayer = dynamic_cast < QgsVectorLayer * >( srcLayer );
373389
QVariantMap options;
374390
options.insert( QStringLiteral( "driverName" ), QStringLiteral( "GPKG" ) );
375391
options.insert( QStringLiteral( "update" ), true );
376392
options.insert( QStringLiteral( "overwrite" ), true );
377393
options.insert( QStringLiteral( "layerName" ), u.name );
378394

379-
std::unique_ptr< QgsVectorLayerExporterTask > exportTask( new QgsVectorLayerExporterTask( srcLayer, uri, QStringLiteral( "ogr" ), srcLayer->crs(), options, owner ) );
380-
395+
std::unique_ptr< QgsVectorLayerExporterTask > exportTask( new QgsVectorLayerExporterTask( vectorSrcLayer, uri, QStringLiteral( "ogr" ), vectorSrcLayer->crs(), options, owner ) );
381396
// when export is successful:
382397
connect( exportTask.get(), &QgsVectorLayerExporterTask::exportComplete, this, [ = ]()
383398
{
@@ -400,24 +415,34 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
400415

401416
QgsApplication::taskManager()->addTask( exportTask.release() );
402417
}
403-
}
404-
else
405-
{
406-
importResults.append( tr( "%1: Not a valid layer!" ).arg( u.name ) );
407-
hasError = true;
408-
}
409-
}
410-
}
411-
else
412-
{
413-
// TODO: implement raster import
414-
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
415-
output->setTitle( tr( "Import to GeoPackage database failed" ) );
416-
output->setMessage( tr( "Failed to import some layers!\n\n" ) + QStringLiteral( "Raster import is not yet implemented!\n" ), QgsMessageOutput::MessageText );
417-
output->showMessage();
418-
}
418+
else // Import raster
419+
{
420+
// In case we need it
421+
// QgsRasterLayer* rasterSrcLayer = dynamic_cast < QgsRasterLayer* > ( srcLayer );
422+
423+
const char *args[] = { "-of", "gpkg", "-co", QStringLiteral( "RASTER_TABLE=%1" ).arg( u.name ).toUtf8().constData(), "-co", "APPEND_SUBDATASET=YES", nullptr };
424+
GDALTranslateOptions *psOptions = GDALTranslateOptionsNew( ( char ** )args, nullptr );
425+
GDALDatasetH hSrcDS = GDALOpen( u.uri.toUtf8().constData(), GA_ReadOnly );
426+
CPLErrorReset();
427+
GDALDatasetH hOutDS = GDALTranslate( mPath.toUtf8().constData(), hSrcDS, psOptions, NULL );
428+
if ( ! hOutDS )
429+
{
430+
importResults.append( tr( "Failed to import layer %1! See the message logs for details.\n\n" ).arg( u.name ) );
431+
hasError = true;
419432

420-
}
433+
}
434+
GDALClose( hSrcDS );
435+
GDALTranslateOptionsFree( psOptions );
436+
}
437+
} // do not overwrite
438+
}
439+
else
440+
{
441+
importResults.append( tr( "%1: Not a valid layer!" ).arg( u.name ) );
442+
hasError = true;
443+
}
444+
} // check for self copy
445+
} // for each
421446

422447
if ( hasError )
423448
{
@@ -426,7 +451,6 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
426451
output->setMessage( tr( "Failed to import some layers!\n\n" ) + importResults.join( QStringLiteral( "\n" ) ), QgsMessageOutput::MessageText );
427452
output->showMessage();
428453
}
429-
430454
return true;
431455
}
432456

0 commit comments

Comments
 (0)