0

I have a cadastral map as WMS in QGIS. Using the QGIS tool "Identify Features" I can click at the map and view a HTML table showing the cadastral number: enter image description here

Is there any way I can pick that number using a point layer?

4
  • 2
    A WMS service returns a picture of the data you can not reliably extract meaningful information from it - if you require actual data you must use a WFS or WCS endpoint to fetch actual data.
    – Ian Turton
    Feb 14, 2023 at 16:01
  • I am completely aware that map shown is a picture, but as the "Identify features" tool can return a text string it should be possible also to get that string in other ways
    – Morten
    Feb 14, 2023 at 21:13
  • 1
    The Identify Features tool generates in this case a WMS GetFeatureInfo request. The request is sent to the WMS server with clicked coordinates, and the server sends the text string back. That the server supports GetFeatureInfo does not guarantee that it supports any other way for querying. If the server happens to be GeoServer it is possible that it supports also WFS and then you can add the parcel layer as a vector layer into your QGIS project. That would provide you complete access to all the attributes.
    – user30184
    Feb 14, 2023 at 21:24
  • You can get the string through the GetFeatureInfo request (request at a pixel location) in what ever info formats are supported by the server. Commonly these would be GML, plain text and HTML. Sometimes you can get other formats such as GeoJSON
    – nmtoken
    Jun 29, 2023 at 17:49

1 Answer 1

2

A practical solution is, to create your own function in the Function Editor within the Field Calculator window. There you can use most of the functionality of the Identify-Tool (class QgsMapToolIdentify) from QGIS.

For me the following implementation did the job.

Note that you might add in some checks/exception handlings to deal with wrong inputs and such

from qgis.core import *
from qgis.gui import *
from qgis.utils import iface
import time

@qgsfunction(args='auto', group='Custom')
def wmsRequestPoint(wmsLayerName, feature, parent):
    wmsLayer = QgsProject.instance().mapLayersByName(wmsLayerName)
    pointCRS = feature.geometry().asPoint()
    canvas = qgis.utils.iface.mapCanvas()
    # edited:
    canvas.setCenter(pointCRS)
    time.sleep(0.25)

    tool = QgsMapToolIdentify(canvas)
    pointCanvas = tool.toCanvasCoordinates(pointCRS)
    identifyResults= tool.identify(pointCanvas.x(), pointCanvas.y(),wmsLayer, QgsMapToolIdentify.TopDownStopAtFirst)
 ...


Now you need to extract the piece you want from the server reply.

  • identifyResults is a list of results, assuming we get exactly one, we take the first element
  • the IdentifyResult class (inner class in QgsMapToolIdentify) has accessible member variables containing the content. These are organized as dictionaries.
  • in my case (German cadastre) the HTML-text was in the member mAttributes with the dictionary key '' (empty String)

So this line worked in my case:
htmlContent = identifyResults[0].mAttributes['']

Finally you might want to parse the html-text rather in that function with Python, than in the Field Calculator environment and return the result.

EDIT: I initially tested that on few points and it worked. But it failed on bigger scale data. So we need to dive a bit deeper:

The WMS GetFeatureInfo request requires a region description and a point (see reference). Using tool.toCanvasCoordinates(pointCRS) and tool.identify(...) does that conversion for us... but not really. It depends on the actual mapCanvas of QGIS.

The points requested must be on the map. But if you zoom out to have all points in the picture, the calculated area of the Pixels gets larger. This leads to the requests having multiple results if our requested box covers multiple source areas.
I also added a delay, since we spam UI commands and Server requests that may take some time...

tldr;

Setup your map to have a low map scale. Add a line of code to move the canvas to the point. (see above)

3
  • I'm not sure I understand your comment that WMS GetFeatureInfo request requires a region description, not a point ; that's not correct a WMS GetFeatureInfo request requires a point (i,j) or (x,y) depending on WMS version which is a pixel location in an image created (in effect by a GetMap request), except WMS servers don't maintain session state, which means that you have to send all the parameters to 'create' the map image plus the pixel coordinates in your GetFeatureInfo request.
    – nmtoken
    Aug 9, 2023 at 11:25
  • You're right. Thanks for clarification. The request itself needs a point and bbox. Yet I'm still unsure, why the request result varies with MapCanvas scale.
    – FrogJ
    Aug 9, 2023 at 12:15
  • Different scale maps may show/expose different data.
    – nmtoken
    Aug 9, 2023 at 15:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.