5

I am using QGIS 3.2 and I am trying to get the features at a specific coordinate for a specific layer. when I use mouse position event the following code works fine but when I calculate the coordinate and use Identify tool. It doesn't work. I do some calculation in my program to get the coordinates, then that coordinate goes to following code to get the features but the following codes returns empty.

for lyr in [layer for layer in QgsProject.instance().mapLayers().values()]:
        if lyr.name() == 'equipment':
            LayerID = lyr
            print(lyr)
canvas=iface.mapCanvas()
f=QgsMapToolIdentify(canvas).identify(151.111650,-33.793260,[LayerID],QgsMapToolIdentify.TopDownAll)
print(f)

The following picture shows the coordinate of the the equipment but this code returns empty list

enter image description here

I have tried the following:

  • Increasing the search Radius in QGIS option (even 50.0mm returns empty)
  • give the input as QgsPoint

To make it clear I should explain that the coordinate not necessarily intersect with the feature coordinate(in most cases it Does). I managed to get around the issue by writing the following code. It does what I need but the issue is. It is too Slow with big data set. Does QGIS have a better way to handle this?

def tool_identifier(self,layer_name,point_x,point_y,buffer=3):
    """ The only reason I created this is because I couldnt do it with maptool Identifier
    this tool gets two coordinate x and y and checks a layer if there is a feature in the buffer it will be add to output list

    :param Layer_name: Qgis Layer name should be Already open.
    :type Layer_name: string

    :param point_x: x coordinate of the center of buffer.
    :type point_x: float (151.117596)

    :param point_x: x coordinate of the center of buffer.
    :type point_x: float (-33.794810)

    :param buffer: this is the buffer radious 
    :type buffer: it should be a number and default value is 3m

    """

    identified_feature_list=[]
    distance = QgsDistanceArea()
    for lyr in [layer for layer in QgsProject.instance().mapLayers().values()]:
        if lyr.name() == layer_name:layer_obj = lyr

    for f in layer_obj.getFeatures():
        distance = QgsDistanceArea()
        distance.setEllipsoid('WGS84')
        geom = f.geometry()
        current_point=geom.asPoint()
        m = distance.measureLine(QgsPointXY(current_point.x(),current_point.y()), QgsPointXY(point_x,point_y))
        if m<buffer:
            identified_feature_list.append(f)

    return identified_feature_list
3

If you want to specify a co-ordinate manually, you could just do something like this (copy & paste into QGIS 3 console):

layer = QgsProject.instance().mapLayersByName('equipment')[0]
MyPnt = QgsGeometry.fromPointXY(QgsPointXY(151.111650,-33.793260))
feats = layer.getFeatures()
for feat in feats:
 if MyPnt.intersects(feat.geometry()):
     feature = feat.id()
     layer.select(feature)
print(feature)

Alternatively, for a more interactive implementation, copy & paste the code below into the QGIS 3 console to test:

from PyQt5.QtGui import *

layer = iface.activeLayer()
layer.removeSelection()
point, okPressed = QInputDialog.getText(None, "Find Feature","Enter co-ordinates (separated by a comma with no space):", QLineEdit.Normal)
if okPressed and point != '':
    x, y = point.split(',')
    pntX = float(x)
    pntY = float(y)
    print(pntX)
    print (pntY)
    MyPnt = QgsGeometry.fromPointXY(QgsPointXY(pntX, pntY))
    feats = layer.getFeatures()
    for feat in feats:
        layer_geoms = feat.geometry()
        if MyPnt.intersects(layer_geoms):
            selection = feat
            selection_id = feat.id()
            layer.select(selection_id)
            iface.openFeatureForm(layer, selection, True)
            print(selection_id)
count = layer.selectedFeatureCount()
if count == 0:
    msg = QMessageBox()
    msg.setWindowTitle("Info")
    msg.setText("No Feature Found")
    msg.show()

Run the script in the console, enter a pair of co-ordinates in the input dialog (DD format, separated by a comma with no space) and hit enter or click ok. You can run the script again and again, entering different co-ordinates each time.

1
  • Your answer works well when the calculated point intersects but the problem is the coordinate I calculate not necessarily intersect with the feature. then I need to search inside a Buffer. Does PyQGIS has such a function As I don't want to reinvent a weel. – Ehsan Aliverdi Oct 25 '18 at 23:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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