diff --git a/src/server/services/wms/qgswmsrenderer.cpp b/src/server/services/wms/qgswmsrenderer.cpp index d3749453ed66..185df933ad5b 100644 --- a/src/server/services/wms/qgswmsrenderer.cpp +++ b/src/server/services/wms/qgswmsrenderer.cpp @@ -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 ) @@ -2841,6 +2842,7 @@ namespace QgsWms continue; QMap fidMap; + QMap fidDisplayNameMap; for ( int j = 0; j < featuresNode.size(); ++j ) { @@ -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) @@ -2892,7 +2912,6 @@ namespace QgsWms { const QDomElement attributeElement = attributesNode.at( k ).toElement(); const QString fieldName = attributeElement.attribute( QStringLiteral( "name" ) ); - attributes << feature.fieldNameIndex( fieldName ); } } @@ -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 diff --git a/tests/src/python/test_qgsserver_wms_getfeatureinfo.py b/tests/src/python/test_qgsserver_wms_getfeatureinfo.py index 4b05eb0a6459..d0f7813d11cb 100644 --- a/tests/src/python/test_qgsserver_wms_getfeatureinfo.py +++ b/tests/src/python/test_qgsserver_wms_getfeatureinfo.py @@ -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()