Skip to content

Commit f8e3dde

Browse files
committed
wcs 1.1 - describe coverage, get multipart response
1 parent cbdcd77 commit f8e3dde

6 files changed

+323
-95
lines changed

src/core/qgsrasterdataprovider.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ QgsRasterBandStats QgsRasterDataProvider::bandStatistics( int theBandNo )
258258

259259
if ( !( capabilities() & QgsRasterDataProvider::Size ) || xSize() == 0 || ySize() == 0 || myXBlockSize == 0 || myYBlockSize == 0 )
260260
{
261+
QgsDebugMsg( "Cannot collect statistics (raster size or block size) are unknown" );
261262
return QgsRasterBandStats(); //invalid raster band stats
262263
}
263264

src/providers/wcs/qgswcscapabilities.cpp

+114-13
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ QgsWcsCapabilities::QgsWcsCapabilities( QgsDataSourceURI const &theUri ):
8080
{
8181
QgsDebugMsg( "uri = " + mUri.encodedUri() );
8282

83+
mUserVersion = QUrl( mUri.param( "url" ) ).queryItemValue( "VERSION" );
84+
8385
retrieveServerCapabilities();
8486
}
8587

@@ -102,6 +104,8 @@ void QgsWcsCapabilities::setUri( QgsDataSourceURI const &theUri )
102104
QgsWcsCapabilitiesProperty c;
103105
mCapabilities = c;
104106

107+
mUserVersion = QUrl( mUri.param( "url" ) ).queryItemValue( "VERSION" );
108+
105109
retrieveServerCapabilities( true );
106110
}
107111

@@ -196,16 +200,15 @@ bool QgsWcsCapabilities::retrieveServerCapabilities( bool forceRefresh )
196200
if ( mCapabilitiesResponse.isNull() || forceRefresh )
197201
{
198202
// Check if user tried to force version
199-
QString userVersion = QUrl( mUri.param( "url" ) ).queryItemValue( "VERSION" );
200-
if ( !userVersion.isEmpty() && !userVersion.startsWith( "1.0." ) )
203+
if ( !mUserVersion.isEmpty() && !mUserVersion.startsWith( "1.0." ) && !mUserVersion.startsWith( "1.1." ) )
201204
{
202205
mErrorTitle = tr( "Version not supported" );
203206
mErrorFormat = "text/plain";
204-
mError = tr( "The version %1 specified in connection URL parameter VERSION is not supported by QGIS" ).arg( userVersion );
207+
mError = tr( "The version %1 specified in connection URL parameter VERSION is not supported by QGIS" ).arg( mUserVersion );
205208
return false;
206209
}
207210

208-
QString url = prepareUri( mUri.param( "url" ) ) + "SERVICE=WCS&REQUEST=GetCapabilities&VERSION=1.0.0";
211+
QString url = prepareUri( mUri.param( "url" ) ) + "SERVICE=WCS&REQUEST=GetCapabilities";
209212

210213
if ( ! sendRequest( url ) ) { return false; }
211214

@@ -234,8 +237,6 @@ bool QgsWcsCapabilities::describeCoverage( QString const &identifier, bool force
234237
{
235238
QgsDebugMsg( " identifier = " + identifier );
236239

237-
if ( !mVersion.startsWith( "1.0." ) ) { return true; } // no need for 1.1
238-
239240
QgsWcsCoverageSummary *coverage = coverageSummary( identifier );
240241
if ( !coverage )
241242
{
@@ -245,15 +246,26 @@ bool QgsWcsCapabilities::describeCoverage( QString const &identifier, bool force
245246

246247
if ( coverage->described && ! forceRefresh ) return true;
247248

248-
QString url = prepareUri( mUri.param( "url" ) ) + "SERVICE=WCS&REQUEST=DescribeCoverage&VERSION=1.0.0&COVERAGE=" + coverage->identifier;
249+
//QString url = prepareUri( mUri.param( "url" ) ) + "SERVICE=WCS&REQUEST=DescribeCoverage&VERSION=1.0.0&COVERAGE=" + coverage->identifier;
250+
QString url = prepareUri( mUri.param( "url" ) ) + "SERVICE=WCS&REQUEST=DescribeCoverage&COVERAGE=" + coverage->identifier;
251+
if ( mUserVersion.isEmpty() )
252+
{
253+
url += "&VERSION=" + mVersion;
254+
}
249255

250256
if ( ! sendRequest( url ) ) { return false; }
251257

252258
QgsDebugMsg( "Converting to Dom." );
253259

254-
bool domOK;
255-
domOK = parseDescribeCoverageDom( mCapabilitiesResponse, coverage );
256-
QgsDebugMsg( "supportedFormat = " + coverage->supportedFormat.join( "," ) );
260+
bool domOK = false;
261+
if ( mVersion.startsWith( "1.0" ) )
262+
{
263+
domOK = parseDescribeCoverageDom10( mCapabilitiesResponse, coverage );
264+
}
265+
else if ( mVersion.startsWith( "1.1" ) )
266+
{
267+
domOK = parseDescribeCoverageDom11( mCapabilitiesResponse, coverage );
268+
}
257269

258270
if ( !domOK )
259271
{
@@ -267,6 +279,8 @@ bool QgsWcsCapabilities::describeCoverage( QString const &identifier, bool force
267279
return false;
268280
}
269281

282+
QgsDebugMsg( "supportedFormat = " + coverage->supportedFormat.join( "," ) );
283+
270284
return true;
271285
}
272286

@@ -366,11 +380,11 @@ bool QgsWcsCapabilities::parseCapabilitiesDom( QByteArray const &xml, QgsWcsCapa
366380
capabilities.version = docElem.attribute( "version" );
367381
mVersion = capabilities.version;
368382

369-
if ( !mVersion.startsWith( "1.0." ) )
383+
if ( !mVersion.startsWith( "1.0" ) && !mVersion.startsWith( "1.1" ) )
370384
{
371385
mErrorTitle = tr( "Version not supported" );
372386
mErrorFormat = "text/plain";
373-
mError = tr( "Could not get WCS capabilities in the expected version 1.1.\nResponse version was: %1" )
387+
mError = tr( "WCS server version %1 is not supported by Quantum GIS (supported versions: 1.0.0, 1.1.0, 1.1.2)" )
374388
.arg( mVersion );
375389

376390
QgsLogger::debug( "WCS version: " + mError );
@@ -453,6 +467,41 @@ QString QgsWcsCapabilities::firstChildText( const QDomElement &element, const QS
453467
return QString();
454468
}
455469

470+
QList<QDomElement> QgsWcsCapabilities::domElements( const QDomElement &element, const QString & path )
471+
{
472+
QList<QDomElement> list;
473+
474+
QStringList names = path.split( "." );
475+
if ( names.size() == 0 ) return list;
476+
QString name = names.value( 0 );
477+
names.removeFirst();
478+
479+
QDomNode n1 = element.firstChild();
480+
while ( !n1.isNull() )
481+
{
482+
QDomElement el = n1.toElement();
483+
if ( !el.isNull() )
484+
{
485+
QString tagName = stripNS( el.tagName() );
486+
if ( tagName == name )
487+
{
488+
QgsDebugMsg( name + " found" );
489+
if ( names.size() == 0 )
490+
{
491+
list.append( el );
492+
}
493+
else
494+
{
495+
list.append( domElements( el, names.join( "." ) ) );
496+
}
497+
}
498+
}
499+
n1 = n1.nextSibling();
500+
}
501+
502+
return list;
503+
}
504+
456505
QDomElement QgsWcsCapabilities::domElement( const QDomElement &element, const QString & path )
457506
{
458507
QStringList names = path.split( "." );
@@ -629,7 +678,7 @@ bool QgsWcsCapabilities::convertToDom( QByteArray const &xml )
629678
return true;
630679
}
631680

632-
bool QgsWcsCapabilities::parseDescribeCoverageDom( QByteArray const &xml, QgsWcsCoverageSummary *coverage )
681+
bool QgsWcsCapabilities::parseDescribeCoverageDom10( QByteArray const &xml, QgsWcsCoverageSummary *coverage )
633682
{
634683
QgsDebugMsg( "coverage->identifier = " + coverage->identifier );
635684
if ( ! convertToDom( xml ) ) return false;
@@ -726,6 +775,58 @@ bool QgsWcsCapabilities::parseDescribeCoverageDom( QByteArray const &xml, QgsWcs
726775
return true;
727776
}
728777
// ------------------------ 1.1 ----------------------------------------------
778+
bool QgsWcsCapabilities::parseDescribeCoverageDom11( QByteArray const &xml, QgsWcsCoverageSummary *coverage )
779+
{
780+
QgsDebugMsg( "coverage->identifier = " + coverage->identifier );
781+
if ( ! convertToDom( xml ) ) return false;
782+
783+
QDomElement docElem = mCapabilitiesDom.documentElement();
784+
785+
QgsDebugMsg( "testing tagName " + docElem.tagName() );
786+
787+
QString tagName = stripNS( docElem.tagName() );
788+
if ( tagName != "CoverageDescriptions" )
789+
{
790+
mErrorTitle = tr( "Dom Exception" );
791+
mErrorFormat = "text/plain";
792+
mError = tr( "Could not get WCS capabilities in the expected format (DTD): no %1 found.\nThis might be due to an incorrect WCS Server URL.\nTag:%3\nResponse was:\n%4" )
793+
.arg( "CoverageDescriptions" )
794+
.arg( docElem.tagName() )
795+
.arg( QString( xml ) );
796+
797+
QgsLogger::debug( "Dom Exception: " + mError );
798+
799+
return false;
800+
}
801+
802+
// Get image size, we can get it from BoundingBox with crs=urn:ogc:def:crs:OGC::imageCRS
803+
// but while at least one BoundingBox is mandatory, it does not have to be urn:ogc:def:crs:OGC::imageCRS
804+
// TODO: if BoundingBox with crs=urn:ogc:def:crs:OGC::imageCRS is not found,
805+
// we could calculate image size from GridCRS.GridOffsets (if available)
806+
QList<QDomElement> boundingBoxElements = domElements( docElem, "CoverageDescription.Domain.SpatialDomain.BoundingBox" );
807+
808+
QgsDebugMsg( QString( "%1 BoundingBox found" ).arg( boundingBoxElements.size() ) );
809+
810+
foreach( QDomElement el, boundingBoxElements )
811+
{
812+
if ( el.attribute( "crs" ) != "urn:ogc:def:crs:OGC::imageCRS" ) continue;
813+
814+
QList<int> low = parseInts( domElementText( el, "LowerCorner" ) );
815+
QList<int> high = parseInts( domElementText( el, "UpperCorner" ) );
816+
if ( low.size() == 2 && high.size() == 2 )
817+
{
818+
coverage->width = high[0] - low[0] + 1;
819+
coverage->height = high[1] - low[1] + 1;
820+
coverage->hasSize = true;
821+
}
822+
break;
823+
}
824+
QgsDebugMsg( QString( "width = %1 height = %2" ).arg( coverage->width ).arg( coverage->height ) );
825+
826+
coverage->described = true;
827+
828+
return true;
829+
}
729830
void QgsWcsCapabilities::parseServiceIdentification( const QDomElement &e, QgsWcsServiceIdentification &serviceIdentification ) // 1.1
730831
{
731832
serviceIdentification.title = firstChildText( e, "Title" );

src/providers/wcs/qgswcscapabilities.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,8 @@ class QgsWcsCapabilities : public QObject
190190
bool describeCoverage( QString const &identifier, bool forceRefresh = false );
191191

192192
bool convertToDom( QByteArray const &xml );
193-
bool parseDescribeCoverageDom( QByteArray const &xml, QgsWcsCoverageSummary *coverage );
193+
bool parseDescribeCoverageDom10( QByteArray const &xml, QgsWcsCoverageSummary *coverage );
194+
bool parseDescribeCoverageDom11( QByteArray const &xml, QgsWcsCoverageSummary *coverage );
194195

195196
//! set authorization header
196197
void setAuthorization( QNetworkRequest &request ) const;
@@ -246,6 +247,10 @@ class QgsWcsCapabilities : public QObject
246247
//! Get first child of specified name, NS is ignored
247248
QDomElement firstChild( const QDomElement &element, const QString &name );
248249

250+
/** Find sub elements by path which is string of dot separated tag names.
251+
* NS is ignored. Example path: domainSet.spatialDomain.RectifiedGrid */
252+
QList<QDomElement> domElements( const QDomElement &element, const QString &path );
253+
249254
/** Find first sub element by path which is string of dot separated tag names.
250255
* NS is ignored. Example path: domainSet.spatialDomain.RectifiedGrid */
251256
QDomElement domElement( const QDomElement &element, const QString &path );
@@ -311,6 +316,9 @@ class QgsWcsCapabilities : public QObject
311316
//! Response capabilities version
312317
QString mVersion;
313318

319+
//! Version specified by user in url
320+
QString mUserVersion;
321+
314322
/**
315323
* Capabilities of the WCS Server (raw)
316324
*/

0 commit comments

Comments
 (0)