Skip to content

Commit

Permalink
[OGR provider] Speed-up layer addition to the canvas when selected fr…
Browse files Browse the repository at this point in the history
…om the data source manager
  • Loading branch information
rouault committed Oct 20, 2017
1 parent 8f3d44d commit c9b0a2b
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 109 deletions.
221 changes: 112 additions & 109 deletions src/providers/ogr/qgsogrprovider.cpp
Expand Up @@ -688,137 +688,140 @@ static OGRwkbGeometryType ogrWkbGeometryTypeFromName( const QString &typeName )
return wkbUnknown;
}

QStringList QgsOgrProvider::subLayers() const
void QgsOgrProvider::addSubLayerDetailsToSubLayerList( int i, QgsOgrLayer *layer ) const
{
if ( !mValid )
QgsOgrFeatureDefn &fdef = layer->GetLayerDefn();
// Get first column name,
// TODO: add support for multiple
QString geometryColumnName;
OGRGeomFieldDefnH geomH = fdef.GetGeomFieldDefn( 0 );
if ( geomH )
{
return QStringList();
geometryColumnName = QString::fromUtf8( OGR_GFld_GetNameRef( geomH ) );
}
QString layerName = QString::fromUtf8( layer->name() );
OGRwkbGeometryType layerGeomType = fdef.GetGeomType();

if ( !mSubLayerList.isEmpty() )
return mSubLayerList;
if ( !mIsSubLayer && ( layerName == QLatin1String( "layer_styles" ) ||
layerName == QLatin1String( "qgis_projects" ) ) )
{
// Ignore layer_styles (coming from QGIS styling support) and
// qgis_projects (coming from http://plugins.qgis.org/plugins/QgisGeopackage/)
return;
}

for ( unsigned int i = 0; i < layerCount() ; i++ )
QgsDebugMsg( QString( "id = %1 name = %2 layerGeomType = %3" ).arg( i ).arg( layerName ).arg( layerGeomType ) );

if ( wkbFlatten( layerGeomType ) != wkbUnknown )
{
QString errCause;
QgsOgrLayer *layer = QgsOgrProviderUtils::getLayer( mOgrOrigLayer->datasetName(),
mOgrOrigLayer->updateMode(),
mOgrOrigLayer->options(),
i,
errCause );
if ( !layer )
continue;
QgsOgrFeatureDefn &fdef = layer->GetLayerDefn();
// Get first column name,
// TODO: add support for multiple
QString geometryColumnName;
OGRGeomFieldDefnH geomH = fdef.GetGeomFieldDefn( 0 );
if ( geomH )
int layerFeatureCount = layer->GetFeatureCount();

QString geom = ogrWkbGeometryTypeName( layerGeomType );

mSubLayerList << QStringLiteral( "%1:%2:%3:%4:%5" ).arg( i ).arg( layerName, layerFeatureCount == -1 ? tr( "Unknown" ) : QString::number( layerFeatureCount ), geom, geometryColumnName );
}
else
{
QgsDebugMsg( "Unknown geometry type, count features for each geometry type" );
// Add virtual sublayers for supported geometry types if layer type is unknown
// Count features for geometry types
QMap<OGRwkbGeometryType, int> fCount;
// TODO: avoid reading attributes, setRelevantFields cannot be called here because it is not constant

layer->ResetReading();
OGRFeatureH fet;
while ( ( fet = layer->GetNextFeature() ) )
{
geometryColumnName = QString::fromUtf8( OGR_GFld_GetNameRef( geomH ) );
OGRGeometryH geom = OGR_F_GetGeometryRef( fet );
if ( geom )
{
OGRwkbGeometryType gType = ogrWkbSingleFlatten( OGR_G_GetGeometryType( geom ) );
fCount[gType] = fCount.value( gType ) + 1;
}
OGR_F_Destroy( fet );
}
QString layerName = QString::fromUtf8( layer->name() );
OGRwkbGeometryType layerGeomType = fdef.GetGeomType();

// ignore this layer if a sublayer was requested and it is not this one
if ( mIsSubLayer &&
( ( !mLayerName.isNull() && layerName != mLayerName ) ||
( mLayerName.isNull() && mLayerIndex >= 0 && i != ( unsigned int )mLayerIndex ) ) )
layer->ResetReading();
// it may happen that there are no features in the layer, in that case add unknown type
// to show to user that the layer exists but it is empty
if ( fCount.isEmpty() )
{
QgsDebugMsg( QString( "subLayers() ignoring layer #%1 (%2)" ).arg( i ).arg( layerName ) );
QgsOgrProviderUtils::release( layer );
continue;
fCount[wkbUnknown] = 0;
}

if ( !mIsSubLayer && ( layerName == QLatin1String( "layer_styles" ) ||
layerName == QLatin1String( "qgis_projects" ) ) )
// List TIN and PolyhedralSurface as Polygon
if ( fCount.contains( wkbTIN ) )
{
// Ignore layer_styles (coming from QGIS styling support) and
// qgis_projects (coming from http://plugins.qgis.org/plugins/QgisGeopackage/)
QgsOgrProviderUtils::release( layer );
continue;
fCount[wkbPolygon] = fCount.value( wkbPolygon ) + fCount[wkbTIN];
fCount.remove( wkbTIN );
}

QgsDebugMsg( QString( "id = %1 name = %2 layerGeomType = %3" ).arg( i ).arg( layerName ).arg( layerGeomType ) );

if ( wkbFlatten( layerGeomType ) != wkbUnknown )
if ( fCount.contains( wkbPolyhedralSurface ) )
{
int layerFeatureCount = layer->GetFeatureCount();
fCount[wkbPolygon] = fCount.value( wkbPolygon ) + fCount[wkbPolyhedralSurface];
fCount.remove( wkbPolyhedralSurface );
}
// When there are CurvePolygons, promote Polygons
if ( fCount.contains( wkbPolygon ) && fCount.contains( wkbCurvePolygon ) )
{
fCount[wkbCurvePolygon] += fCount.value( wkbPolygon );
fCount.remove( wkbPolygon );
}
// When there are CompoundCurves, promote LineStrings and CircularStrings
if ( fCount.contains( wkbLineString ) && fCount.contains( wkbCompoundCurve ) )
{
fCount[wkbCompoundCurve] += fCount.value( wkbLineString );
fCount.remove( wkbLineString );
}
if ( fCount.contains( wkbCircularString ) && fCount.contains( wkbCompoundCurve ) )
{
fCount[wkbCompoundCurve] += fCount.value( wkbCircularString );
fCount.remove( wkbCircularString );
}

QString geom = ogrWkbGeometryTypeName( layerGeomType );
bool bIs25D = wkbHasZ( layerGeomType );
QMap<OGRwkbGeometryType, int>::const_iterator countIt = fCount.constBegin();
for ( ; countIt != fCount.constEnd(); ++countIt )
{
QString geom = ogrWkbGeometryTypeName( ( bIs25D ) ? wkbSetZ( countIt.key() ) : countIt.key() );

mSubLayerList << QStringLiteral( "%1:%2:%3:%4:%5" ).arg( i ).arg( layerName, layerFeatureCount == -1 ? tr( "Unknown" ) : QString::number( layerFeatureCount ), geom, geometryColumnName );
QString sl = QStringLiteral( "%1:%2:%3:%4:%5" ).arg( i ).arg( layerName ).arg( fCount.value( countIt.key() ) ).arg( geom, geometryColumnName );
QgsDebugMsg( "sub layer: " + sl );
mSubLayerList << sl;
}
else
{
QgsDebugMsg( "Unknown geometry type, count features for each geometry type" );
// Add virtual sublayers for supported geometry types if layer type is unknown
// Count features for geometry types
QMap<OGRwkbGeometryType, int> fCount;
// TODO: avoid reading attributes, setRelevantFields cannot be called here because it is not constant
}

layer->ResetReading();
OGRFeatureH fet;
while ( ( fet = layer->GetNextFeature() ) )
{
OGRGeometryH geom = OGR_F_GetGeometryRef( fet );
if ( geom )
{
OGRwkbGeometryType gType = ogrWkbSingleFlatten( OGR_G_GetGeometryType( geom ) );
fCount[gType] = fCount.value( gType ) + 1;
}
OGR_F_Destroy( fet );
}
layer->ResetReading();
// it may happen that there are no features in the layer, in that case add unknown type
// to show to user that the layer exists but it is empty
if ( fCount.isEmpty() )
{
fCount[wkbUnknown] = 0;
}
}

// List TIN and PolyhedralSurface as Polygon
if ( fCount.contains( wkbTIN ) )
{
fCount[wkbPolygon] = fCount.value( wkbPolygon ) + fCount[wkbTIN];
fCount.remove( wkbTIN );
}
if ( fCount.contains( wkbPolyhedralSurface ) )
{
fCount[wkbPolygon] = fCount.value( wkbPolygon ) + fCount[wkbPolyhedralSurface];
fCount.remove( wkbPolyhedralSurface );
}
// When there are CurvePolygons, promote Polygons
if ( fCount.contains( wkbPolygon ) && fCount.contains( wkbCurvePolygon ) )
{
fCount[wkbCurvePolygon] += fCount.value( wkbPolygon );
fCount.remove( wkbPolygon );
}
// When there are CompoundCurves, promote LineStrings and CircularStrings
if ( fCount.contains( wkbLineString ) && fCount.contains( wkbCompoundCurve ) )
{
fCount[wkbCompoundCurve] += fCount.value( wkbLineString );
fCount.remove( wkbLineString );
}
if ( fCount.contains( wkbCircularString ) && fCount.contains( wkbCompoundCurve ) )
{
fCount[wkbCompoundCurve] += fCount.value( wkbCircularString );
fCount.remove( wkbCircularString );
}
QStringList QgsOgrProvider::subLayers() const
{
if ( !mValid )
{
return QStringList();
}

bool bIs25D = wkbHasZ( layerGeomType );
QMap<OGRwkbGeometryType, int>::const_iterator countIt = fCount.constBegin();
for ( ; countIt != fCount.constEnd(); ++countIt )
{
QString geom = ogrWkbGeometryTypeName( ( bIs25D ) ? wkbSetZ( countIt.key() ) : countIt.key() );
if ( !mSubLayerList.isEmpty() )
return mSubLayerList;

QString sl = QStringLiteral( "%1:%2:%3:%4:%5" ).arg( i ).arg( layerName ).arg( fCount.value( countIt.key() ) ).arg( geom, geometryColumnName );
QgsDebugMsg( "sub layer: " + sl );
mSubLayerList << sl;
}
}
if ( mOgrLayer && ( mIsSubLayer || layerCount() == 1 ) )
{
addSubLayerDetailsToSubLayerList( mLayerIndex, mOgrLayer );
}
else
{
for ( unsigned int i = 0; i < layerCount() ; i++ )
{
QString errCause;
QgsOgrLayer *layer = QgsOgrProviderUtils::getLayer( mOgrOrigLayer->datasetName(),
mOgrOrigLayer->updateMode(),
mOgrOrigLayer->options(),
i,
errCause );
if ( !layer )
continue;

addSubLayerDetailsToSubLayerList( i, layer );

QgsOgrProviderUtils::release( layer );
QgsOgrProviderUtils::release( layer );
}
}
return mSubLayerList;
}
Expand Down
2 changes: 2 additions & 0 deletions src/providers/ogr/qgsogrprovider.h
Expand Up @@ -178,6 +178,8 @@ class QgsOgrProvider : public QgsVectorDataProvider
//! Commits a transaction
bool commitTransaction();

void addSubLayerDetailsToSubLayerList( int i, QgsOgrLayer *layer ) const;

QgsFields mAttributeFields;

//! Map of field index to default value
Expand Down

0 comments on commit c9b0a2b

Please sign in to comment.