Skip to content

Commit 7cf2636

Browse files
committed
Handle gpkg vectors and rasters with ogr data items
1 parent 6bc1d1f commit 7cf2636

File tree

2 files changed

+47
-15
lines changed

2 files changed

+47
-15
lines changed

src/providers/gdal/qgsgdaldataitems.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,32 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
241241
#endif
242242
}
243243

244+
// Filters out the OGR/GDAL supported formats that can contain multiple layers
245+
// and should be treated like a DB: GeoPackage and SQLite
246+
// NOTE: this formats are scanned for rasters too and they are handled
247+
// by the "ogr" provider. For this reason they must
248+
// be skipped by "gdal" provider or the rasters will be listed
249+
// twice. ogrSupportedDbLayersExtensions must be kept in sync
250+
// with the companion variable (same name) in the ogr provider
251+
// class
252+
// TODO: add more OGR supported multiple layers formats here!
253+
QStringList ogrSupportedDbLayersExtensions;
254+
ogrSupportedDbLayersExtensions << QLatin1String( "gpkg" ) << QLatin1String( "sqlite" ) << QLatin1String( "db" );
255+
QStringList ogrSupportedDbDriverNames;
256+
ogrSupportedDbDriverNames << QLatin1String( "GPKG" ) << QLatin1String( "db" );
257+
244258
// return item without testing if:
245259
// scanExtSetting
246260
// or zipfile and scan zip == "Basic scan"
247261
if ( scanExtSetting ||
248262
( ( is_vsizip || is_vsitar ) && scanZipSetting == QLatin1String( "basic" ) ) )
249263
{
264+
// Skip this layer if it's handled by ogr:
265+
if ( ogrSupportedDbLayersExtensions.contains( suffix ) )
266+
{
267+
return nullptr;
268+
}
269+
250270
// if this is a VRT file make sure it is raster VRT to avoid duplicates
251271
if ( suffix == QLatin1String( "vrt" ) )
252272
{
@@ -283,6 +303,15 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
283303
return nullptr;
284304
}
285305

306+
GDALDriverH hDriver = GDALGetDatasetDriver( hDS );
307+
QString ogrDriverName = GDALGetDriverShortName( hDriver );
308+
309+
// Skip this layer if it's handled by ogr:
310+
if ( ogrSupportedDbDriverNames.contains( ogrDriverName ) )
311+
{
312+
return nullptr;
313+
}
314+
286315
QStringList sublayers = QgsGdalProvider::subLayers( hDS );
287316

288317
GDALClose( hDS );

src/providers/ogr/qgsogrdataitems.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,8 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
578578
// TODO: add more OGR supported multiple layers formats here!
579579
QStringList ogrSupportedDbLayersExtensions;
580580
ogrSupportedDbLayersExtensions << QLatin1String( "gpkg" ) << QLatin1String( "sqlite" ) << QLatin1String( "db" );
581+
QStringList ogrSupportedDbDriverNames;
582+
ogrSupportedDbDriverNames << QLatin1String( "GPKG" ) << QLatin1String( "db" );
581583

582584
// Fast track: return item without testing if:
583585
// scanExtSetting or zipfile and scan zip == "Basic scan"
@@ -624,13 +626,16 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
624626
return item;
625627
}
626628

629+
// Slow track: scan file contents
630+
QgsDataItem *item = nullptr;
631+
627632
// test that file is valid with OGR
628633
OGRRegisterAll();
629-
GDALDriverH hDriver;
634+
OGRSFDriverH hDriver;
630635
// do not print errors, but write to debug
631636
CPLPushErrorHandler( CPLQuietErrorHandler );
632637
CPLErrorReset();
633-
GDALDatasetH hDataSource = QgsOgrProviderUtils::GDALOpenWrapper( path.toUtf8().constData(), false, &hDriver );
638+
OGRDataSourceH hDataSource = QgsOgrProviderUtils::GDALOpenWrapper( path.toUtf8().constData(), false, &hDriver );
634639
CPLPopErrorHandler();
635640

636641
if ( ! hDataSource )
@@ -639,26 +644,24 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
639644
return nullptr;
640645
}
641646

642-
QgsDebugMsgLevel( QString( "GDAL Driver : %1" ).arg( GDALGetDriverShortName( hDriver ) ), 2 );
643-
644-
QgsDataItem *item = nullptr;
645-
647+
QgsDebugMsgLevel( QString( "GDAL Driver : %1" ).arg( OGR_Dr_GetName( hDriver ) ), 2 );
648+
QString ogrDriverName = OGR_Dr_GetName( hDriver );
646649
int numLayers = OGR_DS_GetLayerCount( hDataSource );
647-
if ( numLayers == 1 )
650+
651+
// GeoPackage needs a specialized data item, mainly because of raster deletion not
652+
// yet implemented in GDAL (2.2.1)
653+
if ( ogrDriverName == QLatin1String( "GPKG" ) )
648654
{
649-
QgsDebugMsgLevel( QString( "using name = %1" ).arg( name ), 2 );
650-
item = dataItemForLayer( parentItem, name, path, hDataSource, 0 );
655+
item = new QgsGeoPackageCollectionItem( parentItem, name, path );
651656
}
652-
else if ( numLayers > 1 )
657+
else if ( numLayers > 1 || ogrSupportedDbDriverNames.contains( ogrDriverName ) )
653658
{
654-
QgsDebugMsgLevel( QString( "using name = %1" ).arg( name ), 2 );
655659
item = new QgsOgrDataCollectionItem( parentItem, name, path );
656660
}
657-
else if ( suffix.compare( QLatin1String( "gpkg" ), Qt::CaseInsensitive ) == 0 )
661+
else
658662
{
659-
item = new QgsGeoPackageCollectionItem( parentItem, name, path );
663+
item = dataItemForLayer( parentItem, name, path, hDataSource, 0 );
660664
}
661-
662-
GDALClose( hDataSource );
665+
OGR_DS_Destroy( hDataSource );
663666
return item;
664667
}

0 commit comments

Comments
 (0)