Skip to content

Commit

Permalink
Rework QgsOgrProviderUtils::querySubLayerList to use QgsProviderSubla…
Browse files Browse the repository at this point in the history
…yerDetails for layer details storage
  • Loading branch information
nyalldawson committed Jun 28, 2021
1 parent 46a8016 commit a98411f
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 38 deletions.
35 changes: 29 additions & 6 deletions src/core/providers/ogr/qgsogrprovider.cpp
Expand Up @@ -34,6 +34,7 @@ email : sherman at mrcc.com
#include "qgssymbol.h"
#include "qgsembeddedsymbolrenderer.h"
#include "qgszipitem.h"
#include "qgsprovidersublayerdetails.h"

#define CPL_SUPRESS_CPLUSPLUS //#spellok
#include <gdal.h> // to collect version information
Expand Down Expand Up @@ -575,10 +576,32 @@ uint QgsOgrProvider::subLayerCount() const
return count;
}

QStringList subLayerDetailsToStringList( const QList< QgsProviderSublayerDetails > &layers )
{
QStringList res;
res.reserve( layers.size() );

for ( const QgsProviderSublayerDetails &layer : layers )
{
const OGRwkbGeometryType ogrGeomType = QgsOgrProviderUtils::ogrTypeFromQgisType( layer.wkbType() );

const QStringList parts { QString::number( layer.layerNumber() ),
layer.name(),
QString::number( layer.featureCount() ),
QgsOgrProviderUtils::ogrWkbGeometryTypeName( ogrGeomType ),
layer.geometryColumnName(),
layer.description() };
res << parts.join( QgsDataProvider::sublayerSeparator() );
}
return res;
}

QStringList QgsOgrProvider::subLayers() const
{
const bool withFeatureCount = ( mReadFlags & QgsDataProvider::SkipFeatureCount ) == 0;
return _subLayers( withFeatureCount );
return subLayerDetailsToStringList( _subLayers( withFeatureCount
? ( Qgis::SublayerQueryFlag::CountFeatures | Qgis::SublayerQueryFlag::ResolveGeometryType )
: Qgis::SublayerQueryFlag::ResolveGeometryType ) );
}

QgsLayerMetadata QgsOgrProvider::layerMetadata() const
Expand All @@ -588,25 +611,25 @@ QgsLayerMetadata QgsOgrProvider::layerMetadata() const

QStringList QgsOgrProvider::subLayersWithoutFeatureCount() const
{
return _subLayers( false );
return subLayerDetailsToStringList( _subLayers( Qgis::SublayerQueryFlag::ResolveGeometryType ) );
}

QStringList QgsOgrProvider::_subLayers( bool withFeatureCount ) const
QList<QgsProviderSublayerDetails> QgsOgrProvider::_subLayers( Qgis::SublayerQueryFlags flags ) const
{
QgsCPLHTTPFetchOverrider oCPLHTTPFetcher( mAuthCfg );
QgsSetCPLHTTPFetchOverriderInitiatorClass( oCPLHTTPFetcher, QStringLiteral( "QgsOgrProvider" ) );

if ( !mValid )
{
return QStringList();
return {};
}

if ( !mSubLayerList.isEmpty() )
return mSubLayerList;

if ( mOgrLayer && ( mIsSubLayer || layerCount() == 1 ) )
{
QgsOgrProviderUtils::querySubLayerList( mLayerIndex, mOgrLayer, withFeatureCount, mGDALDriverName, mIsSubLayer, mSubLayerList );
mSubLayerList << QgsOgrProviderUtils::querySubLayerList( mLayerIndex, mOgrLayer, mGDALDriverName, flags, mIsSubLayer, dataSourceUri() );
}
else
{
Expand All @@ -629,7 +652,7 @@ QStringList QgsOgrProvider::_subLayers( bool withFeatureCount ) const
if ( !layer )
continue;

QgsOgrProviderUtils::querySubLayerList( i, layer.get(), withFeatureCount, mGDALDriverName, mIsSubLayer, mSubLayerList );
mSubLayerList << QgsOgrProviderUtils::querySubLayerList( i, layer.get(), mGDALDriverName, flags, mIsSubLayer, dataSourceUri() );
if ( firstLayer == nullptr )
{
firstLayer = std::move( layer );
Expand Down
5 changes: 3 additions & 2 deletions src/core/providers/ogr/qgsogrprovider.h
Expand Up @@ -25,6 +25,7 @@ email : sherman at mrcc.com

class QgsOgrLayer;
class QgsOgrTransaction;
class QgsProviderSublayerDetails;

///@cond PRIVATE
#define SIP_NO_FILE
Expand Down Expand Up @@ -198,7 +199,7 @@ class QgsOgrProvider final: public QgsVectorDataProvider
//! Does the real job of settings the subset string and adds an argument to disable update capabilities
bool _setSubsetString( const QString &theSQL, bool updateFeatureCount = true, bool updateCapabilities = true, bool hasExistingRef = true );

QStringList _subLayers( bool withFeatureCount ) const;
QList< QgsProviderSublayerDetails > _subLayers( Qgis::SublayerQueryFlags flags ) const;

QgsFields mAttributeFields;

Expand Down Expand Up @@ -277,7 +278,7 @@ class QgsOgrProvider final: public QgsVectorDataProvider

mutable long long mFeaturesCounted = static_cast< long long >( Qgis::FeatureCountState::Uncounted );

mutable QStringList mSubLayerList;
mutable QList<QgsProviderSublayerDetails> mSubLayerList;

//! Converts \a value from json QVariant to QString
QString jsonStringValue( const QVariant &value ) const;
Expand Down
70 changes: 41 additions & 29 deletions src/core/providers/ogr/qgsogrproviderutils.cpp
Expand Up @@ -21,7 +21,7 @@ email : nyall dot dawson at gmail dot com
#include "qgsmessagelog.h"
#include "qgsvectorfilewriter.h"
#include "qgsauthmanager.h"
#include "qgsogrprovider.h"
#include "qgsprovidersublayerdetails.h"

#include <ogr_srs_api.h>
#include <cpl_port.h>
Expand Down Expand Up @@ -2292,7 +2292,7 @@ bool QgsOgrProviderUtils::canDriverShareSameDatasetAmongLayers( const QString &d
!( updateMode && dsName.endsWith( QLatin1String( ".shp.zip" ), Qt::CaseInsensitive ) );
}

void QgsOgrProviderUtils::querySubLayerList( int i, QgsOgrLayer *layer, bool withFeatureCount, const QString &driverName, bool isSubLayer, QStringList &sublayerList )
QList< QgsProviderSublayerDetails > QgsOgrProviderUtils::querySubLayerList( int i, QgsOgrLayer *layer, const QString &driverName, Qgis::SublayerQueryFlags flags, bool isSubLayer, const QString &baseUri )
{
QString layerName = QString::fromUtf8( layer->name() );

Expand All @@ -2301,14 +2301,13 @@ void QgsOgrProviderUtils::querySubLayerList( int i, QgsOgrLayer *layer, bool wit
{
// Ignore layer_styles (coming from QGIS styling support) and
// qgis_projects (coming from http://plugins.qgis.org/plugins/QgisGeopackage/)
return;
return {};
}
// Get first column name,
// TODO: add support for multiple
QString geometryColumnName;
OGRwkbGeometryType layerGeomType = wkbUnknown;
const bool slowGeomTypeRetrieval =
driverName == QLatin1String( "OAPIF" ) || driverName == QLatin1String( "WFS3" ) || driverName == QLatin1String( "PGeo" );
const bool slowGeomTypeRetrieval = driverName == QLatin1String( "OAPIF" ) || driverName == QLatin1String( "WFS3" ) || driverName == QLatin1String( "PGeo" );
if ( !slowGeomTypeRetrieval )
{
QgsOgrFeatureDefn &fdef = layer->GetLayerDefn();
Expand All @@ -2328,22 +2327,27 @@ void QgsOgrProviderUtils::querySubLayerList( int i, QgsOgrLayer *layer, bool wit

QgsDebugMsgLevel( QStringLiteral( "id = %1 name = %2 layerGeomType = %3 longDescription = %4" ).arg( i ).arg( layerName ).arg( layerGeomType ). arg( longDescription ), 2 );


QVariantMap parts = QgsOgrProviderMetadata().decodeUri( baseUri );
parts.insert( QStringLiteral( "layerName" ), layerName );

if ( slowGeomTypeRetrieval || wkbFlatten( layerGeomType ) != wkbUnknown )
{
long long layerFeatureCount = withFeatureCount ? layer->GetApproxFeatureCount() : -1;
const long long layerFeatureCount = flags & Qgis::SublayerQueryFlag::CountFeatures ? layer->GetApproxFeatureCount() : static_cast< long >( Qgis::FeatureCountState::Uncounted );

QString geom = QgsOgrProviderUtils::ogrWkbGeometryTypeName( layerGeomType );
QgsProviderSublayerDetails details;
details.setLayerNumber( i );
details.setName( layerName );
details.setFeatureCount( layerFeatureCount );
details.setWkbType( QgsOgrUtils::ogrGeometryTypeToQgsWkbType( layerGeomType ) );
details.setGeometryColumnName( geometryColumnName );
details.setDescription( longDescription );
details.setProviderKey( QStringLiteral( "ogr" ) );

// For feature count, -1 indicates an unknown count state
QStringList parts = QStringList()
<< QString::number( i )
<< layerName
<< QString::number( layerFeatureCount )
<< geom
<< geometryColumnName
<< longDescription;
const QString uri = QgsOgrProviderMetadata().encodeUri( parts );
details.setUri( uri );

sublayerList << parts.join( QgsOgrProvider::sublayerSeparator() );
return { details };
}
else
{
Expand Down Expand Up @@ -2401,24 +2405,32 @@ void QgsOgrProviderUtils::querySubLayerList( int i, QgsOgrLayer *layer, bool wit
fCount.remove( wkbCircularString );
}

QList< QgsProviderSublayerDetails > res;
res.reserve( fCount.size() );

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

QStringList parts = QStringList()
<< QString::number( i )
<< layerName
<< QString::number( fCount.value( countIt.key() ) )
<< geom
<< geometryColumnName
<< longDescription;

QString sl = parts.join( QgsOgrProvider::sublayerSeparator() );
QgsDebugMsgLevel( "sub layer: " + sl, 2 );
sublayerList << sl;
QgsProviderSublayerDetails details;
details.setLayerNumber( i );
details.setName( layerName );
details.setFeatureCount( fCount.value( countIt.key() ) );
details.setWkbType( QgsOgrUtils::ogrGeometryTypeToQgsWkbType( ( bIs25D ) ? wkbSetZ( countIt.key() ) : countIt.key() ) );
details.setGeometryColumnName( geometryColumnName );
details.setDescription( longDescription );
details.setProviderKey( QStringLiteral( "ogr" ) );

if ( fCount.size() > 1 )
parts.insert( QStringLiteral( "geometryType" ), ogrWkbGeometryTypeName( countIt.key() ) );
else
parts.remove( QStringLiteral( "geometryType" ) );

details.setUri( QgsOgrProviderMetadata().encodeUri( parts ) );

res << details;
}
return res;
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/core/providers/ogr/qgsogrproviderutils.h
Expand Up @@ -34,6 +34,7 @@ email : nyall dot dawson at gmail dot com

class QgsOgrLayer;
class QgsCoordinateReferenceSystem;
class QgsProviderSublayerDetails;

///@cond PRIVATE
#define SIP_NO_FILE
Expand Down Expand Up @@ -256,7 +257,7 @@ class CORE_EXPORT QgsOgrProviderUtils
bool updateMode,
const QString &dsName );

static void querySubLayerList( int i, QgsOgrLayer *layer, bool withFeatureCount, const QString &driverName, bool isSubLayer, QStringList &sublayerList );
static QList<QgsProviderSublayerDetails> querySubLayerList( int i, QgsOgrLayer *layer, const QString &driverName, Qgis::SublayerQueryFlags flags, bool isSubLayer, const QString &baseUri );

};

Expand Down

0 comments on commit a98411f

Please sign in to comment.