Skip to content

Commit

Permalink
[OAPIF provider] Integrate provider within WFS provider GUI
Browse files Browse the repository at this point in the history
Funded by Planet
  • Loading branch information
rouault authored and nyalldawson committed Oct 25, 2019
1 parent 4a6b49f commit 681229a
Show file tree
Hide file tree
Showing 13 changed files with 431 additions and 83 deletions.
9 changes: 9 additions & 0 deletions python/gui/auto_generated/qgsnewhttpconnection.sip.in
Expand Up @@ -78,6 +78,15 @@ Returns the current connection url.

protected:

enum WfsVersionIndex
{
WFS_VERSION_MAX,
WFS_VERSION_1_0,
WFS_VERSION_1_1,
WFS_VERSION_2_0,
WFS_VERSION_API_FEATURES,
};

virtual bool validate();
%Docstring
Returns ``True`` if dialog settings are valid, or ``False`` if current
Expand Down
43 changes: 23 additions & 20 deletions src/gui/qgsnewhttpconnection.cpp
Expand Up @@ -73,6 +73,7 @@ QgsNewHttpConnection::QgsNewHttpConnection( QWidget *parent, ConnectionTypes typ
cmbVersion->addItem( tr( "1.0" ) );
cmbVersion->addItem( tr( "1.1" ) );
cmbVersion->addItem( tr( "2.0" ) );
cmbVersion->addItem( tr( "OGC API - Features" ) );
connect( cmbVersion,
static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ),
this, &QgsNewHttpConnection::wfsVersionCurrentIndexChanged );
Expand Down Expand Up @@ -166,10 +167,11 @@ QgsNewHttpConnection::QgsNewHttpConnection( QWidget *parent, ConnectionTypes typ
void QgsNewHttpConnection::wfsVersionCurrentIndexChanged( int index )
{
// For now 2019-06-06, leave paging checkable for some WFS version 1.1 servers with support
cbxWfsFeaturePaging->setEnabled( index == 0 || index >= 2 );
lblPageSize->setEnabled( cbxWfsFeaturePaging->isChecked() && ( index == 0 || index >= 2 ) );
txtPageSize->setEnabled( cbxWfsFeaturePaging->isChecked() && ( index == 0 || index >= 2 ) );
cbxWfsIgnoreAxisOrientation->setEnabled( index != 1 );
cbxWfsFeaturePaging->setEnabled( index == WFS_VERSION_MAX || index >= WFS_VERSION_2_0 );
lblPageSize->setEnabled( cbxWfsFeaturePaging->isChecked() && ( index == WFS_VERSION_MAX || index >= WFS_VERSION_1_1 ) );
txtPageSize->setEnabled( cbxWfsFeaturePaging->isChecked() && ( index == WFS_VERSION_MAX || index >= WFS_VERSION_1_1 ) );
cbxWfsIgnoreAxisOrientation->setEnabled( index != WFS_VERSION_1_0 && index != WFS_VERSION_API_FEATURES );
cbxWfsInvertAxisOrientation->setEnabled( index != WFS_VERSION_API_FEATURES );
}

void QgsNewHttpConnection::wfsFeaturePagingStateChanged( int state )
Expand Down Expand Up @@ -312,29 +314,27 @@ void QgsNewHttpConnection::updateServiceSpecificSettings()
cmbDpiMode->setCurrentIndex( dpiIdx );

QString version = settings.value( wfsKey + "/version" ).toString();
int versionIdx = 0; // AUTO
int versionIdx = WFS_VERSION_MAX; // AUTO
if ( version == QLatin1String( "1.0.0" ) )
versionIdx = 1;
versionIdx = WFS_VERSION_1_0;
else if ( version == QLatin1String( "1.1.0" ) )
versionIdx = 2;
versionIdx = WFS_VERSION_1_1;
else if ( version == QLatin1String( "2.0.0" ) )
versionIdx = 3;
versionIdx = WFS_VERSION_2_0;
else if ( version == QLatin1String( "OGC_API_FEATURES" ) )
versionIdx = WFS_VERSION_API_FEATURES;
cmbVersion->setCurrentIndex( versionIdx );

// Enable/disable these items per WFS versions
wfsVersionCurrentIndexChanged( versionIdx );

txtReferer->setText( settings.value( wmsKey + "/referer" ).toString() );
txtMaxNumFeatures->setText( settings.value( wfsKey + "/maxnumfeatures" ).toString() );

// Only default to paging enabled if WFS 2.0.0 or higher
bool pagingEnabled = settings.value( wfsKey + "/pagingenabled", ( versionIdx == 0 || versionIdx >= 3 ) ).toBool();
bool pagingEnabled = settings.value( wfsKey + "/pagingenabled", ( versionIdx == WFS_VERSION_MAX || versionIdx >= WFS_VERSION_2_0 ) ).toBool();
txtPageSize->setText( settings.value( wfsKey + "/pagesize" ).toString() );
cbxWfsFeaturePaging->setChecked( pagingEnabled );

// Enable/disable these items per WFS versions
// For now 2019-06-06, leave paging checkable for some WFS version 1.1 servers with support
txtPageSize->setEnabled( pagingEnabled && ( versionIdx == 0 || versionIdx >= 2 ) );
lblPageSize->setEnabled( pagingEnabled && ( versionIdx == 0 || versionIdx >= 2 ) );
cbxWfsFeaturePaging->setEnabled( versionIdx == 0 || versionIdx >= 2 );
cbxWfsIgnoreAxisOrientation->setEnabled( versionIdx != 1 );
}

QUrl QgsNewHttpConnection::urlTrimmed() const
Expand Down Expand Up @@ -434,18 +434,21 @@ void QgsNewHttpConnection::accept()
QString version = QStringLiteral( "auto" );
switch ( cmbVersion->currentIndex() )
{
case 0:
case WFS_VERSION_MAX:
version = QStringLiteral( "auto" );
break;
case 1:
case WFS_VERSION_1_0:
version = QStringLiteral( "1.0.0" );
break;
case 2:
case WFS_VERSION_1_1:
version = QStringLiteral( "1.1.0" );
break;
case 3:
case WFS_VERSION_2_0:
version = QStringLiteral( "2.0.0" );
break;
case WFS_VERSION_API_FEATURES:
version = QStringLiteral( "OGC_API_FEATURES" );
break;
}
settings.setValue( wfsKey + "/version", version );

Expand Down
10 changes: 10 additions & 0 deletions src/gui/qgsnewhttpconnection.h
Expand Up @@ -103,6 +103,16 @@ class GUI_EXPORT QgsNewHttpConnection : public QDialog, private Ui::QgsNewHttpCo

protected:

//! Index of wfsVersionComboBox
enum WfsVersionIndex
{
WFS_VERSION_MAX = 0,
WFS_VERSION_1_0 = 1,
WFS_VERSION_1_1 = 2,
WFS_VERSION_2_0 = 3,
WFS_VERSION_API_FEATURES = 4,
};

/**
* Returns TRUE if dialog settings are valid, or FALSE if current
* settings are not valid and the dialog should not be acceptable.
Expand Down
5 changes: 5 additions & 0 deletions src/providers/wfs/qgswfscapabilities.cpp
Expand Up @@ -145,6 +145,11 @@ class CPLXMLTreeUniquePointer

void QgsWfsCapabilities::capabilitiesReplyFinished()
{
if ( mErrorCode != QgsBaseNetworkRequest::NoError )
{
emit gotCapabilities();
return;
}
const QByteArray &buffer = mResponse;

QgsDebugMsgLevel( QStringLiteral( "parsing capabilities: " ) + buffer, 4 );
Expand Down
90 changes: 71 additions & 19 deletions src/providers/wfs/qgswfsdataitems.cpp
Expand Up @@ -19,11 +19,15 @@
#include "qgsdataitemprovider.h"
#include "qgsdataprovider.h"
#include "qgslogger.h"
#include "qgsoapiflandingpagerequest.h"
#include "qgsoapifcollection.h"
#include "qgsoapifprovider.h"
#include "qgswfsconstants.h"
#include "qgswfsconnection.h"
#include "qgswfscapabilities.h"
#include "qgswfsdataitems.h"
#include "qgswfsdatasourceuri.h"
#include "qgswfsprovider.h"
#include "qgssettings.h"
#include "qgsgeonodeconnection.h"
#include "qgsgeonoderequest.h"
Expand All @@ -40,8 +44,8 @@
// QgsWfsLayerItem
//

QgsWfsLayerItem::QgsWfsLayerItem( QgsDataItem *parent, QString name, const QgsDataSourceUri &uri, QString featureType, QString title, QString crsString )
: QgsLayerItem( parent, title, parent->path() + '/' + name, QString(), QgsLayerItem::Vector, QStringLiteral( "WFS" ) )
QgsWfsLayerItem::QgsWfsLayerItem( QgsDataItem *parent, QString name, const QgsDataSourceUri &uri, QString featureType, QString title, QString crsString, const QString &providerKey )
: QgsLayerItem( parent, title.isEmpty() ? featureType : title, parent->path() + '/' + name, QString(), QgsLayerItem::Vector, providerKey )
{
QgsSettings settings;
bool useCurrentViewExtent = settings.value( QStringLiteral( "Windows/WFSSourceSelect/FeatureCurrentViewExtent" ), true ).toBool();
Expand Down Expand Up @@ -140,34 +144,82 @@ QgsWfsConnectionItem::QgsWfsConnectionItem( QgsDataItem *parent, QString name, Q
mCapabilities |= Collapse;
}

QVector<QgsDataItem *> QgsWfsConnectionItem::createChildren()

QVector<QgsDataItem *> QgsWfsConnectionItem::createChildrenOapif()
{
QVector<QgsDataItem *> layers;
QgsDataSourceUri uri( mUri );
QgsDebugMsg( "mUri = " + mUri );

QgsWfsCapabilities capabilities( mUri );

const bool synchronous = true;
const bool forceRefresh = false;
capabilities.requestCapabilities( synchronous, forceRefresh );

QVector<QgsDataItem *> layers;
if ( capabilities.errorCode() == QgsWfsCapabilities::NoError )
QgsOapifLandingPageRequest landingPageRequest( uri );
if ( landingPageRequest.request( synchronous, forceRefresh ) &&
landingPageRequest.errorCode() == QgsBaseNetworkRequest::NoError )
{
const auto featureTypes = capabilities.capabilities().featureTypes;
for ( const QgsWfsCapabilities::FeatureType &featureType : featureTypes )
QString url = landingPageRequest.collectionsUrl();
while ( !url.isEmpty() )
{
QgsWfsLayerItem *layer = new QgsWfsLayerItem( this, mName, uri, featureType.name, featureType.title, !featureType.crslist.isEmpty() ? featureType.crslist.first() : QString() );
layers.append( layer );
QgsOapifCollectionsRequest collectionsRequest( uri, url );
url.clear();
if ( collectionsRequest.request( synchronous, forceRefresh ) &&
collectionsRequest.errorCode() == QgsBaseNetworkRequest::NoError )
{
for ( const auto &collection : collectionsRequest.collections() )
{
QgsWfsLayerItem *layer = new QgsWfsLayerItem(
this, mName, uri, collection.mId, collection.mTitle,
QString(), QgsOapifProvider::OAPIF_PROVIDER_KEY );
layers.append( layer );
}
url = collectionsRequest.nextUrl();
}
}
}
else

return layers;
}

QVector<QgsDataItem *> QgsWfsConnectionItem::createChildren()
{
QgsDataSourceUri uri( mUri );
QgsDebugMsg( "mUri = " + mUri );

const bool synchronous = true;
const bool forceRefresh = false;
auto version = QgsWFSDataSourceURI( mUri ).version();
if ( version == QLatin1String( "OGC_API_FEATURES" ) )
{
//layers.append( new QgsErrorItem( this, tr( "Failed to retrieve layers" ), mPath + "/error" ) );
// TODO: show the error without adding child
return createChildrenOapif();
}
else
{
QgsWfsCapabilities capabilities( mUri );
if ( version == QgsWFSConstants::VERSION_AUTO )
{
capabilities.setLogErrors( false ); // as this might be a OAPIF server
}
capabilities.requestCapabilities( synchronous, forceRefresh );

return layers;
QVector<QgsDataItem *> layers;
if ( capabilities.errorCode() == QgsWfsCapabilities::NoError )
{
const auto featureTypes = capabilities.capabilities().featureTypes;
for ( const QgsWfsCapabilities::FeatureType &featureType : featureTypes )
{
QgsWfsLayerItem *layer = new QgsWfsLayerItem(
this, mName, uri, featureType.name, featureType.title,
!featureType.crslist.isEmpty() ? featureType.crslist.first() : QString(),
QgsWFSProvider::WFS_PROVIDER_KEY );
layers.append( layer );
}
}
else if ( version == QgsWFSConstants::VERSION_AUTO )
{
return createChildrenOapif();
}

return layers;
}
}


Expand Down Expand Up @@ -233,7 +285,7 @@ QgsDataItem *QgsWfsDataItemProvider::createDataItem( const QString &path, QgsDat
QgsDebugMsgLevel( "WFS path = " + path, 4 );
if ( path.isEmpty() )
{
return new QgsWfsRootItem( parentItem, QStringLiteral( "WFS" ), QStringLiteral( "wfs:" ) );
return new QgsWfsRootItem( parentItem, QStringLiteral( "WFS / OGC API - Features" ), QStringLiteral( "wfs:" ) );
}

// path schema: wfs:/connection name (used by OWS)
Expand Down
4 changes: 2 additions & 2 deletions src/providers/wfs/qgswfsdataitems.h
Expand Up @@ -55,7 +55,7 @@ class QgsWfsConnectionItem : public QgsDataCollectionItem
private:
QString mUri;

QgsWfsCapabilities *mWfsCapabilities = nullptr;
QVector<QgsDataItem *> createChildrenOapif();
};


Expand All @@ -64,7 +64,7 @@ class QgsWfsLayerItem : public QgsLayerItem
Q_OBJECT

public:
QgsWfsLayerItem( QgsDataItem *parent, QString name, const QgsDataSourceUri &uri, QString featureType, QString title, QString crsString );
QgsWfsLayerItem( QgsDataItem *parent, QString name, const QgsDataSourceUri &uri, QString featureType, QString title, QString crsString, const QString &providerKey );

QList<QMenu *> menus( QWidget *parent ) override;

Expand Down
4 changes: 4 additions & 0 deletions src/providers/wfs/qgswfsdatasourceuri.cpp
Expand Up @@ -372,6 +372,10 @@ QString QgsWFSDataSourceURI::build( const QString &baseUri,
uri.setSql( sql );
if ( restrictToCurrentViewExtent )
uri.mURI.setParam( QgsWFSConstants::URI_PARAM_RESTRICT_TO_REQUEST_BBOX, QStringLiteral( "1" ) );
if ( uri.version() == QStringLiteral( "OGC_API_FEATURES" ) )
{
uri.setVersion( QString() );
}
return uri.uri();
}

Expand Down

0 comments on commit 681229a

Please sign in to comment.