6

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

1 Answer 1

7

To apply a search distance around your coordinates, construct a QgsGeometry object from a QgsPointXY object created from your coordinates. Then you can use the buffer() method to create the search zone.

To do the actual geometric test, you can use a QgsSpatialIndex and QgsGeometryEngine which should be fast on your large data set.

layer = QgsProject.instance().mapLayersByName('equipment')[0]
pnt = QgsGeometry.fromPointXY(QgsPointXY(151.111650,-33.793260))
buffer_dist = 3# meters

index = QgsSpatialIndex(layer.getFeatures())

def transform_buffer_distance(dist):
    da = QgsDistanceArea()
    da.setEllipsoid('WGS84')
    dist = da.convertLengthMeasurement(dist, QgsUnitTypes.DistanceDegrees)
    return dist

search_radius = pnt.buffer(transform_buffer_distance(buffer_dist), 25)
engine = QgsGeometry.createGeometryEngine(search_radius.constGet())
engine.prepareGeometry()

matches = [f.id() for f in layer.getFeatures(index.intersects(search_radius.boundingBox())) if engine.contains(f.geometry().constGet())]
layer.selectByIds(matches)
print(matches)
2
  • 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. Oct 25, 2018 at 23:14
  • @Ehsan Aliverdi, several years after originally answering this question, I have updated my answer, to show how to search within a buffer and also how to use a spatial index and geometry engine to speed up the analysis on large datasets.
    – Ben W
    Dec 10, 2022 at 8:51

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.