Skip to content

Commit f15622f

Browse files
committed
Properly support OGR sublayers (with createChildren) to avoid #4400
1 parent bfb4d0f commit f15622f

File tree

3 files changed

+134
-102
lines changed

3 files changed

+134
-102
lines changed

src/providers/gdal/qgsgdalprovider.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,6 +1941,7 @@ QgsGdalLayerItem::QgsGdalLayerItem( QgsDataItem* parent,
19411941
: QgsLayerItem( parent, name, path, uri, QgsLayerItem::Raster, "gdal" )
19421942
{
19431943
mToolTip = uri;
1944+
mPopulated = true; // children are not expected
19441945
}
19451946

19461947
QgsGdalLayerItem::~QgsGdalLayerItem()

src/providers/ogr/qgsogrprovider.cpp

Lines changed: 124 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -2272,6 +2272,7 @@ QgsOgrLayerItem::QgsOgrLayerItem( QgsDataItem* parent,
22722272
: QgsLayerItem( parent, name, path, uri, layerType, "ogr" )
22732273
{
22742274
mToolTip = uri;
2275+
mPopulated = true; // children are not expected
22752276
}
22762277

22772278
QgsOgrLayerItem::~QgsOgrLayerItem()
@@ -2358,135 +2359,156 @@ bool QgsOgrLayerItem::setCrs( QgsCoordinateReferenceSystem crs )
23582359
return false;
23592360
}
23602361

2362+
2363+
static QgsOgrLayerItem* dataItemForLayer( QgsDataItem* parentItem, QString name, QString path, OGRDataSourceH hDataSource, int layerId )
2364+
{
2365+
OGRLayerH hLayer = OGR_DS_GetLayer( hDataSource, layerId );
2366+
OGRFeatureDefnH hDef = OGR_L_GetLayerDefn( hLayer );
2367+
2368+
QgsLayerItem::LayerType layerType = QgsLayerItem::Vector;
2369+
int ogrType = getOgrGeomType( hLayer );
2370+
switch ( ogrType )
2371+
{
2372+
case wkbUnknown:
2373+
case wkbGeometryCollection:
2374+
break;
2375+
case wkbNone:
2376+
layerType = QgsLayerItem::TableLayer;
2377+
break;
2378+
case wkbPoint:
2379+
case wkbMultiPoint:
2380+
case wkbPoint25D:
2381+
case wkbMultiPoint25D:
2382+
layerType = QgsLayerItem::Point;
2383+
break;
2384+
case wkbLineString:
2385+
case wkbMultiLineString:
2386+
case wkbLineString25D:
2387+
case wkbMultiLineString25D:
2388+
layerType = QgsLayerItem::Line;
2389+
break;
2390+
case wkbPolygon:
2391+
case wkbMultiPolygon:
2392+
case wkbPolygon25D:
2393+
case wkbMultiPolygon25D:
2394+
layerType = QgsLayerItem::Polygon;
2395+
break;
2396+
default:
2397+
break;
2398+
}
2399+
2400+
QgsDebugMsg( QString( "ogrType = %1 layertype = %2" ).arg( ogrType ).arg( layerType ) );
2401+
2402+
QString layerUri = path;
2403+
2404+
if ( name.isEmpty() )
2405+
{
2406+
// we are in a collection
2407+
name = FROM8( OGR_FD_GetName( hDef ) );
2408+
QgsDebugMsg( "OGR layer name : " + name );
2409+
2410+
layerUri += "|layerid=" + QString::number( layerId );
2411+
2412+
path += "/" + name;
2413+
}
2414+
2415+
QgsDebugMsg( "OGR layer uri : " + layerUri );
2416+
2417+
return new QgsOgrLayerItem( parentItem, name, path, layerUri, layerType );
2418+
}
2419+
23612420
QGISEXTERN QgsDataItem * dataItem( QString thePath, QgsDataItem* parentItem )
23622421
{
23632422
if ( thePath.isEmpty() )
23642423
return 0;
23652424

23662425
QFileInfo info( thePath );
2367-
if ( info.isFile() )
2426+
if ( !info.isFile() )
2427+
return 0;
2428+
2429+
// We have to filter by extensions, otherwise e.g. all Shapefile files are displayed
2430+
// because OGR drive can open also .dbf, .shx.
2431+
QStringList myExtensions = fileExtensions();
2432+
if ( myExtensions.indexOf( info.suffix().toLower() ) < 0 )
23682433
{
2369-
// We have to filter by extensions, otherwise e.g. all Shapefile files are displayed
2370-
// because OGR drive can open also .dbf, .shx.
2371-
QStringList myExtensions = fileExtensions();
2372-
if ( myExtensions.indexOf( info.suffix().toLower() ) < 0 )
2434+
bool matches = false;
2435+
foreach( QString wildcard, wildcards() )
23732436
{
2374-
bool matches = false;
2375-
foreach( QString wildcard, wildcards() )
2437+
QRegExp rx( wildcard, Qt::CaseInsensitive, QRegExp::Wildcard );
2438+
if ( rx.exactMatch( info.fileName() ) )
23762439
{
2377-
QRegExp rx( wildcard, Qt::CaseInsensitive, QRegExp::Wildcard );
2378-
if ( rx.exactMatch( info.fileName() ) )
2379-
{
2380-
matches = true;
2381-
break;
2382-
}
2440+
matches = true;
2441+
break;
23832442
}
2384-
if ( !matches )
2385-
return 0;
2386-
}
2387-
2388-
// .dbf should probably appear if .shp is not present
2389-
if ( info.suffix().toLower() == "dbf" )
2390-
{
2391-
QString pathShp = thePath.left( thePath.count() - 4 ) + ".shp";
2392-
if ( QFileInfo( pathShp ).exists() )
2393-
return 0;
23942443
}
2444+
if ( !matches )
2445+
return 0;
2446+
}
23952447

2396-
OGRRegisterAll();
2397-
OGRSFDriverH hDriver;
2398-
OGRDataSourceH hDataSource = OGROpen( TO8F( thePath ), false, &hDriver );
2399-
2400-
if ( !hDataSource )
2448+
// .dbf should probably appear if .shp is not present
2449+
if ( info.suffix().toLower() == "dbf" )
2450+
{
2451+
QString pathShp = thePath.left( thePath.count() - 4 ) + ".shp";
2452+
if ( QFileInfo( pathShp ).exists() )
24012453
return 0;
2454+
}
24022455

2403-
QString driverName = OGR_Dr_GetName( hDriver );
2404-
QgsDebugMsg( "OGR Driver : " + driverName );
2456+
OGRRegisterAll();
2457+
OGRSFDriverH hDriver;
2458+
OGRDataSourceH hDataSource = OGROpen( TO8F( thePath ), false, &hDriver );
24052459

2406-
int numLayers = OGR_DS_GetLayerCount( hDataSource );
2460+
if ( !hDataSource )
2461+
return 0;
24072462

2408-
if ( numLayers == 0 )
2409-
{
2410-
OGR_DS_Destroy( hDataSource );
2411-
return 0;
2412-
}
2463+
QString driverName = OGR_Dr_GetName( hDriver );
2464+
QgsDebugMsg( "OGR Driver : " + driverName );
24132465

2414-
QgsDataCollectionItem * collection = 0;
2415-
if ( numLayers > 1 )
2416-
{
2417-
collection = new QgsDataCollectionItem( parentItem, info.fileName(), thePath );
2418-
}
2466+
int numLayers = OGR_DS_GetLayerCount( hDataSource );
24192467

2420-
for ( int i = 0; i < numLayers; i++ )
2421-
{
2422-
OGRLayerH hLayer = OGR_DS_GetLayer( hDataSource, i );
2423-
OGRFeatureDefnH hDef = OGR_L_GetLayerDefn( hLayer );
2468+
QgsDataItem* item = 0;
24242469

2425-
QgsLayerItem::LayerType layerType = QgsLayerItem::Vector;
2426-
int ogrType = getOgrGeomType( hLayer );
2427-
switch ( ogrType )
2428-
{
2429-
case wkbUnknown:
2430-
case wkbGeometryCollection:
2431-
break;
2432-
case wkbNone:
2433-
layerType = QgsLayerItem::TableLayer;
2434-
break;
2435-
case wkbPoint:
2436-
case wkbMultiPoint:
2437-
case wkbPoint25D:
2438-
case wkbMultiPoint25D:
2439-
layerType = QgsLayerItem::Point;
2440-
break;
2441-
case wkbLineString:
2442-
case wkbMultiLineString:
2443-
case wkbLineString25D:
2444-
case wkbMultiLineString25D:
2445-
layerType = QgsLayerItem::Line;
2446-
break;
2447-
case wkbPolygon:
2448-
case wkbMultiPolygon:
2449-
case wkbPolygon25D:
2450-
case wkbMultiPolygon25D:
2451-
layerType = QgsLayerItem::Polygon;
2452-
break;
2453-
default:
2454-
break;
2455-
}
2470+
if ( numLayers == 1 )
2471+
{
2472+
QString name = info.completeBaseName();
2473+
item = dataItemForLayer( parentItem, name, thePath, hDataSource, 0 );
2474+
}
2475+
else if ( numLayers > 1 )
2476+
{
2477+
item = new QgsOgrDataCollectionItem( parentItem, info.fileName(), thePath );
2478+
}
24562479

2457-
QgsDebugMsg( QString( "ogrType = %1 layertype = %2" ).arg( ogrType ).arg( layerType ) );
2480+
OGR_DS_Destroy( hDataSource );
2481+
return item;
2482+
}
24582483

2459-
QString name = info.completeBaseName();
2484+
QgsOgrDataCollectionItem::QgsOgrDataCollectionItem( QgsDataItem* parent, QString name, QString path )
2485+
: QgsDataCollectionItem( parent, name, path )
2486+
{
2487+
}
24602488

2461-
QString layerName = FROM8( OGR_FD_GetName( hDef ) );
2462-
QgsDebugMsg( "OGR layer name : " + layerName );
2489+
QgsOgrDataCollectionItem::~QgsOgrDataCollectionItem()
2490+
{
2491+
}
24632492

2464-
QString path = thePath;
2465-
if ( numLayers > 1 )
2466-
{
2467-
name = layerName;
2468-
path += "/" + name;
2469-
}
2493+
QVector<QgsDataItem*> QgsOgrDataCollectionItem::createChildren()
2494+
{
2495+
QVector<QgsDataItem*> children;
24702496

2471-
QString layerUri = thePath;
2472-
if ( collection )
2473-
layerUri += "|layerid=" + QString::number( i );
2474-
QgsDebugMsg( "OGR layer uri : " + layerUri );
2497+
OGRSFDriverH hDriver;
2498+
OGRDataSourceH hDataSource = OGROpen( TO8F( mPath ), false, &hDriver );
2499+
if ( !hDataSource )
2500+
return children;
2501+
int numLayers = OGR_DS_GetLayerCount( hDataSource );
24752502

2476-
QgsOgrLayerItem * item = new QgsOgrLayerItem( collection ? collection : parentItem, name, path, layerUri, layerType );
2477-
if ( numLayers == 1 )
2478-
{
2479-
OGR_DS_Destroy( hDataSource );
2480-
return item;
2481-
}
2482-
collection->addChild( item );
2483-
}
2484-
collection->setPopulated();
2485-
OGR_DS_Destroy( hDataSource );
2486-
return collection;
2503+
for ( int i = 0; i < numLayers; i++ )
2504+
{
2505+
QgsOgrLayerItem* item = dataItemForLayer( this, QString(), mPath, hDataSource, i );
2506+
children.append( item );
24872507
}
24882508

2489-
return 0;
2509+
OGR_DS_Destroy( hDataSource );
2510+
2511+
return children;
24902512
}
24912513

24922514
QGISEXTERN QgsVectorLayerImport::ImportError createEmptyLayer(

src/providers/ogr/qgsogrprovider.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,3 +335,12 @@ class QgsOgrLayerItem : public QgsLayerItem
335335
Capability capabilities();
336336
};
337337

338+
class QgsOgrDataCollectionItem : public QgsDataCollectionItem
339+
{
340+
Q_OBJECT
341+
public:
342+
QgsOgrDataCollectionItem( QgsDataItem* parent, QString name, QString path );
343+
~QgsOgrDataCollectionItem();
344+
345+
QVector<QgsDataItem*> createChildren();
346+
};

0 commit comments

Comments
 (0)