Skip to content

Commit

Permalink
Handle gpkg vectors and rasters with ogr data items
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Sep 18, 2017
1 parent 6bc1d1f commit 7cf2636
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 15 deletions.
29 changes: 29 additions & 0 deletions src/providers/gdal/qgsgdaldataitems.cpp
Expand Up @@ -241,12 +241,32 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
#endif #endif
} }


// Filters out the OGR/GDAL supported formats that can contain multiple layers
// and should be treated like a DB: GeoPackage and SQLite
// NOTE: this formats are scanned for rasters too and they are handled
// by the "ogr" provider. For this reason they must
// be skipped by "gdal" provider or the rasters will be listed
// twice. ogrSupportedDbLayersExtensions must be kept in sync
// with the companion variable (same name) in the ogr provider
// class
// TODO: add more OGR supported multiple layers formats here!
QStringList ogrSupportedDbLayersExtensions;
ogrSupportedDbLayersExtensions << QLatin1String( "gpkg" ) << QLatin1String( "sqlite" ) << QLatin1String( "db" );
QStringList ogrSupportedDbDriverNames;
ogrSupportedDbDriverNames << QLatin1String( "GPKG" ) << QLatin1String( "db" );

// return item without testing if: // return item without testing if:
// scanExtSetting // scanExtSetting
// or zipfile and scan zip == "Basic scan" // or zipfile and scan zip == "Basic scan"
if ( scanExtSetting || if ( scanExtSetting ||
( ( is_vsizip || is_vsitar ) && scanZipSetting == QLatin1String( "basic" ) ) ) ( ( is_vsizip || is_vsitar ) && scanZipSetting == QLatin1String( "basic" ) ) )
{ {
// Skip this layer if it's handled by ogr:
if ( ogrSupportedDbLayersExtensions.contains( suffix ) )
{
return nullptr;
}

// if this is a VRT file make sure it is raster VRT to avoid duplicates // if this is a VRT file make sure it is raster VRT to avoid duplicates
if ( suffix == QLatin1String( "vrt" ) ) if ( suffix == QLatin1String( "vrt" ) )
{ {
Expand Down Expand Up @@ -283,6 +303,15 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
return nullptr; return nullptr;
} }


GDALDriverH hDriver = GDALGetDatasetDriver( hDS );
QString ogrDriverName = GDALGetDriverShortName( hDriver );

// Skip this layer if it's handled by ogr:
if ( ogrSupportedDbDriverNames.contains( ogrDriverName ) )
{
return nullptr;
}

QStringList sublayers = QgsGdalProvider::subLayers( hDS ); QStringList sublayers = QgsGdalProvider::subLayers( hDS );


GDALClose( hDS ); GDALClose( hDS );
Expand Down
33 changes: 18 additions & 15 deletions src/providers/ogr/qgsogrdataitems.cpp
Expand Up @@ -578,6 +578,8 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
// TODO: add more OGR supported multiple layers formats here! // TODO: add more OGR supported multiple layers formats here!
QStringList ogrSupportedDbLayersExtensions; QStringList ogrSupportedDbLayersExtensions;
ogrSupportedDbLayersExtensions << QLatin1String( "gpkg" ) << QLatin1String( "sqlite" ) << QLatin1String( "db" ); ogrSupportedDbLayersExtensions << QLatin1String( "gpkg" ) << QLatin1String( "sqlite" ) << QLatin1String( "db" );
QStringList ogrSupportedDbDriverNames;
ogrSupportedDbDriverNames << QLatin1String( "GPKG" ) << QLatin1String( "db" );


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


// Slow track: scan file contents
QgsDataItem *item = nullptr;

// test that file is valid with OGR // test that file is valid with OGR
OGRRegisterAll(); OGRRegisterAll();
GDALDriverH hDriver; OGRSFDriverH hDriver;
// do not print errors, but write to debug // do not print errors, but write to debug
CPLPushErrorHandler( CPLQuietErrorHandler ); CPLPushErrorHandler( CPLQuietErrorHandler );
CPLErrorReset(); CPLErrorReset();
GDALDatasetH hDataSource = QgsOgrProviderUtils::GDALOpenWrapper( path.toUtf8().constData(), false, &hDriver ); OGRDataSourceH hDataSource = QgsOgrProviderUtils::GDALOpenWrapper( path.toUtf8().constData(), false, &hDriver );
CPLPopErrorHandler(); CPLPopErrorHandler();


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


QgsDebugMsgLevel( QString( "GDAL Driver : %1" ).arg( GDALGetDriverShortName( hDriver ) ), 2 ); QgsDebugMsgLevel( QString( "GDAL Driver : %1" ).arg( OGR_Dr_GetName( hDriver ) ), 2 );

QString ogrDriverName = OGR_Dr_GetName( hDriver );
QgsDataItem *item = nullptr;

int numLayers = OGR_DS_GetLayerCount( hDataSource ); int numLayers = OGR_DS_GetLayerCount( hDataSource );
if ( numLayers == 1 )
// GeoPackage needs a specialized data item, mainly because of raster deletion not
// yet implemented in GDAL (2.2.1)
if ( ogrDriverName == QLatin1String( "GPKG" ) )
{ {
QgsDebugMsgLevel( QString( "using name = %1" ).arg( name ), 2 ); item = new QgsGeoPackageCollectionItem( parentItem, name, path );
item = dataItemForLayer( parentItem, name, path, hDataSource, 0 );
} }
else if ( numLayers > 1 ) else if ( numLayers > 1 || ogrSupportedDbDriverNames.contains( ogrDriverName ) )
{ {
QgsDebugMsgLevel( QString( "using name = %1" ).arg( name ), 2 );
item = new QgsOgrDataCollectionItem( parentItem, name, path ); item = new QgsOgrDataCollectionItem( parentItem, name, path );
} }
else if ( suffix.compare( QLatin1String( "gpkg" ), Qt::CaseInsensitive ) == 0 ) else
{ {
item = new QgsGeoPackageCollectionItem( parentItem, name, path ); item = dataItemForLayer( parentItem, name, path, hDataSource, 0 );
} }

OGR_DS_Destroy( hDataSource );
GDALClose( hDataSource );
return item; return item;
} }

0 comments on commit 7cf2636

Please sign in to comment.