1

I'm trying to build a plugin that would select let's say 8 closest points from a mouse click. I've found a working plugin that selects the closest feature from a mouse click here: https://www.lutraconsulting.co.uk/blog/2014/10/17/getting-started-writing-qgis-python-plugins/

So far I've managed to make it select only point features and I know how to make it select 2nd or 3rd closest point, but I have trouble making it select more features. The following doesn't return any selection:

class NearestFeatureMapTool(QgsMapTool):

    def __init__(self, canvas):

        super(QgsMapTool, self).__init__(canvas)
        self.canvas = canvas
        self.cursor = QCursor(Qt.CrossCursor)

    def activate(self):
        self.canvas.setCursor(self.cursor)

    def canvasReleaseEvent(self, mouseEvent):
        """ 
        Each time the mouse is clicked on the map canvas, perform 
        the following tasks:
            Loop through all visible vector layers and for each:
                Ensure no features are selected
                Determine the distance of the closes feature in the layer to the mouse click
                Keep track of the layer id and id of the closest feature
                Select the id of the closes feature """

        layerData = []

        for layer in self.canvas.layers():

            if layer.geometryType() != QGis.Point:

                # Ignore this layer as it's not a vector
                continue

            if layer.featureCount() == 0:
                # There are no features - skip
                continue

            #layer.removeSelection()

            # Determine the location of the click in real-world coords
            layerPoint = self.toLayerCoordinates( layer, mouseEvent.pos() )

            shortestDistance = float("inf")
            closestFeatureId = -1

            # Loop through all features in the layer
            for f in layer.getFeatures():
                dist = f.geometry().distance( QgsGeometry.fromPoint( layerPoint) )

                shortestDistance = dist
                closestFeatureId = f.id()

                info = (layer, closestFeatureId, shortestDistance)
                layerData.append(info)

        if not len(layerData) > 0:
                # Looks like no vector layers were found - do nothing
            return

            # Sort the layer information by shortest distance
        layerData.sort( key=lambda element: element[2] )


        selected_fid = []
        for closestFeatureId in layerData:
            if len(selected_fid) != 8:
                selected_fid.append(closestFeatureId)
            else:
                break
        layer.select(selected_fid)
  • While I haven't got the programming skills to aid you, I have ideas: Couldn't you use the distance matrix-tool somehow in order to return the eight closest points to your newly generated point? – Erik Dec 28 '18 at 9:20
1

Your layerData list contains tuples not the QgsFeatureIds required to select features, simple fix will be:

    selected_fid = []
    for (layer, closestFeatureId, shortestDistance) in layerData:
        if len(selected_fid) < 8:
            selected_fid.append((layer, closestFeatureId, shortestDistance))
            layer.select(closestFeatureId)
        else:
            break

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.