Skip to content

Commit c9b0a2b

Browse files
committedOct 20, 2017
[OGR provider] Speed-up layer addition to the canvas when selected from the data source manager
1 parent 8f3d44d commit c9b0a2b

File tree

2 files changed

+114
-109
lines changed

2 files changed

+114
-109
lines changed
 

‎src/providers/ogr/qgsogrprovider.cpp

Lines changed: 112 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -688,137 +688,140 @@ static OGRwkbGeometryType ogrWkbGeometryTypeFromName( const QString &typeName )
688688
return wkbUnknown;
689689
}
690690

691-
QStringList QgsOgrProvider::subLayers() const
691+
void QgsOgrProvider::addSubLayerDetailsToSubLayerList( int i, QgsOgrLayer *layer ) const
692692
{
693-
if ( !mValid )
693+
QgsOgrFeatureDefn &fdef = layer->GetLayerDefn();
694+
// Get first column name,
695+
// TODO: add support for multiple
696+
QString geometryColumnName;
697+
OGRGeomFieldDefnH geomH = fdef.GetGeomFieldDefn( 0 );
698+
if ( geomH )
694699
{
695-
return QStringList();
700+
geometryColumnName = QString::fromUtf8( OGR_GFld_GetNameRef( geomH ) );
696701
}
702+
QString layerName = QString::fromUtf8( layer->name() );
703+
OGRwkbGeometryType layerGeomType = fdef.GetGeomType();
697704

698-
if ( !mSubLayerList.isEmpty() )
699-
return mSubLayerList;
705+
if ( !mIsSubLayer && ( layerName == QLatin1String( "layer_styles" ) ||
706+
layerName == QLatin1String( "qgis_projects" ) ) )
707+
{
708+
// Ignore layer_styles (coming from QGIS styling support) and
709+
// qgis_projects (coming from http://plugins.qgis.org/plugins/QgisGeopackage/)
710+
return;
711+
}
700712

701-
for ( unsigned int i = 0; i < layerCount() ; i++ )
713+
QgsDebugMsg( QString( "id = %1 name = %2 layerGeomType = %3" ).arg( i ).arg( layerName ).arg( layerGeomType ) );
714+
715+
if ( wkbFlatten( layerGeomType ) != wkbUnknown )
702716
{
703-
QString errCause;
704-
QgsOgrLayer *layer = QgsOgrProviderUtils::getLayer( mOgrOrigLayer->datasetName(),
705-
mOgrOrigLayer->updateMode(),
706-
mOgrOrigLayer->options(),
707-
i,
708-
errCause );
709-
if ( !layer )
710-
continue;
711-
QgsOgrFeatureDefn &fdef = layer->GetLayerDefn();
712-
// Get first column name,
713-
// TODO: add support for multiple
714-
QString geometryColumnName;
715-
OGRGeomFieldDefnH geomH = fdef.GetGeomFieldDefn( 0 );
716-
if ( geomH )
717+
int layerFeatureCount = layer->GetFeatureCount();
718+
719+
QString geom = ogrWkbGeometryTypeName( layerGeomType );
720+
721+
mSubLayerList << QStringLiteral( "%1:%2:%3:%4:%5" ).arg( i ).arg( layerName, layerFeatureCount == -1 ? tr( "Unknown" ) : QString::number( layerFeatureCount ), geom, geometryColumnName );
722+
}
723+
else
724+
{
725+
QgsDebugMsg( "Unknown geometry type, count features for each geometry type" );
726+
// Add virtual sublayers for supported geometry types if layer type is unknown
727+
// Count features for geometry types
728+
QMap<OGRwkbGeometryType, int> fCount;
729+
// TODO: avoid reading attributes, setRelevantFields cannot be called here because it is not constant
730+
731+
layer->ResetReading();
732+
OGRFeatureH fet;
733+
while ( ( fet = layer->GetNextFeature() ) )
717734
{
718-
geometryColumnName = QString::fromUtf8( OGR_GFld_GetNameRef( geomH ) );
735+
OGRGeometryH geom = OGR_F_GetGeometryRef( fet );
736+
if ( geom )
737+
{
738+
OGRwkbGeometryType gType = ogrWkbSingleFlatten( OGR_G_GetGeometryType( geom ) );
739+
fCount[gType] = fCount.value( gType ) + 1;
740+
}
741+
OGR_F_Destroy( fet );
719742
}
720-
QString layerName = QString::fromUtf8( layer->name() );
721-
OGRwkbGeometryType layerGeomType = fdef.GetGeomType();
722-
723-
// ignore this layer if a sublayer was requested and it is not this one
724-
if ( mIsSubLayer &&
725-
( ( !mLayerName.isNull() && layerName != mLayerName ) ||
726-
( mLayerName.isNull() && mLayerIndex >= 0 && i != ( unsigned int )mLayerIndex ) ) )
743+
layer->ResetReading();
744+
// it may happen that there are no features in the layer, in that case add unknown type
745+
// to show to user that the layer exists but it is empty
746+
if ( fCount.isEmpty() )
727747
{
728-
QgsDebugMsg( QString( "subLayers() ignoring layer #%1 (%2)" ).arg( i ).arg( layerName ) );
729-
QgsOgrProviderUtils::release( layer );
730-
continue;
748+
fCount[wkbUnknown] = 0;
731749
}
732750

733-
if ( !mIsSubLayer && ( layerName == QLatin1String( "layer_styles" ) ||
734-
layerName == QLatin1String( "qgis_projects" ) ) )
751+
// List TIN and PolyhedralSurface as Polygon
752+
if ( fCount.contains( wkbTIN ) )
735753
{
736-
// Ignore layer_styles (coming from QGIS styling support) and
737-
// qgis_projects (coming from http://plugins.qgis.org/plugins/QgisGeopackage/)
738-
QgsOgrProviderUtils::release( layer );
739-
continue;
754+
fCount[wkbPolygon] = fCount.value( wkbPolygon ) + fCount[wkbTIN];
755+
fCount.remove( wkbTIN );
740756
}
741-
742-
QgsDebugMsg( QString( "id = %1 name = %2 layerGeomType = %3" ).arg( i ).arg( layerName ).arg( layerGeomType ) );
743-
744-
if ( wkbFlatten( layerGeomType ) != wkbUnknown )
757+
if ( fCount.contains( wkbPolyhedralSurface ) )
745758
{
746-
int layerFeatureCount = layer->GetFeatureCount();
759+
fCount[wkbPolygon] = fCount.value( wkbPolygon ) + fCount[wkbPolyhedralSurface];
760+
fCount.remove( wkbPolyhedralSurface );
761+
}
762+
// When there are CurvePolygons, promote Polygons
763+
if ( fCount.contains( wkbPolygon ) && fCount.contains( wkbCurvePolygon ) )
764+
{
765+
fCount[wkbCurvePolygon] += fCount.value( wkbPolygon );
766+
fCount.remove( wkbPolygon );
767+
}
768+
// When there are CompoundCurves, promote LineStrings and CircularStrings
769+
if ( fCount.contains( wkbLineString ) && fCount.contains( wkbCompoundCurve ) )
770+
{
771+
fCount[wkbCompoundCurve] += fCount.value( wkbLineString );
772+
fCount.remove( wkbLineString );
773+
}
774+
if ( fCount.contains( wkbCircularString ) && fCount.contains( wkbCompoundCurve ) )
775+
{
776+
fCount[wkbCompoundCurve] += fCount.value( wkbCircularString );
777+
fCount.remove( wkbCircularString );
778+
}
747779

748-
QString geom = ogrWkbGeometryTypeName( layerGeomType );
780+
bool bIs25D = wkbHasZ( layerGeomType );
781+
QMap<OGRwkbGeometryType, int>::const_iterator countIt = fCount.constBegin();
782+
for ( ; countIt != fCount.constEnd(); ++countIt )
783+
{
784+
QString geom = ogrWkbGeometryTypeName( ( bIs25D ) ? wkbSetZ( countIt.key() ) : countIt.key() );
749785

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

760-
layer->ResetReading();
761-
OGRFeatureH fet;
762-
while ( ( fet = layer->GetNextFeature() ) )
763-
{
764-
OGRGeometryH geom = OGR_F_GetGeometryRef( fet );
765-
if ( geom )
766-
{
767-
OGRwkbGeometryType gType = ogrWkbSingleFlatten( OGR_G_GetGeometryType( geom ) );
768-
fCount[gType] = fCount.value( gType ) + 1;
769-
}
770-
OGR_F_Destroy( fet );
771-
}
772-
layer->ResetReading();
773-
// it may happen that there are no features in the layer, in that case add unknown type
774-
// to show to user that the layer exists but it is empty
775-
if ( fCount.isEmpty() )
776-
{
777-
fCount[wkbUnknown] = 0;
778-
}
792+
}
779793

780-
// List TIN and PolyhedralSurface as Polygon
781-
if ( fCount.contains( wkbTIN ) )
782-
{
783-
fCount[wkbPolygon] = fCount.value( wkbPolygon ) + fCount[wkbTIN];
784-
fCount.remove( wkbTIN );
785-
}
786-
if ( fCount.contains( wkbPolyhedralSurface ) )
787-
{
788-
fCount[wkbPolygon] = fCount.value( wkbPolygon ) + fCount[wkbPolyhedralSurface];
789-
fCount.remove( wkbPolyhedralSurface );
790-
}
791-
// When there are CurvePolygons, promote Polygons
792-
if ( fCount.contains( wkbPolygon ) && fCount.contains( wkbCurvePolygon ) )
793-
{
794-
fCount[wkbCurvePolygon] += fCount.value( wkbPolygon );
795-
fCount.remove( wkbPolygon );
796-
}
797-
// When there are CompoundCurves, promote LineStrings and CircularStrings
798-
if ( fCount.contains( wkbLineString ) && fCount.contains( wkbCompoundCurve ) )
799-
{
800-
fCount[wkbCompoundCurve] += fCount.value( wkbLineString );
801-
fCount.remove( wkbLineString );
802-
}
803-
if ( fCount.contains( wkbCircularString ) && fCount.contains( wkbCompoundCurve ) )
804-
{
805-
fCount[wkbCompoundCurve] += fCount.value( wkbCircularString );
806-
fCount.remove( wkbCircularString );
807-
}
794+
QStringList QgsOgrProvider::subLayers() const
795+
{
796+
if ( !mValid )
797+
{
798+
return QStringList();
799+
}
808800

809-
bool bIs25D = wkbHasZ( layerGeomType );
810-
QMap<OGRwkbGeometryType, int>::const_iterator countIt = fCount.constBegin();
811-
for ( ; countIt != fCount.constEnd(); ++countIt )
812-
{
813-
QString geom = ogrWkbGeometryTypeName( ( bIs25D ) ? wkbSetZ( countIt.key() ) : countIt.key() );
801+
if ( !mSubLayerList.isEmpty() )
802+
return mSubLayerList;
814803

815-
QString sl = QStringLiteral( "%1:%2:%3:%4:%5" ).arg( i ).arg( layerName ).arg( fCount.value( countIt.key() ) ).arg( geom, geometryColumnName );
816-
QgsDebugMsg( "sub layer: " + sl );
817-
mSubLayerList << sl;
818-
}
819-
}
804+
if ( mOgrLayer && ( mIsSubLayer || layerCount() == 1 ) )
805+
{
806+
addSubLayerDetailsToSubLayerList( mLayerIndex, mOgrLayer );
807+
}
808+
else
809+
{
810+
for ( unsigned int i = 0; i < layerCount() ; i++ )
811+
{
812+
QString errCause;
813+
QgsOgrLayer *layer = QgsOgrProviderUtils::getLayer( mOgrOrigLayer->datasetName(),
814+
mOgrOrigLayer->updateMode(),
815+
mOgrOrigLayer->options(),
816+
i,
817+
errCause );
818+
if ( !layer )
819+
continue;
820+
821+
addSubLayerDetailsToSubLayerList( i, layer );
820822

821-
QgsOgrProviderUtils::release( layer );
823+
QgsOgrProviderUtils::release( layer );
824+
}
822825
}
823826
return mSubLayerList;
824827
}

‎src/providers/ogr/qgsogrprovider.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ class QgsOgrProvider : public QgsVectorDataProvider
178178
//! Commits a transaction
179179
bool commitTransaction();
180180

181+
void addSubLayerDetailsToSubLayerList( int i, QgsOgrLayer *layer ) const;
182+
181183
QgsFields mAttributeFields;
182184

183185
//! Map of field index to default value

0 commit comments

Comments
 (0)
Please sign in to comment.