3

I am new to QGIS plugin scripting (3.16 Hannover) (in Python 3.7).

I have lots of different layers in my layers panel and I want to be able to click on a button on my GUI, which then activates a function, so I can click on any vector on my map canvas, and then receive the M-value of the chosen feature in the vector layer. I want to store this M-value in a variable, so I can use it later.

First off I tried reading the documentation on https://qgis.org/pyqgis/3.2/gui/Map/QgsMapToolIdentify.html#qgis.gui.QgsMapToolIdentify.identifyVectorLayer But I'm also new to programming in Python, so it's a bit difficult for me to understand.

I got the following code :

def canvas_clicked(self):
    self.canvas = self.iface.mapCanvas() # make mapcanvas variable
    self.pointTool = QgsMapToolEmitPoint(self.canvas) # using QgsMapToolEmitPoint to emit point, so i can retrieve x, y of mouse click
    self.pointTool.canvasClicked.connect(self.store_m_value) # connect function to mouseclick on canvas (in this function I want the program to store m-value of clicked vector in a variable)
    self.canvas.setMapTool(self.pointTool) # Set the map tool, so i can click the canvas

Then I connect my button (I use Qt designer - where i named my button btn_canvas_clicked) to the canvas_clicked function.

def run(self)
    self.dialog.btn_canvas_clicked.connect(self.canvas_clicked)

I tried the following to store the m-value unsuccesfully

def store_m_value(self, point, event)
   self.identify_vector = QgsMapToolIdentify(self.canvas)
   self.result = self.identify_vector.identify(point.x(), point.y(), [], QgsMapToolIdentify.DefaultQgsSetting)
   m_value = self.result.geometry().constGet().mAt(0)

I tried using following answer as a guideline for retrieving M value from vector layer: enter link description here

1 Answer 1

2

There are two main issues with your code. First one is that QgsMapToolIdentify.identify() will return a list of identified features. So you will need index your result variable before accessing any geometries. For example:

self.result = self.identify_vector.identify(point.x(), point.y(), [], QgsMapToolIdentify.DefaultQgsSetting)
if self.result:
    m_value = self.result[0].geometry().constGet().mAt(0)

And second is that the mAt() function is only available on LineString geometries. So if you might have some point or polygon geometries that won't work either. With polygons I guess you would need to access the exterior LineString to get it's m values with something like geometry.exteriorRing().curveToLine().mAt(0) and for point geometries use the m() property.

In general you might not even need the additional step of using a QgsMapToolEmitPoint to retrieve the coordinates. Since you need to use QgsMapToolIdentify anyways you could use it's canvasReleaseEvent function which provides coordinates through the QgsMapMouseEvent parameter:

def store_m_value(event):
    result = identify_vector.identify(event.x(), event.y(), [], QgsMapToolIdentify.DefaultQgsSetting)
    if result:
        m_value = result[0].geometry().constGet().mAt(0) # only for LineString as explained above

identify_vector = QgsMapToolIdentify(iface.mapCanvas())
identify_vector.canvasReleaseEvent = store_m_value
iface.mapCanvas().setMapTool(identify_vector)

1
  • thank you very much! This helped me understand how to read the documentation and solved my problem! May 4, 2022 at 12:37

Your Answer

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

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