Skip to content

Commit

Permalink
implement separate wfs title (implements #55317)
Browse files Browse the repository at this point in the history
  • Loading branch information
jef-n committed Jun 21, 2024
1 parent cfb57fd commit ef9dbf6
Show file tree
Hide file tree
Showing 20 changed files with 176 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,15 @@ Sets the ``title`` of the layer used by QGIS Server in GetCapabilities request.
.. seealso:: :py:func:`title`

.. versionadded:: 3.38
%End

void setWfsTitle( const QString &title );
%Docstring
Sets the ``title`` of the layer used by QGIS Server in WFS GetCapabilities request.

.. seealso:: :py:func:`title`

.. versionadded:: 3.40
%End

QString title() const;
Expand All @@ -277,6 +286,16 @@ Returns the title of the layer used by QGIS Server in GetCapabilities request.
.. seealso:: :py:func:`setTitle`

.. versionadded:: 3.38
%End

QString wfsTitle() const;
%Docstring
Returns the optional WFS title if set or the title of the layer used by
QGIS WFS in GetCapabilities request.

.. seealso:: :py:func:`setWfsTitle`

.. versionadded:: 3.40
%End

void setAbstract( const QString &abstract );
Expand Down
19 changes: 19 additions & 0 deletions python/core/auto_generated/qgsmaplayerserverproperties.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,15 @@ Sets the ``title`` of the layer used by QGIS Server in GetCapabilities request.
.. seealso:: :py:func:`title`

.. versionadded:: 3.38
%End

void setWfsTitle( const QString &title );
%Docstring
Sets the ``title`` of the layer used by QGIS Server in WFS GetCapabilities request.

.. seealso:: :py:func:`title`

.. versionadded:: 3.40
%End

QString title() const;
Expand All @@ -277,6 +286,16 @@ Returns the title of the layer used by QGIS Server in GetCapabilities request.
.. seealso:: :py:func:`setTitle`

.. versionadded:: 3.38
%End

QString wfsTitle() const;
%Docstring
Returns the optional WFS title if set or the title of the layer used by
QGIS WFS in GetCapabilities request.

.. seealso:: :py:func:`setWfsTitle`

.. versionadded:: 3.40
%End

void setAbstract( const QString &abstract );
Expand Down
6 changes: 6 additions & 0 deletions src/core/qgsmaplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,12 @@ bool QgsMapLayer::writeLayerXml( QDomElement &layerElement, QDomDocument &docume
QDomElement layerTitle = document.createElement( QStringLiteral( "title" ) );
const QDomText layerTitleText = document.createTextNode( mServerProperties->title() );
layerTitle.appendChild( layerTitleText );

if ( mServerProperties->title() != mServerProperties->wfsTitle() )
{
layerTitle.setAttribute( "wfs", mServerProperties->wfsTitle() );
}

layerElement.appendChild( layerTitle );
}

Expand Down
1 change: 1 addition & 0 deletions src/core/qgsmaplayerserverproperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ void QgsMapLayerServerProperties::readXml( const QDomNode &layer_node )
if ( !titleElem.isNull() )
{
mTitle = titleElem.text();
mWfsTitle = titleElem.attribute( QStringLiteral( "wfs" ) );
}

//abstract
Expand Down
20 changes: 20 additions & 0 deletions src/core/qgsmaplayerserverproperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,15 @@ class CORE_EXPORT QgsMapLayerServerProperties: public QgsServerMetadataUrlProper
*/
void setTitle( const QString &title ) { mTitle = title; }

/**
* Sets the \a title of the layer used by QGIS Server in WFS GetCapabilities request.
*
* \see title()
*
* \since QGIS 3.40
*/
void setWfsTitle( const QString &title ) { mWfsTitle = title; }

/**
* Returns the title of the layer used by QGIS Server in GetCapabilities request.
*
Expand All @@ -343,6 +352,16 @@ class CORE_EXPORT QgsMapLayerServerProperties: public QgsServerMetadataUrlProper
*/
QString title() const { return mTitle; }

/**
* Returns the optional WFS title if set or the title of the layer used by
* QGIS WFS in GetCapabilities request.
*
* \see setWfsTitle()
*
* \since QGIS 3.40
*/
QString wfsTitle() const { return mWfsTitle.isEmpty() ? mTitle : mWfsTitle; }

/**
* Sets the \a abstract of the layer used by QGIS Server in GetCapabilities request.
*
Expand Down Expand Up @@ -475,6 +494,7 @@ class CORE_EXPORT QgsMapLayerServerProperties: public QgsServerMetadataUrlProper

QString mShortName;
QString mTitle;
QString mWfsTitle; // optional WFS title

QString mAttribution;
QString mAttributionUrl;
Expand Down
12 changes: 12 additions & 0 deletions src/gui/vector/qgsvectorlayerproperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(

//layer title and abstract
mLayerTitleLineEdit->setText( mLayer->serverProperties()->title() );
if ( mLayer->serverProperties()->wfsTitle() != mLayer->serverProperties()->title() )
mLayerOptWfsTitleLineEdit->setText( mLayer->serverProperties()->wfsTitle() );
mLayerAbstractTextEdit->setPlainText( mLayer->serverProperties()->abstract() );
mLayerKeywordListLineEdit->setText( mLayer->serverProperties()->keywordList() );
mLayerDataUrlLineEdit->setText( mLayer->serverProperties()->dataUrl() );
Expand Down Expand Up @@ -834,6 +836,16 @@ void QgsVectorLayerProperties::apply()
mMetadataFilled = false;
mLayer->serverProperties()->setTitle( mLayerTitleLineEdit->text() );

if ( !mLayerOptWfsTitleLineEdit->text().isEmpty() && mLayerOptWfsTitleLineEdit->text() != mLayerTitleLineEdit->text() )
{
mLayer->serverProperties()->setWfsTitle( mLayerOptWfsTitleLineEdit->text() );
mMetadataFilled = false;
}
else
{
mLayer->serverProperties()->setWfsTitle( QString() );
}

if ( mLayer->serverProperties()->abstract() != mLayerAbstractTextEdit->toPlainText() )
mMetadataFilled = false;
mLayer->serverProperties()->setAbstract( mLayerAbstractTextEdit->toPlainText() );
Expand Down
2 changes: 1 addition & 1 deletion src/server/services/wfs/qgswfsgetcapabilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ namespace QgsWfs

//create Title
QDomElement titleElem = doc.createElement( QStringLiteral( "Title" ) );
QString title = layer->serverProperties()->title();
QString title = layer->serverProperties()->wfsTitle();
if ( title.isEmpty() )
{
title = layer->name();
Expand Down
14 changes: 7 additions & 7 deletions src/server/services/wfs3/qgswfs3handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ void QgsWfs3CollectionsHandler::handleRequest( const QgsServerApiContext &contex
// Check if the layer is published, raise not found if it is not
checkLayerIsAccessible( layer, context );

const std::string title{layer->serverProperties()->title().isEmpty() ? layer->name().toStdString() : layer->serverProperties()->title().toStdString()};
const std::string title{layer->serverProperties()->wfsTitle().isEmpty() ? layer->name().toStdString() : layer->serverProperties()->wfsTitle().toStdString()};
const QString shortName{layer->serverProperties()->shortName().isEmpty() ? layer->name() : layer->serverProperties()->shortName()};
data["collections"].push_back(
{
Expand Down Expand Up @@ -633,7 +633,7 @@ void QgsWfs3DescribeCollectionHandler::handleRequest( const QgsServerApiContext
// Check if the layer is published, raise not found if it is not
checkLayerIsAccessible( mapLayer, context );

const std::string title { mapLayer->serverProperties()->title().isEmpty() ? mapLayer->name().toStdString() : mapLayer->serverProperties()->title().toStdString() };
const std::string title { mapLayer->serverProperties()->wfsTitle().isEmpty() ? mapLayer->name().toStdString() : mapLayer->serverProperties()->wfsTitle().toStdString() };
const std::string itemsTitle { title + " items" };
const QString shortName { mapLayer->serverProperties()->shortName().isEmpty() ? mapLayer->name() : mapLayer->serverProperties()->shortName() };
json linksList = links( context );
Expand Down Expand Up @@ -720,7 +720,7 @@ json QgsWfs3DescribeCollectionHandler::schema( const QgsServerApiContext &contex
const QString shortName { mapLayer->serverProperties()->shortName().isEmpty() ? mapLayer->name() : mapLayer->serverProperties()->shortName() };
// Use layer id for operationId
const QString layerId { mapLayer->id() };
const std::string title { mapLayer->serverProperties()->title().isEmpty() ? mapLayer->name().toStdString() : mapLayer->serverProperties()->title().toStdString() };
const std::string title { mapLayer->serverProperties()->wfsTitle().isEmpty() ? mapLayer->name().toStdString() : mapLayer->serverProperties()->wfsTitle().toStdString() };
const std::string path { QgsServerApiUtils::appendMapParameter( context.apiRootPath() + QStringLiteral( "/collections/%1" ).arg( shortName ), context.request()->url() ).toStdString() };

data[ path ] =
Expand Down Expand Up @@ -978,7 +978,7 @@ json QgsWfs3CollectionsItemsHandler::schema( const QgsServerApiContext &context
for ( const auto &mapLayer : layers )
{
const QString shortName { mapLayer->serverProperties()->shortName().isEmpty() ? mapLayer->name() : mapLayer->serverProperties()->shortName() };
const std::string title { mapLayer->serverProperties()->title().isEmpty() ? mapLayer->name().toStdString() : mapLayer->serverProperties()->title().toStdString() };
const std::string title { mapLayer->serverProperties()->wfsTitle().isEmpty() ? mapLayer->name().toStdString() : mapLayer->serverProperties()->wfsTitle().toStdString() };
// Use layer id for operationId
const QString layerId { mapLayer->id() };
const QString path { QgsServerApiUtils::appendMapParameter( context.apiRootPath() + QStringLiteral( "/collections/%1/items" ).arg( shortName ), context.request()->url() ) };
Expand Down Expand Up @@ -1142,7 +1142,7 @@ void QgsWfs3CollectionsItemsHandler::handleRequest( const QgsServerApiContext &c
// Check if the layer is published, raise not found if it is not
checkLayerIsAccessible( mapLayer, context );

const std::string title { mapLayer->serverProperties()->title().isEmpty() ? mapLayer->name().toStdString() : mapLayer->serverProperties()->title().toStdString() };
const std::string title { mapLayer->serverProperties()->wfsTitle().isEmpty() ? mapLayer->name().toStdString() : mapLayer->serverProperties()->wfsTitle().toStdString() };

// Get parameters
QVariantMap params = values( context );
Expand Down Expand Up @@ -1740,7 +1740,7 @@ void QgsWfs3CollectionsFeatureHandler::handleRequest( const QgsServerApiContext
// Check if the layer is published, raise not found if it is not
checkLayerIsAccessible( mapLayer, context );

const std::string title { mapLayer->serverProperties()->title().isEmpty() ? mapLayer->name().toStdString() : mapLayer->serverProperties()->title().toStdString() };
const std::string title { mapLayer->serverProperties()->wfsTitle().isEmpty() ? mapLayer->name().toStdString() : mapLayer->serverProperties()->wfsTitle().toStdString() };

// Retrieve feature from storage
const QString featureId { match.captured( QStringLiteral( "featureId" ) ) };
Expand Down Expand Up @@ -2145,7 +2145,7 @@ json QgsWfs3CollectionsFeatureHandler::schema( const QgsServerApiContext &contex
const QString shortName { mapLayer->serverProperties()->shortName().isEmpty() ? mapLayer->name() : mapLayer->serverProperties()->shortName() };
// Use layer id for operationId
const QString layerId { mapLayer->id() };
const std::string title { mapLayer->serverProperties()->title().isEmpty() ? mapLayer->name().toStdString() : mapLayer->serverProperties()->title().toStdString() };
const std::string title { mapLayer->serverProperties()->wfsTitle().isEmpty() ? mapLayer->name().toStdString() : mapLayer->serverProperties()->wfsTitle().toStdString() };
const std::string path { QgsServerApiUtils::appendMapParameter( context.apiRootPath() + QStringLiteral( "/collections/%1/items/{featureId}" ).arg( shortName ), context.request()->url() ).toStdString() };

data[ path ] =
Expand Down
32 changes: 26 additions & 6 deletions src/ui/qgsvectorlayerpropertiesbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -2259,7 +2259,27 @@
</property>
</widget>
</item>
<item row="5" column="1">
<item row="2" column="0">
<widget class="QLabel" name="mLayerOptWfsTitleLabel">
<property name="text">
<string>WFS title</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="mLayerOptWfsTitleLineEdit">
<property name="toolTip">
<string>The alternative title is for the benefit of humans to identify the WFS layer if the original title is only helpful with the WMS grouping.</string>
</property>
<property name="text">
<string/>
</property>
<property name="placeholderText">
<string>Optional alternative title for the layer for use with WFS</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="mLayerKeywordListLineEdit">
<property name="toolTip">
<string>List of keywords separated by comma to help catalog searching.</string>
Expand All @@ -2269,7 +2289,7 @@
</property>
</widget>
</item>
<item row="6" column="1">
<item row="7" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLineEdit" name="mLayerDataUrlLineEdit">
Expand Down Expand Up @@ -2309,7 +2329,7 @@
</item>
</layout>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QLabel" name="mLayerKeywordListLabel">
<property name="text">
<string>Keyword list</string>
Expand Down Expand Up @@ -2349,14 +2369,14 @@
</property>
</widget>
</item>
<item row="3" column="0">
<item row="4" column="0">
<widget class="QLabel" name="mLayerAbstractLabel">
<property name="text">
<string>Abstract</string>
</property>
</widget>
</item>
<item row="3" column="1">
<item row="4" column="1">
<widget class="QPlainTextEdit" name="mLayerAbstractTextEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
Expand All @@ -2375,7 +2395,7 @@
</property>
</widget>
</item>
<item row="6" column="0">
<item row="7" column="0">
<widget class="QLabel" name="mLayerDataUrlLabel">
<property name="text">
<string>Data URL</string>
Expand Down
27 changes: 27 additions & 0 deletions tests/src/python/test_qgsmaplayerserverproperties.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,33 @@ def test_metadata_url(self):
other = QgsMapLayerServerProperties.MetadataUrl("https://my.url", "FGDC", "text/xml")
self.assertTrue(url == other)

def test_wfs_title(self):
layer = QgsVectorLayer('Point?field=fldtxt:string', 'layer_1', 'memory')

self.assertEqual("", layer.title())
self.assertEqual("", layer.serverProperties().title())
self.assertEqual("", layer.serverProperties().wfsTitle())

layer.serverProperties().setTitle("title")
self.assertEqual("title", layer.title())
self.assertEqual("title", layer.serverProperties().title())
self.assertEqual("title", layer.serverProperties().wfsTitle())

layer.serverProperties().setWfsTitle("wfstitle")
self.assertEqual("title", layer.title())
self.assertEqual("title", layer.serverProperties().title())
self.assertEqual("wfstitle", layer.serverProperties().wfsTitle())

layer.serverProperties().setTitle("title2")
self.assertEqual("title2", layer.title())
self.assertEqual("title2", layer.serverProperties().title())
self.assertEqual("wfstitle", layer.serverProperties().wfsTitle())

layer.serverProperties().setWfsTitle("")
self.assertEqual("title2", layer.title())
self.assertEqual("title2", layer.serverProperties().title())
self.assertEqual("title2", layer.serverProperties().wfsTitle())


if __name__ == '__main__':
unittest.main()
12 changes: 6 additions & 6 deletions tests/testdata/qgis_server/api/test_wfs3_api_project.json
Original file line number Diff line number Diff line change
Expand Up @@ -1694,7 +1694,7 @@ Content-Type: application/vnd.oai.openapi+json;version=3.0
}
}
},
"description": "Metadata about the collection 'A test vector layer èé' shared by this API."
"description": "Metadata about the collection 'A test wfs vector layer èé' shared by this API."
},
"default": {
"content": {
Expand All @@ -1712,7 +1712,7 @@ Content-Type: application/vnd.oai.openapi+json;version=3.0
"description": "An error occurred."
}
},
"summary": "Describe the 'A test vector layer èé' feature collection",
"summary": "Describe the 'A test wfs vector layer èé' feature collection",
"tags": [
"Capabilities"
]
Expand Down Expand Up @@ -1809,7 +1809,7 @@ Content-Type: application/vnd.oai.openapi+json;version=3.0
}
}
},
"description": "Metadata about the collection 'A test vector layer èé' shared by this API."
"description": "Metadata about the collection 'A test wfs vector layer èé' shared by this API."
},
"default": {
"content": {
Expand All @@ -1827,7 +1827,7 @@ Content-Type: application/vnd.oai.openapi+json;version=3.0
"description": "An error occurred."
}
},
"summary": "Retrieve features of 'A test vector layer èé' feature collection",
"summary": "Retrieve features of 'A test wfs vector layer èé' feature collection",
"tags": [
"Features"
]
Expand Down Expand Up @@ -1926,7 +1926,7 @@ Content-Type: application/vnd.oai.openapi+json;version=3.0
}
}
},
"description": "Retrieve a 'A test vector layer èé' feature by 'featureId'."
"description": "Retrieve a 'A test wfs vector layer èé' feature by 'featureId'."
},
"default": {
"content": {
Expand All @@ -1944,7 +1944,7 @@ Content-Type: application/vnd.oai.openapi+json;version=3.0
"description": "An error occurred."
}
},
"summary": "Retrieve a single feature from the 'A test vector layer èé' feature collection",
"summary": "Retrieve a single feature from the 'A test wfs vector layer èé' feature collection",
"tags": [
"Features"
]
Expand Down
Loading

0 comments on commit ef9dbf6

Please sign in to comment.