Skip to content

Commit

Permalink
[QGIS-Server] Update UI for WCS configuration
Browse files Browse the repository at this point in the history
In the project properties OWS tab, the user can select the layers he
would like to publish in a Web Coverage Service.
  • Loading branch information
rldhont committed Jan 7, 2014
1 parent 7e254b4 commit df48b05
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 10 deletions.
80 changes: 80 additions & 0 deletions src/app/qgsprojectproperties.cpp
Expand Up @@ -430,6 +430,43 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *pa
twWFSLayers->setRowCount( j );
twWFSLayers->verticalHeader()->setResizeMode( QHeaderView::ResizeToContents );

mWCSUrlLineEdit->setText( QgsProject::instance()->readEntry( "WCSUrl", "/", "" ) );
QStringList wcsLayerIdList = QgsProject::instance()->readListEntry( "WCSLayers", "/" );

QSignalMapper *smWcsPublied = new QSignalMapper( this );
connect( smWcsPublied, SIGNAL( mapped( int ) ), this, SLOT( cbxWCSPubliedStateChanged( int ) ) );

twWCSLayers->setColumnCount( 2 );
twWCSLayers->horizontalHeader()->setVisible( true );
twWCSLayers->setRowCount( mapLayers.size() );

i = 0;
j = 0;
for ( QMap<QString, QgsMapLayer*>::const_iterator it = mapLayers.constBegin(); it != mapLayers.constEnd(); it++, i++ )
{
currentLayer = it.value();
if ( currentLayer->type() == QgsMapLayer::RasterLayer )
{

QTableWidgetItem *twi = new QTableWidgetItem( QString::number( j ) );
twWCSLayers->setVerticalHeaderItem( j, twi );

twi = new QTableWidgetItem( currentLayer->name() );
twi->setData( Qt::UserRole, it.key() );
twi->setFlags( twi->flags() & ~Qt::ItemIsEditable );
twWCSLayers->setItem( j, 0, twi );

QCheckBox* cbp = new QCheckBox();
cbp->setChecked( wcsLayerIdList.contains( currentLayer->id() ) );
twWCSLayers->setCellWidget( j, 1, cbp );

smWcsPublied->setMapping( cbp, j );
connect( cbp, SIGNAL( stateChanged( int ) ), smWcsPublied, SLOT( map() ) );

j++;
}
}

// Default Styles
mStyle = QgsStyleV2::defaultStyle();
populateStyles();
Expand Down Expand Up @@ -797,6 +834,20 @@ void QgsProjectProperties::apply()
QgsProject::instance()->writeEntry( "WFSTLayers", "Insert", wfstInsertLayerList );
QgsProject::instance()->writeEntry( "WFSTLayers", "Delete", wfstDeleteLayerList );

QgsProject::instance()->writeEntry( "WCSUrl", "/", mWCSUrlLineEdit->text() );
QStringList wcsLayerList;
for ( int i = 0; i < twWCSLayers->rowCount(); i++ )
{
QString id = twWCSLayers->item( i, 0 )->data( Qt::UserRole ).toString();
QCheckBox* cb;
cb = qobject_cast<QCheckBox *>( twWCSLayers->cellWidget( i, 1 ) );
if ( cb && cb->isChecked() )
{
wcsLayerList << id;
}
}
QgsProject::instance()->writeEntry( "WCSLayers", "/", wcsLayerList );

// Default Styles
QgsProject::instance()->writeEntry( "DefaultStyles", "/Marker", cboStyleMarker->currentText() );
QgsProject::instance()->writeEntry( "DefaultStyles", "/Line", cboStyleLine->currentText() );
Expand Down Expand Up @@ -943,6 +994,17 @@ void QgsProjectProperties::cbxWFSDeleteStateChanged( int aIdx )
}
}

void QgsProjectProperties::cbxWCSPubliedStateChanged( int aIdx )
{
QCheckBox* cb = qobject_cast<QCheckBox *>( twWCSLayers->cellWidget( aIdx, 1 ) );
if ( cb && !cb->isChecked() )
{
QCheckBox* cbn = qobject_cast<QCheckBox *>( twWCSLayers->cellWidget( aIdx, 2 ) );
if ( cbn )
cbn->setChecked( false );
}
}

void QgsProjectProperties::setMapUnitsToCurrentProjection()
{
long myCRSID = projectionSelector->selectedCrsId();
Expand Down Expand Up @@ -1138,6 +1200,24 @@ void QgsProjectProperties::on_pbnWFSLayersUnselectAll_clicked()
}
}

void QgsProjectProperties::on_pbnWCSLayersSelectAll_clicked()
{
for ( int i = 0; i < twWCSLayers->rowCount(); i++ )
{
QCheckBox *cb = qobject_cast<QCheckBox *>( twWCSLayers->cellWidget( i, 1 ) );
cb->setChecked( true );
}
}

void QgsProjectProperties::on_pbnWCSLayersUnselectAll_clicked()
{
for ( int i = 0; i < twWCSLayers->rowCount(); i++ )
{
QCheckBox *cb = qobject_cast<QCheckBox *>( twWCSLayers->cellWidget( i, 1 ) );
cb->setChecked( false );
}
}

void QgsProjectProperties::on_pbnAddScale_clicked()
{
int myScale = QInputDialog::getInt(
Expand Down
11 changes: 11 additions & 0 deletions src/app/qgsprojectproperties.h
Expand Up @@ -115,6 +115,12 @@ class APP_EXPORT QgsProjectProperties : public QgsOptionsDialogBase, private Ui:
void on_pbnWFSLayersSelectAll_clicked();
void on_pbnWFSLayersUnselectAll_clicked();

/*!
* Slots to select/unselect all the WCS layers
*/
void on_pbnWCSLayersSelectAll_clicked();
void on_pbnWCSLayersUnselectAll_clicked();

/*!
* Slots for Styles
*/
Expand All @@ -141,6 +147,11 @@ class APP_EXPORT QgsProjectProperties : public QgsOptionsDialogBase, private Ui:
void cbxWFSInsertStateChanged( int aIdx );
void cbxWFSDeleteStateChanged( int aIdx );

/*!
* Slot to link WCS checkboxes
*/
void cbxWCSPubliedStateChanged( int aIdx );

/*!
* If user changes the CRS, set the corresponding map units
*/
Expand Down
7 changes: 7 additions & 0 deletions src/mapserver/qgsconfigparser.h
Expand Up @@ -82,6 +82,9 @@ class QgsConfigParser
/**Returns the names of the published wfs layers (not the ids as in wfsLayers() )*/
virtual QStringList wfsLayerNames() const { return QStringList(); }

/**Returns the names of the published wcs layers (not the ids as in wcsLayers() )*/
virtual QStringList wcsLayerNames() const { return QStringList(); }

/**Possibility to add a parameter map to the config parser. This is used by the SLD parser. Default implementation does nothing*/
virtual void setParameterMap( const QMap<QString, QString>& parameterMap )
{ Q_UNUSED( parameterMap ); }
Expand Down Expand Up @@ -120,6 +123,9 @@ class QgsConfigParser
virtual QStringList wfstInsertLayers() const { return QStringList(); }
virtual QStringList wfstDeleteLayers() const { return QStringList(); }

/**Returns an ID-list of layers which queryable in WCS service*/
virtual QStringList wcsLayers() const { return QStringList(); }

/**Returns a set of supported epsg codes for the capabilities document. An empty list means
that all possible CRS should be advertised (which could result in very long capabilities documents)*/
virtual QStringList supportedOutputCrsList() const { return QStringList(); }
Expand All @@ -142,6 +148,7 @@ class QgsConfigParser
/**Returns service address (or empty string if not defined in the configuration*/
virtual QString serviceUrl() const { return QString(); }
virtual QString wfsServiceUrl() const { return QString(); }
virtual QString wcsServiceUrl() const { return QString(); }

QColor selectionColor() const { return mSelectionColor; }
void setSelectionColor( const QColor& c ) { mSelectionColor = c; }
Expand Down
102 changes: 94 additions & 8 deletions src/mapserver/qgsprojectparser.cpp
Expand Up @@ -140,16 +140,16 @@ void QgsProjectParser::layersAndStylesCapabilities( QDomElement& parentElement,

void QgsProjectParser::featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const
{
QStringList wfsLayersId = wfsLayers();
QStringList wfstUpdateLayersId = wfstUpdateLayers();
QStringList wfstInsertLayersId = wfstInsertLayers();
QStringList wfstDeleteLayersId = wfstDeleteLayers();

if ( mProjectLayerElements.size() < 1 )
{
return;
}

QStringList wfsLayersId = wfsLayers();
QStringList wfstUpdateLayersId = wfstUpdateLayers();
QStringList wfstInsertLayersId = wfstInsertLayers();
QStringList wfstDeleteLayersId = wfstDeleteLayers();

QMap<QString, QgsMapLayer *> layerMap;

foreach ( const QDomElement &elem, mProjectLayerElements )
Expand Down Expand Up @@ -279,12 +279,13 @@ void QgsProjectParser::featureTypeList( QDomElement& parentElement, QDomDocument

void QgsProjectParser::wcsContentMetadata( QDomElement& parentElement, QDomDocument& doc ) const
{

if ( mProjectLayerElements.size() < 1 )
{
return;
}

QStringList wcsLayersId = wcsLayers();

QMap<QString, QgsMapLayer *> layerMap;

foreach ( const QDomElement &elem, mProjectLayerElements )
Expand All @@ -294,7 +295,7 @@ void QgsProjectParser::wcsContentMetadata( QDomElement& parentElement, QDomDocum
{
//QgsMapLayer *layer = createLayerFromElement( *layerIt );
QgsMapLayer *layer = createLayerFromElement( elem );
if ( layer )
if ( layer && wcsLayersId.contains( layer->id() ) )
{
QgsDebugMsg( QString( "add layer %1 to map" ).arg( layer->id() ) );
layerMap.insert( layer->id(), layer );
Expand Down Expand Up @@ -640,6 +641,7 @@ void QgsProjectParser::describeCoverage( const QString& aCoveName, QDomElement&
return;
}

QStringList wcsLayersId = wcsLayers();
QStringList coveNameList;
if ( aCoveName != "" )
{
Expand All @@ -663,7 +665,7 @@ void QgsProjectParser::describeCoverage( const QString& aCoveName, QDomElement&
continue;
QString coveName = layer->name();
coveName = coveName.replace( " ", "_" );
if ( aCoveName == "" || coveNameList.contains( coveName ) )
if ( wcsLayersId.contains( layer->id() ) && ( aCoveName == "" || coveNameList.contains( coveName ) ) )
{
QgsDebugMsg( QString( "add layer %1 to map" ).arg( layer->id() ) );
layerMap.insert( layer->id(), layer );
Expand Down Expand Up @@ -852,6 +854,8 @@ QList<QgsMapLayer*> QgsProjectParser::mapLayerFromTypeName( const QString& tName
{
QgsMapLayer *mLayer = createLayerFromElement( elem, useCache );
QgsVectorLayer* layer = dynamic_cast<QgsVectorLayer*>( mLayer );
if ( !layer || !wfsLayersId.contains( layer->id() ) )
return layerList;

QString typeName = layer->name();
typeName = typeName.replace( " ", "_" );
Expand All @@ -874,13 +878,17 @@ QList<QgsMapLayer*> QgsProjectParser::mapLayerFromCoverage( const QString& cName
return layerList;
}

QStringList wcsLayersId = wcsLayers();

foreach ( const QDomElement &elem, mProjectLayerElements )
{
QString type = elem.attribute( "type" );
if ( type == "raster" )
{
QgsMapLayer *mLayer = createLayerFromElement( elem, useCache );
QgsRasterLayer* layer = dynamic_cast<QgsRasterLayer*>( mLayer );
if ( !layer || !wcsLayersId.contains( layer->id() ) )
return layerList;

QString coveName = layer->name();
coveName = coveName.replace( " ", "_" );
Expand Down Expand Up @@ -2113,6 +2121,37 @@ QStringList QgsProjectParser::wfstDeleteLayers() const
return wfsList;
}

QStringList QgsProjectParser::wcsLayers() const
{
QStringList wcsList;
if ( !mXMLDoc )
{
return wcsList;
}

QDomElement qgisElem = mXMLDoc->documentElement();
if ( qgisElem.isNull() )
{
return wcsList;
}
QDomElement propertiesElem = qgisElem.firstChildElement( "properties" );
if ( propertiesElem.isNull() )
{
return wcsList;
}
QDomElement wcsLayersElem = propertiesElem.firstChildElement( "WCSLayers" );
if ( wcsLayersElem.isNull() )
{
return wcsList;
}
QDomNodeList valueList = wcsLayersElem.elementsByTagName( "value" );
for ( int i = 0; i < valueList.size(); ++i )
{
wcsList << valueList.at( i ).toElement().text();
}
return wcsList;
}

QStringList QgsProjectParser::supportedOutputCrsList() const
{
QStringList crsList;
Expand Down Expand Up @@ -3201,6 +3240,53 @@ QStringList QgsProjectParser::wfsLayerNames() const
return layerNameList;
}

QString QgsProjectParser::wcsServiceUrl() const
{
QString url;

if ( !mXMLDoc )
{
return url;
}

QDomElement propertiesElem = mXMLDoc->documentElement().firstChildElement( "properties" );
if ( !propertiesElem.isNull() )
{
QDomElement wcsUrlElem = propertiesElem.firstChildElement( "WCSUrl" );
if ( !wcsUrlElem.isNull() )
{
url = wcsUrlElem.text();
}
}
return url;
}

QStringList QgsProjectParser::wcsLayerNames() const
{
QStringList layerNameList;

QMap<QString, QgsMapLayer*> layerMap;
projectLayerMap( layerMap );

QgsMapLayer* currentLayer = 0;
QStringList wcsIdList = wcsLayers();
QStringList::const_iterator wcsIdIt = wcsIdList.constBegin();
for ( ; wcsIdIt != wcsIdList.constEnd(); ++wcsIdIt )
{
QMap<QString, QgsMapLayer*>::const_iterator layerMapIt = layerMap.find( *wcsIdIt );
if ( layerMapIt != layerMap.constEnd() )
{
currentLayer = layerMapIt.value();
if ( currentLayer )
{
layerNameList.append( currentLayer->name() );
}
}
}

return layerNameList;
}

QHash<QString, QString> QgsProjectParser::featureInfoLayerAliasMap() const
{
QHash<QString, QString> aliasMap;
Expand Down
8 changes: 8 additions & 0 deletions src/mapserver/qgsprojectparser.h
Expand Up @@ -87,6 +87,9 @@ class QgsProjectParser: public QgsConfigParser
virtual QStringList wfstInsertLayers() const;
virtual QStringList wfstDeleteLayers() const;

/**Returns an ID-list of layers queryable for WCS service (comes from <properties> -> <WCSLayers> in the project file*/
virtual QStringList wcsLayers() const;

/**Returns a set of supported epsg codes for the capabilities document. The list comes from the property <WMSEpsgList> in the project file.
An empty set means that all possible CRS should be advertised (which could result in very long capabilities documents)
Example:
Expand Down Expand Up @@ -127,9 +130,14 @@ class QgsProjectParser: public QgsConfigParser

QString wfsServiceUrl() const;

QString wcsServiceUrl() const;

/**Returns the names of the published wfs layers (not the ids as in wfsLayers() )*/
QStringList wfsLayerNames() const;

/**Returns the names of the published wcs layers (not the ids as in wcsLayers() )*/
QStringList wcsLayerNames() const;

/**Returns map with layer aliases for GetFeatureInfo (or 0 pointer if not supported). Key: layer name, Value: layer alias*/
virtual QHash<QString, QString> featureInfoLayerAliasMap() const;

Expand Down
6 changes: 4 additions & 2 deletions src/mapserver/qgswcsserver.cpp
Expand Up @@ -90,7 +90,7 @@ QDomDocument QgsWCSServer::getCapabilities()
dcpTypeElement.appendChild( httpElement );

//Prepare url
QString hrefString = mConfigParser->wfsServiceUrl();
QString hrefString = mConfigParser->wcsServiceUrl();
if ( hrefString.isEmpty() )
{
hrefString = mConfigParser->serviceUrl();
Expand Down Expand Up @@ -172,6 +172,8 @@ QDomDocument QgsWCSServer::describeCoverage()

QByteArray* QgsWCSServer::getCoverage()
{
QStringList wcsLayersId = mConfigParser->wcsLayers();

QList<QgsMapLayer*> layerList;

QStringList mErrors = QStringList();
Expand Down Expand Up @@ -273,7 +275,7 @@ QByteArray* QgsWCSServer::getCoverage()

QgsMapLayer* layer = layerList.at( 0 );
QgsRasterLayer* rLayer = dynamic_cast<QgsRasterLayer*>( layer );
if ( rLayer )
if ( rLayer && wcsLayersId.contains( rLayer->id() ) )
{
QTemporaryFile tempFile;
tempFile.open();
Expand Down

1 comment on commit df48b05

@slarosa
Copy link
Member

@slarosa slarosa commented on df48b05 Jan 9, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comment [0] was related at this changes. Sorry.

[0] - #1025 (comment)

Please sign in to comment.