Skip to content

Commit

Permalink
Enable loading wms category/collection layers in the layers panel
Browse files Browse the repository at this point in the history
Fixes #35460
  • Loading branch information
Samweli committed Apr 1, 2020
1 parent dda80ed commit 7422d65
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 89 deletions.
177 changes: 101 additions & 76 deletions src/providers/wms/qgswmsdataitems.cpp
Expand Up @@ -267,14 +267,89 @@ bool QgsWMSConnectionItem::equal( const QgsDataItem *other )
}

// ---------------------------------------------------------------------------

QgsWMSLayerCollectionItem::QgsWMSLayerCollectionItem( QgsDataItem *parent, QString name, QString path, const QgsWmsCapabilitiesProperty &capabilitiesProperty, const QgsDataSourceUri &dataSourceUri, const QgsWmsLayerProperty &layerProperty )
: QgsDataCollectionItem( parent, name, path, QStringLiteral( "WMS" ) )
, mCapabilitiesProperty( capabilitiesProperty )
QgsWMSItemBase::QgsWMSItemBase( const QgsWmsCapabilitiesProperty &capabilitiesProperty, const QgsDataSourceUri &dataSourceUri, const QgsWmsLayerProperty &layerProperty )
: mCapabilitiesProperty( capabilitiesProperty )
, mDataSourceUri( dataSourceUri )
, mLayerProperty( layerProperty )
{
}

QString QgsWMSItemBase::createUri()
{
if ( mLayerProperty.name.isEmpty() )
return QString(); // layer collection

// Number of styles must match number of layers
mDataSourceUri.setParam( QStringLiteral( "layers" ), mLayerProperty.name );
QString style = !mLayerProperty.style.isEmpty() ? mLayerProperty.style.at( 0 ).name : QString();
mDataSourceUri.setParam( QStringLiteral( "styles" ), style );

// Check for layer dimensions
for ( const QgsWmsDimensionProperty &dimension : qgis::as_const( mLayerProperty.dimensions ) )
{
// add temporal dimensions only
if ( dimension.name == QLatin1String( "time" ) || dimension.name == QLatin1String( "reference_time" ) )
{
QString name = dimension.name == QLatin1String( "time" ) ? QString( "timeDimensionExtent" ) : QString( "referenceTimeDimensionExtent" );

if ( !( mDataSourceUri.param( QLatin1String( "type" ) ) == QLatin1String( "wmst" ) ) )
mDataSourceUri.setParam( QLatin1String( "type" ), QLatin1String( "wmst" ) );
mDataSourceUri.setParam( name, dimension.extent );
}
}

// WMS-T defaults settings
if ( mDataSourceUri.param( QLatin1String( "type" ) ) == QLatin1String( "wmst" ) )
{
mDataSourceUri.setParam( QLatin1String( "temporalSource" ), QLatin1String( "provider" ) );
mDataSourceUri.setParam( QLatin1String( "enableTime" ), QLatin1String( "yes" ) );
}

QString format;
// get first supported by qt and server
QVector<QgsWmsSupportedFormat> formats( QgsWmsProvider::supportedFormats() );
const auto constFormats = formats;
for ( const QgsWmsSupportedFormat &f : constFormats )
{
if ( mCapabilitiesProperty.capability.request.getMap.format.indexOf( f.format ) >= 0 )
{
format = f.format;
break;
}
}
mDataSourceUri.setParam( QStringLiteral( "format" ), format );

QString crs;
// get first known if possible
QgsCoordinateReferenceSystem testCrs;
for ( const QString &c : qgis::as_const( mLayerProperty.crs ) )
{
testCrs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( c );
if ( testCrs.isValid() )
{
crs = c;
break;
}
}
if ( crs.isEmpty() && !mLayerProperty.crs.isEmpty() )
{
crs = mLayerProperty.crs[0];
}
mDataSourceUri.setParam( QStringLiteral( "crs" ), crs );
//uri = rasterLayerPath + "|layers=" + layers.join( "," ) + "|styles=" + styles.join( "," ) + "|format=" + format + "|crs=" + crs;

return mDataSourceUri.encodedUri();
}


// ---------------------------------------------------------------------------

QgsWMSLayerCollectionItem::QgsWMSLayerCollectionItem( QgsDataItem *parent, QString name, QString path, const QgsWmsCapabilitiesProperty &capabilitiesProperty, const QgsDataSourceUri &dataSourceUri, const QgsWmsLayerProperty &layerProperty )
: QgsDataCollectionItem( parent, name, path, QStringLiteral( "wms" ) )
, QgsWMSItemBase( capabilitiesProperty, dataSourceUri, layerProperty )
{
mIconName = QStringLiteral( "mIconWms.svg" );
mUri = createUri();

// Populate everything, it costs nothing, all info about layers is collected
for ( const QgsWmsLayerProperty &layerProperty : qgis::as_const( mLayerProperty.layer ) )
Expand Down Expand Up @@ -334,17 +409,35 @@ bool QgsWMSLayerCollectionItem::equal( const QgsDataItem *other )
}
}


return ( mPath == otherCollectionItem->mPath && mName == otherCollectionItem->mName );
}

bool QgsWMSLayerCollectionItem::hasDragEnabled() const
{
if ( !mLayerProperty.name.isEmpty() )
return true;
return false;
}

QgsMimeDataUtils::Uri QgsWMSLayerCollectionItem::mimeUri() const
{
QgsMimeDataUtils::Uri u;

u.layerType = QStringLiteral( "raster" );
u.providerKey = providerKey();
u.name = name();
u.uri = mUri;
u.supportedCrs = mLayerProperty.crs;
u.supportedFormats = mCapabilitiesProperty.capability.request.getMap.format;

return u;
}

// ---------------------------------------------------------------------------

QgsWMSLayerItem::QgsWMSLayerItem( QgsDataItem *parent, QString name, QString path, const QgsWmsCapabilitiesProperty &capabilitiesProperty, const QgsDataSourceUri &dataSourceUri, const QgsWmsLayerProperty &layerProperty )
: QgsLayerItem( parent, name, path, QString(), QgsLayerItem::Raster, QStringLiteral( "wms" ) )
, mCapabilitiesProperty( capabilitiesProperty )
, mDataSourceUri( dataSourceUri )
, mLayerProperty( layerProperty )
, QgsWMSItemBase( capabilitiesProperty, dataSourceUri, layerProperty )
{
mSupportedCRS = mLayerProperty.crs;
mSupportFormats = mCapabilitiesProperty.capability.request.getMap.format;
Expand All @@ -355,73 +448,6 @@ QgsWMSLayerItem::QgsWMSLayerItem( QgsDataItem *parent, QString name, QString pat
setState( Populated );
}

QString QgsWMSLayerItem::createUri()
{
if ( mLayerProperty.name.isEmpty() )
return QString(); // layer collection

// Number of styles must match number of layers
mDataSourceUri.setParam( QStringLiteral( "layers" ), mLayerProperty.name );
QString style = !mLayerProperty.style.isEmpty() ? mLayerProperty.style.at( 0 ).name : QString();
mDataSourceUri.setParam( QStringLiteral( "styles" ), style );

// Check for layer dimensions
for ( const QgsWmsDimensionProperty &dimension : qgis::as_const( mLayerProperty.dimensions ) )
{
// add temporal dimensions only
if ( dimension.name == QLatin1String( "time" ) || dimension.name == QLatin1String( "reference_time" ) )
{
QString name = dimension.name == QLatin1String( "time" ) ? QString( "timeDimensionExtent" ) : QString( "referenceTimeDimensionExtent" );

if ( !( mDataSourceUri.param( QLatin1String( "type" ) ) == QLatin1String( "wmst" ) ) )
mDataSourceUri.setParam( QLatin1String( "type" ), QLatin1String( "wmst" ) );
mDataSourceUri.setParam( name, dimension.extent );
}
}

// WMS-T defaults settings
if ( mDataSourceUri.param( QLatin1String( "type" ) ) == QLatin1String( "wmst" ) )
{
mDataSourceUri.setParam( QLatin1String( "temporalSource" ), QLatin1String( "provider" ) );
mDataSourceUri.setParam( QLatin1String( "enableTime" ), QLatin1String( "yes" ) );
}

QString format;
// get first supported by qt and server
QVector<QgsWmsSupportedFormat> formats( QgsWmsProvider::supportedFormats() );
const auto constFormats = formats;
for ( const QgsWmsSupportedFormat &f : constFormats )
{
if ( mCapabilitiesProperty.capability.request.getMap.format.indexOf( f.format ) >= 0 )
{
format = f.format;
break;
}
}
mDataSourceUri.setParam( QStringLiteral( "format" ), format );

QString crs;
// get first known if possible
QgsCoordinateReferenceSystem testCrs;
for ( const QString &c : qgis::as_const( mLayerProperty.crs ) )
{
testCrs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( c );
if ( testCrs.isValid() )
{
crs = c;
break;
}
}
if ( crs.isEmpty() && !mLayerProperty.crs.isEmpty() )
{
crs = mLayerProperty.crs[0];
}
mDataSourceUri.setParam( QStringLiteral( "crs" ), crs );
//uri = rasterLayerPath + "|layers=" + layers.join( "," ) + "|styles=" + styles.join( "," ) + "|format=" + format + "|crs=" + crs;

return mDataSourceUri.encodedUri();
}

bool QgsWMSLayerItem::equal( const QgsDataItem *other )
{
if ( type() != other->type() )
Expand All @@ -437,7 +463,6 @@ bool QgsWMSLayerItem::equal( const QgsDataItem *other )
if ( !mLayerProperty.equal( otherLayer->mLayerProperty ) )
return false;


return ( mPath == otherLayer->mPath && mName == otherLayer->mName );
}

Expand Down
45 changes: 32 additions & 13 deletions src/providers/wms/qgswmsdataitems.h
Expand Up @@ -41,12 +41,36 @@ class QgsWMSConnectionItem : public QgsDataCollectionItem
QgsWmsCapabilitiesDownload *mCapabilitiesDownload = nullptr;
};

/**
* Base class which contains similar basic attributes and functions needed by the
* wms collection layers and child layers.
*
*/
class QgsWMSItemBase
{
public:
QgsWMSItemBase( const QgsWmsCapabilitiesProperty &capabilitiesProperty,
const QgsDataSourceUri &dataSourceUri,
const QgsWmsLayerProperty &layerProperty );

QString createUri();

//! Stores GetCapabilities response
QgsWmsCapabilitiesProperty mCapabilitiesProperty;

//! Stores WMS connection information
QgsDataSourceUri mDataSourceUri;

//! WMS Layer properties, can be inherited by subsidiary layers
QgsWmsLayerProperty mLayerProperty;
};

/**
* \brief WMS Layer Collection.
*
* This collection contains a WMS Layer element that can enclose other layers
* This collection contains a WMS Layer element that can enclose other layers.
*/
class QgsWMSLayerCollectionItem : public QgsDataCollectionItem
class QgsWMSLayerCollectionItem : public QgsDataCollectionItem, public QgsWMSItemBase
{
Q_OBJECT
public:
Expand All @@ -57,14 +81,13 @@ class QgsWMSLayerCollectionItem : public QgsDataCollectionItem

bool equal( const QgsDataItem *other ) override;

//! Stores GetCapabilities response
QgsWmsCapabilitiesProperty mCapabilitiesProperty;
bool hasDragEnabled() const override;

//! Stores WMS connection information
QgsDataSourceUri mDataSourceUri;
QgsMimeDataUtils::Uri mimeUri() const override;

//! WMS Layer properties, can be inherited by subsidiary layers
QgsWmsLayerProperty mLayerProperty;
protected:
//! The URI
QString mUri;

// QgsDataItem interface
public:
Expand All @@ -73,7 +96,7 @@ class QgsWMSLayerCollectionItem : public QgsDataCollectionItem

// WMS Layers may be nested, so that they may be both QgsDataCollectionItem and QgsLayerItem
// We have to use QgsDataCollectionItem and support layer methods if necessary
class QgsWMSLayerItem : public QgsLayerItem
class QgsWMSLayerItem : public QgsLayerItem, public QgsWMSItemBase
{
Q_OBJECT
public:
Expand All @@ -83,11 +106,7 @@ class QgsWMSLayerItem : public QgsLayerItem
const QgsWmsLayerProperty &layerProperty );

bool equal( const QgsDataItem *other ) override;
QString createUri();

QgsWmsCapabilitiesProperty mCapabilitiesProperty;
QgsDataSourceUri mDataSourceUri;
QgsWmsLayerProperty mLayerProperty;
};

class QgsWMTSLayerItem : public QgsLayerItem
Expand Down

0 comments on commit 7422d65

Please sign in to comment.