Skip to content

Commit

Permalink
Merge pull request #60343 from elpaso/bugfix-gh59353-server-gfy-displ…
Browse files Browse the repository at this point in the history
…ay_name-for-json

[server][wms] Add displayName to GFI JSON response
  • Loading branch information
rouault authored Jan 29, 2025
2 parents bb59344 + c4c27c6 commit de18045
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 2 deletions.
28 changes: 26 additions & 2 deletions src/server/services/wms/qgswmsrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2810,6 +2810,7 @@ namespace QgsWms
{ "features", json::array() },
};
const bool withGeometry = ( QgsServerProjectUtils::wmsFeatureInfoAddWktGeometry( *mProject ) && mWmsParameters.withGeometry() );
const bool withDisplayName = mWmsParameters.withDisplayName();

const QDomNodeList layerList = doc.elementsByTagName( QStringLiteral( "Layer" ) );
for ( int i = 0; i < layerList.size(); ++i )
Expand Down Expand Up @@ -2841,6 +2842,7 @@ namespace QgsWms
continue;

QMap<QgsFeatureId, QString> fidMap;
QMap<QgsFeatureId, QString> fidDisplayNameMap;

for ( int j = 0; j < featuresNode.size(); ++j )
{
Expand Down Expand Up @@ -2881,6 +2883,24 @@ namespace QgsWms
feature.setGeometry( QgsGeometry::fromWkt( wkt ) );
}
}

// Note: this is the feature expression display name, not the field alias
if ( withDisplayName )
{
QString displayName;
const QDomNodeList attrs = featureNode.elementsByTagName( "Attribute" );
for ( int k = 0; k < attrs.count(); k++ )
{
const QDomElement elm = attrs.at( k ).toElement();
if ( elm.attribute( QStringLiteral( "name" ) ).compare( "displayName" ) == 0 )
{
displayName = elm.attribute( "value" );
break;
}
}
fidDisplayNameMap.insert( feature.id(), displayName );
}

features << feature;

// search attributes to export (one time only)
Expand All @@ -2892,7 +2912,6 @@ namespace QgsWms
{
const QDomElement attributeElement = attributesNode.at( k ).toElement();
const QString fieldName = attributeElement.attribute( QStringLiteral( "name" ) );

attributes << feature.fieldNameIndex( fieldName );
}
}
Expand All @@ -2909,7 +2928,12 @@ namespace QgsWms
for ( const auto &feature : std::as_const( features ) )
{
const QString id = QStringLiteral( "%1.%2" ).arg( layerName ).arg( fidMap.value( feature.id() ) );
json["features"].push_back( exporter.exportFeatureToJsonObject( feature, QVariantMap(), id ) );
QVariantMap extraProperties;
if ( withDisplayName )
{
extraProperties.insert( QStringLiteral( "display_name" ), fidDisplayNameMap.value( feature.id() ) );
}
json["features"].push_back( exporter.exportFeatureToJsonObject( feature, extraProperties, id ) );
}
}
else // raster layer
Expand Down
60 changes: 60 additions & 0 deletions tests/src/python/test_qgsserver_wms_getfeatureinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,66 @@ def test_getfeatureinfo_form_config(self):
self.assertNotIn("name_xyz", body)
self.assertIn("id_xyz", body)

def test_getfeatureinfo_display_name(self):
"""Test issue GH #59353"""

# create a memory layer with points
fields = QgsFields()
fields.append(QgsField("id_xyz", QVariant.Int))
fields.append(QgsField("name_xyz", QVariant.String))
layer = QgsMemoryProviderUtils.createMemoryLayer(
"points",
fields,
QgsWkbTypes.Point,
QgsCoordinateReferenceSystem("EPSG:4326"),
)
layer.setDisplayExpression("name_xyz || ' (' || id_xyz || ')'")

provider = layer.dataProvider()
self.assertTrue(layer.isValid())

# add some features
f = QgsFeature(fields)
f.setAttribute("id_xyz", 1)
f.setAttribute("name_xyz", "point1")
f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(0, 0)))
provider.addFeature(f)

f = QgsFeature(fields)
f.setAttribute("id_xyz", 2)
f.setAttribute("name_xyz", "point2")
f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 1)))
provider.addFeature(f)

f = QgsFeature(fields)
f.setAttribute("id_xyz", 3)
f.setAttribute("name_xyz", "point3")
f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-1, -1)))
provider.addFeature(f)

project = QgsProject()
project.addMapLayer(layer)

# set up the WMS server
server = QgsServer()
request = QgsServerRequest()
w = 10
w2 = int(w / 2)

# Note: not implemented for , 'application/vnd.ogc.gml'
for info_format in ["text/plain", "application/json", "text/xml"]:

request.setUrl(
QUrl(
f"?SERVICE=WMS&REQUEST=GetFeatureInfo&LAYERS=points&QUERY_LAYERS=points&INFO_FORMAT={info_format}&FEATURE_COUNT=1&WIDTH={w}&HEIGHT={w}&CRS=EPSG:4326&STYLES=&WITH_DISPLAY_NAME=true&BBOX=-1,-1,1,1&X={w2}&Y={w2}&VERSION=1.3.0"
)
)
response = QgsBufferServerResponse()

server.handleRequest(request, response, project)
body = response.body().data().decode("utf8").replace("\n", " ")
self.assertIn("point1 (1)", body)


if __name__ == "__main__":
unittest.main()

0 comments on commit de18045

Please sign in to comment.