Merge pull request #60243 from elpaso/bugfix-gh59818-server-wms-gfi-tolerance

[server][wms] GFI: fix sub-pixel tolerance
This commit is contained in:
Alessandro Pasotti 2025-01-24 08:57:41 +01:00 committed by GitHub
commit f99111c692
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 66 additions and 2 deletions

View File

@ -3153,6 +3153,9 @@ namespace QgsWms
}
}
// Make sure the map unit tolerance is at least 1 pixel
mapUnitTolerance = std::max( mapUnitTolerance, 1.0 * rct.mapToPixel().mapUnitsPerPixel() );
QgsRectangle mapRectangle( infoPoint.x() - mapUnitTolerance, infoPoint.y() - mapUnitTolerance, infoPoint.x() + mapUnitTolerance, infoPoint.y() + mapUnitTolerance );
return ( mapSettings.mapToLayerCoordinates( ml, mapRectangle ) );
}

View File

@ -37,9 +37,15 @@ from qgis.core import (
QgsMemoryProviderUtils,
QgsProject,
QgsWkbTypes,
QgsPointXY,
)
from qgis.PyQt.QtCore import QVariant, QUrl
from qgis.server import (
QgsBufferServerRequest,
QgsBufferServerResponse,
QgsServer,
QgsServerRequest,
)
from qgis.PyQt.QtCore import QVariant
from qgis.server import QgsBufferServerRequest, QgsBufferServerResponse
from qgis.testing import unittest, QgisTestCase
from test_qgsserver_wms import TestQgsServerWMSTestBase
@ -1357,6 +1363,61 @@ class TestQgsServerWMSGetFeatureInfo(TestQgsServerWMSTestBase):
"test_project_values.qgz",
)
def test_getfeatureinfo_sub_px_tolerance(self):
# create a memory layer with points
fields = QgsFields()
fields.append(QgsField("id", QVariant.Int))
fields.append(QgsField("name", QVariant.String))
layer = QgsMemoryProviderUtils.createMemoryLayer(
"points",
fields,
QgsWkbTypes.Point,
QgsCoordinateReferenceSystem("EPSG:4326"),
)
provider = layer.dataProvider()
self.assertTrue(layer.isValid())
# add some features
f = QgsFeature(fields)
f.setAttribute("id", 1)
f.setAttribute("name", "point1")
f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(0, 0)))
provider.addFeature(f)
f = QgsFeature(fields)
f.setAttribute("id", 2)
f.setAttribute("name", "point2")
f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 1)))
provider.addFeature(f)
f = QgsFeature(fields)
f.setAttribute("id", 2)
f.setAttribute("name", "point2")
f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-1, -1)))
provider.addFeature(f)
project = QgsProject()
project.addMapLayer(layer)
# set up the WMS server
server = QgsServer()
request = QgsServerRequest()
# Choose a small extent to trigger the sub-pixel tolerance adjustment
w = 10
w2 = int(w / 2)
request.setUrl(
QUrl(
f"?SERVICE=WMS&REQUEST=GetFeatureInfo&LAYERS=points&QUERY_LAYERS=points&INFO_FORMAT=application/json&FEATURE_COUNT=1&WIDTH={w}&HEIGHT={w}&CRS=EPSG:4326&STYLES=&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.assertEqual(len(json.loads(body)["features"]), 1)
if __name__ == "__main__":
unittest.main()