Skip to content

Commit

Permalink
WCS time support
Browse files Browse the repository at this point in the history
  • Loading branch information
blazek committed Aug 7, 2012
1 parent e09a0a5 commit e9afc7b
Show file tree
Hide file tree
Showing 10 changed files with 280 additions and 139 deletions.
26 changes: 22 additions & 4 deletions src/gui/qgsowssourceselect.cpp
Expand Up @@ -160,8 +160,8 @@ void QgsOWSSourceSelect::populateFormats()
// selectedLayersFormats may come in various forms:
// image/tiff, GTiff, GeoTIFF, TIFF, geotiff_int16, geotiff_rgb,
// PNG, GTOPO30, ARCGRID, IMAGEMOSAIC
// and even any string defined in server configuration, for example the
// value used in UMN Mapserver for OUTPUTFORMAT->NAME is used in
// and even any string defined in server configuration, for example the
// value used in UMN Mapserver for OUTPUTFORMAT->NAME is used in
// WCS 1.0.0 SupportedFormats/Format

// TODO: It is impossible to cover all possible formats comming from server
Expand Down Expand Up @@ -241,6 +241,14 @@ void QgsOWSSourceSelect::populateFormats()
mImageFormatsGroupBox->setEnabled( true );
}

void QgsOWSSourceSelect::populateTimes()
{
QgsDebugMsg( "entered" );
mTimeComboBox->clear();
mTimeComboBox->insertItems( 0, selectedLayersTimes() );
mTimeComboBox->setEnabled( !selectedLayersTimes().isEmpty() );
}

void QgsOWSSourceSelect::populateConnectionList()
{
mConnectionsComboBox->clear();
Expand Down Expand Up @@ -436,7 +444,7 @@ void QgsOWSSourceSelect::on_mLayersTreeWidget_itemSelectionChanged()

void QgsOWSSourceSelect::populateCRS()
{
QgsDebugMsg ("Entered");
QgsDebugMsg( "Entered" );
mSelectedLayersCRSs = selectedLayersCRSs().toSet();
mCRSGroupBox->setTitle( tr( "Coordinate Reference System (%n available)", "crs count", mSelectedLayersCRSs.count() ) );

Expand Down Expand Up @@ -474,7 +482,7 @@ void QgsOWSSourceSelect::populateCRS()
mSelectedCRS = "";
mSelectedCRSLabel->setText( "" );
}
QgsDebugMsg ("mSelectedCRS = " + mSelectedCRS);
QgsDebugMsg( "mSelectedCRS = " + mSelectedCRS );
mChangeCRSButton->setEnabled( !mSelectedLayersCRSs.isEmpty() );
}

Expand Down Expand Up @@ -535,6 +543,11 @@ QString QgsOWSSourceSelect::selectedCRS()
return mSelectedCRS;
}

QString QgsOWSSourceSelect::selectedTime()
{
return mTimeComboBox->currentText();
}

void QgsOWSSourceSelect::setConnectionListPosition()
{
QString toSelect = QgsOWSConnection::selectedConnection( mService );
Expand Down Expand Up @@ -805,6 +818,11 @@ QStringList QgsOWSSourceSelect::selectedLayersCRSs()
return QStringList();
}

QStringList QgsOWSSourceSelect::selectedLayersTimes()
{
return QStringList();
}

void QgsOWSSourceSelect::updateButtons()
{
}
9 changes: 9 additions & 0 deletions src/gui/qgsowssourceselect.h
Expand Up @@ -124,6 +124,9 @@ class GUI_EXPORT QgsOWSSourceSelect : public QDialog, public Ui::QgsOWSSourceSel
//! Server CRS supported for currently selected layer item(s)
virtual QStringList selectedLayersCRSs();

//! List of times (temporalDomain timePosition/timePeriod for currently selected layer item(s)
virtual QStringList selectedLayersTimes();

//virtual QStringList layerCRS( int id );

//! Populate the connection list combo box
Expand All @@ -138,6 +141,9 @@ class GUI_EXPORT QgsOWSSourceSelect : public QDialog, public Ui::QgsOWSSourceSel
//! Set supported CRSs
void populateCRS();

//! Populate times
void populateTimes();

//! Connection name
QString connName();

Expand Down Expand Up @@ -199,6 +205,9 @@ class GUI_EXPORT QgsOWSSourceSelect : public QDialog, public Ui::QgsOWSSourceSel
//! Returns currently selected Crs
QString selectedCRS();

//! Returns currently selected time
QString selectedTime();

QList<QTreeWidgetItem*> mCurrentSelection;
QTableWidgetItem* mCurrentTileset;

Expand Down
4 changes: 3 additions & 1 deletion src/providers/wcs/URI
Expand Up @@ -11,7 +11,9 @@ Parameters:

* identifier (required) : Coverage name

* format: (optional) : Supported format name. Default is the first supported format with tif in name or the first supported format.
* time (optional) : time position or time period (beginPosition/endPosition[/timeResolution])

* format (optional) : Supported format name. Default is the first supported format with tif in name or the first supported format.

* crs (optional) : CRS in form AUTHORITY:ID, e.g. EPSG:4326. Default is EPSG:4326 if supported or the first supported CRS.

Expand Down
72 changes: 55 additions & 17 deletions src/providers/wcs/qgswcscapabilities.cpp
Expand Up @@ -196,15 +196,15 @@ bool QgsWcsCapabilities::retrieveServerCapabilities( )

if ( !preferredVersion.isEmpty() )
{
// This is not
if ( preferredVersion.startsWith ( "1.0" ) )
// This is not
if ( preferredVersion.startsWith( "1.0" ) )
{
versions << "VERSION=" + preferredVersion;
}
else if ( preferredVersion.startsWith ( "1.1" ) )
else if ( preferredVersion.startsWith( "1.1" ) )
{
// Ignored by UMN Mapserver 6.0.3, see below
versions << "AcceptVersions=" + preferredVersion;
// Ignored by UMN Mapserver 6.0.3, see below
versions << "AcceptVersions=" + preferredVersion;
}
}
else
Expand All @@ -214,7 +214,7 @@ bool QgsWcsCapabilities::retrieveServerCapabilities( )
versions << "AcceptVersions=1.1,1.0" << "VERSION=1.0";
}

foreach( QString v, versions )
foreach ( QString v, versions )
{
if ( retrieveServerCapabilities( v ) )
{
Expand Down Expand Up @@ -427,7 +427,7 @@ bool QgsWcsCapabilities::parseCapabilitiesDom( QByteArray const &xml, QgsWcsCapa
capabilities.abstract = domElementText( docElem, "ServiceIdentification.Abstract" );

QList<QDomElement> operationElements = domElements( docElem, "OperationsMetadata.Operation" );
foreach( QDomElement el, operationElements )
foreach ( QDomElement el, operationElements )
{
if ( el.attribute( "name" ) == "GetCoverage" )
{
Expand Down Expand Up @@ -509,7 +509,7 @@ QStringList QgsWcsCapabilities::domElementsTexts( const QDomElement &element, co
QStringList list;
QList<QDomElement> elems = domElements( element, path );

foreach( QDomElement el, elems )
foreach ( QDomElement el, elems )
{
list << el.text();
}
Expand Down Expand Up @@ -539,9 +539,8 @@ QString QgsWcsCapabilities::domElementText( const QDomElement &element, const QS
QList<int> QgsWcsCapabilities::parseInts( const QString &text )
{
QList<int> list;
foreach( QString s, text.split( " " ) )
foreach ( QString s, text.split( " " ) )
{
int i;
bool ok;
list.append( s.toInt( &ok ) );
if ( !ok )
Expand All @@ -556,9 +555,8 @@ QList<int> QgsWcsCapabilities::parseInts( const QString &text )
QList<double> QgsWcsCapabilities::parseDoubles( const QString &text )
{
QList<double> list;
foreach( QString s, text.split( " " ) )
foreach ( QString s, text.split( " " ) )
{
int i;
bool ok;
list.append( s.toDouble( &ok ) );
if ( !ok )
Expand Down Expand Up @@ -758,7 +756,7 @@ bool QgsWcsCapabilities::parseDescribeCoverageDom10( QByteArray const &xml, QgsW

QgsDebugMsg( QString( "%1 envelopeElements found" ).arg( envelopeElements.size() ) );

foreach( QDomElement el, envelopeElements )
foreach ( QDomElement el, envelopeElements )
{
QString srsName = el.attribute( "srsName" );

Expand All @@ -779,10 +777,30 @@ bool QgsWcsCapabilities::parseDescribeCoverageDom10( QByteArray const &xml, QgsW
}
}

coverage->times = domElementsTexts( coverageOfferingElement, "domainSet.temporalDomain.timePosition" );

QList<QDomElement> timePeriodElements = domElements( coverageOfferingElement, "domainSet.temporalDomain.timePeriod" );

QgsDebugMsg( QString( "%1 timePeriod found" ).arg( timePeriodElements.size() ) );

foreach ( QDomElement el, timePeriodElements )
{
QString beginPosition = domElementText( el, "beginPosition" );
QString endPosition = domElementText( el, "endPosition" );
QString timeResolution = domElementText( el, "timeResolution" );
// Format used in request
QString time = beginPosition + "/" + endPosition;
if ( !timeResolution.isEmpty() )
{
time += "/" + timeResolution;
}
coverage->times << time;
}

// Find native bounding box
if ( !coverage->nativeCrs.isEmpty() )
{
foreach( QString srsName, coverage->boundingBoxes.keys() )
foreach ( QString srsName, coverage->boundingBoxes.keys() )
{
if ( srsName == coverage->nativeCrs )
{
Expand All @@ -793,7 +811,7 @@ bool QgsWcsCapabilities::parseDescribeCoverageDom10( QByteArray const &xml, QgsW

// NULL / no data values
// TODO: handle multiple range sets
foreach( QString text, domElementsTexts( coverageOfferingElement, "rangeSet.RangeSet.nullValue.singleValue" ) )
foreach ( QString text, domElementsTexts( coverageOfferingElement, "rangeSet.RangeSet.nullValue.singleValue" ) )
{
bool ok;
double val = text.toDouble( &ok );
Expand Down Expand Up @@ -840,7 +858,7 @@ bool QgsWcsCapabilities::parseDescribeCoverageDom11( QByteArray const &xml, QgsW

QgsDebugMsg( QString( "%1 BoundingBox found" ).arg( boundingBoxElements.size() ) );

foreach( QDomElement el, boundingBoxElements )
foreach ( QDomElement el, boundingBoxElements )
{
QString authid = crsUrnToAuthId( el.attribute( "crs" ) );
QList<double> low = parseDoubles( domElementText( el, "LowerCorner" ) );
Expand Down Expand Up @@ -876,9 +894,29 @@ bool QgsWcsCapabilities::parseDescribeCoverageDom11( QByteArray const &xml, QgsW
// if urn:ogc:def:crs:OGC::imageCRS BoundingBox was not found
}

coverage->times = domElementsTexts( docElem, "CoverageDescription.Domain.TemporalDomain.timePosition" );

QList<QDomElement> timePeriodElements = domElements( docElem, "CoverageDescription.Domain.TemporalDomain.timePeriod" );

QgsDebugMsg( QString( "%1 timePeriod found" ).arg( timePeriodElements.size() ) );

foreach ( QDomElement el, timePeriodElements )
{
QString beginPosition = domElementText( el, "beginTime" );
QString endPosition = domElementText( el, "endTime" );
QString timeResolution = domElementText( el, "timeResolution" );
// Format used in request
QString time = beginPosition + "/" + endPosition;
if ( !timeResolution.isEmpty() )
{
time += "/" + timeResolution;
}
coverage->times << time;
}

// NULL / no data values
// TODO: handle multiple fields / ranges (?)
foreach( QString text, domElementsTexts( docElem, "CoverageDescription.Range.Field.NullValue" ) )
foreach ( QString text, domElementsTexts( docElem, "CoverageDescription.Range.Field.NullValue" ) )
{
bool ok;
double val = text.toDouble( &ok );
Expand Down
2 changes: 2 additions & 0 deletions src/providers/wcs/qgswcscapabilities.h
Expand Up @@ -49,6 +49,8 @@ struct QgsWcsCoverageSummary
// Map of bounding boxes, key is CRS name (srsName), e.g. EPSG:4326
QMap<QString, QgsRectangle> boundingBoxes;
QgsRectangle nativeBoundingBox;
// timePosition or timePeriod (beginPosition/endPosition[/timeResolution] - used in KVP request)
QStringList times;
QVector<QgsWcsCoverageSummary> coverageSummary;
// non reflecting Capabilities structure:
bool valid;
Expand Down
14 changes: 13 additions & 1 deletion src/providers/wcs/qgswcsprovider.cpp
Expand Up @@ -357,6 +357,8 @@ bool QgsWcsProvider::parseUri( QString uriString )

mIdentifier = uri.param( "identifier" );

mTime = uri.param( "time" );

setFormat( uri.param( "format" ) );

if ( !uri.param( "crs" ).isEmpty() )
Expand Down Expand Up @@ -561,6 +563,10 @@ void QgsWcsProvider::getCache( int bandNo, QgsRectangle const & viewExtent, int
if ( mCapabilities.version().startsWith( "1.0" ) )
{
setQueryItem( url, "COVERAGE", mIdentifier );
if ( !mTime.isEmpty() )
{
setQueryItem( url, "TIME", mTime );
}
setQueryItem( url, "BBOX", bbox );
setQueryItem( url, "CRS", crs ); // request BBOX CRS
setQueryItem( url, "RESPONSE_CRS", crs ); // response CRS
Expand All @@ -574,6 +580,12 @@ void QgsWcsProvider::getCache( int bandNo, QgsRectangle const & viewExtent, int
setQueryItem( url, "IDENTIFIER", mIdentifier );
QString crsUrn = QString( "urn:ogc:def:crs:%1::%2" ).arg( crs.split( ':' ).value( 0 ) ).arg( crs.split( ':' ).value( 1 ) );
bbox += "," + crsUrn;

if ( !mTime.isEmpty() )
{
setQueryItem( url, "TIMESEQUENCE", mTime );
}

setQueryItem( url, "BOUNDINGBOX", bbox );

// GridBaseCRS=urn:ogc:def:crs:SG:6.6:32618
Expand Down Expand Up @@ -1292,7 +1304,7 @@ QString QgsWcsProvider::metadata()
metadata += tr( "Coverages" );
metadata += "</th></tr>";

foreach( QgsWcsCoverageSummary c, mCapabilities.coverages() )
foreach ( QgsWcsCoverageSummary c, mCapabilities.coverages() )
{
metadata += coverageMetadata( c );
}
Expand Down
3 changes: 3 additions & 0 deletions src/providers/wcs/qgswcsprovider.h
Expand Up @@ -251,6 +251,9 @@ class QgsWcsProvider : public QgsRasterDataProvider, QgsGdalProviderBase
//! Identifier / coverage / layer name
QString mIdentifier;

//! Time (temporalDomain), optional
QString mTime;

//! Format of coverage to be used in request
QString mFormat;

Expand Down
30 changes: 24 additions & 6 deletions src/providers/wcs/qgswcssourceselect.cpp
Expand Up @@ -144,6 +144,12 @@ void QgsWCSSourceSelect::addClicked( )
uri.setParam( "format", selectedFormat() );
}

QgsDebugMsg( "selectedTime = " + selectedTime() );
if ( !selectedTime().isEmpty() )
{
uri.setParam( "time", selectedTime() );
}

emit addRasterLayer( uri.encodedUri(), identifier, "wcs" );
}

Expand All @@ -154,11 +160,9 @@ void QgsWCSSourceSelect::on_mLayersTreeWidget_itemSelectionChanged()
QString identifier = selectedIdentifier();
if ( identifier.isEmpty() ) { return; }

if ( mCapabilities.version().startsWith( "1.0" ) )
{
// 1.0 get additional info
mCapabilities.describeCoverage( identifier );
}
mCapabilities.describeCoverage( identifier );

populateTimes();

populateFormats();

Expand Down Expand Up @@ -194,7 +198,7 @@ QList<QgsOWSSupportedFormat> QgsWCSSourceSelect::providerFormats()
QList<QgsOWSSupportedFormat> formats;

QMap<QString, QString> mimes = QgsWcsProvider::supportedMimes();
foreach( QString mime, mimes.keys() )
foreach ( QString mime, mimes.keys() )
{
QgsOWSSupportedFormat format = { mime, mimes.value( mime ) };

Expand Down Expand Up @@ -239,6 +243,20 @@ QStringList QgsWCSSourceSelect::selectedLayersCRSs()
return c.supportedCrs;
}

QStringList QgsWCSSourceSelect::selectedLayersTimes()
{
QgsDebugMsg( "entered" );

QString identifier = selectedIdentifier();
if ( identifier.isEmpty() ) { return QStringList(); }

QgsWcsCoverageSummary c = mCapabilities.coverage( identifier );
if ( !c.valid ) { return QStringList(); }

QgsDebugMsg( "times = " + c.times.join( "," ) );
return c.times;
}

void QgsWCSSourceSelect::enableLayersForCrs( QTreeWidgetItem * )
{
// TODO: I am not convinced to disable layers according to selected CRS
Expand Down
1 change: 1 addition & 0 deletions src/providers/wcs/qgswcssourceselect.h
Expand Up @@ -78,6 +78,7 @@ class QgsWCSSourceSelect : public QgsOWSSourceSelect
QList<QgsOWSSupportedFormat> providerFormats();
QStringList selectedLayersFormats();
QStringList selectedLayersCRSs();
QStringList selectedLayersTimes();
};
#endif // QGSWCSSOURCESELECT_H

Expand Down

0 comments on commit e9afc7b

Please sign in to comment.