3

I saw Finding the nearest line to a point in QGIS?

I wanted to create a program to get the line closest to the selected point.

Here is the code.

        dPos = mouseEvent.pos()
        qpoint = self.get_canvas_point(dPos)         
        layer = self.iface.activeLayer()
        features = layer.getFeatures()

        SpInd = QgsSpatialIndex(features)
        nearestSpIndids = SpInd.nearestNeighbor(qpoint,2)

        for nearestid in nearestSpIndids:
            gettingfeatures = layer.getFeatures(QgsFeatureRequest(nearestid))

            for feat in gettingfeatures:
                #feature_check
                prop1 = feat['PEN_Color']
                prop2 = feat['ID']
                root = QTreeWidgetItem()
                root.setText(0,str(prop1) +':' + str(prop2))

                self.dlg.treeWidget.addTopLevelItem(root)

However, even if I select any places, "Specific" lines will be selected.

For example : Regardless of where on the map you choose, you can only get information on the red line.

enter image description here

Is there anything strange about code?

  • @Havard My QGIS/Python gets an error on line3 because my nnfeature is a line, and qpoint.distance() has to have a qpoint as an argument. It doesn't know how to find the distance between a point and a line, do you know how to make the code you've listed above work if nnfeature has a line geometry? – James Greener Oct 15 '18 at 14:51
  • If you have a new question, please ask it by clicking the Ask Question button. Include a link to this question if it helps provide context. - From Review – csk Oct 15 '18 at 15:59
2

QgsSpatialIndex.nearestNeighbor finds the nearest neighbours using bounding rectangles and not the real geometry. You can use the index to get candidate features, but you have to use the real feature geometries at some point to find the true nearest neighbour.

I have used QgsSpatialIndex.nearestNeighbor to get a feature that I can use to fetch all features that may be closer than that feature using QgsSpatialIndex.intersects:

 nearestid = SpInd.nearestNeighbor(qpoint, 1)[0]
 nnfeature = next(layer.getFeatures(QgsFeatureRequest(nearestid)))
 mindist = qpoint.distance(nnfeature.geometry())
 px = qpoint.x()
 py = qpoint.y()
 # Get all features that have a bounding rectangle that intersects
 # a square centered at qpoint with a size decided based on the
 # distance to the geometry of the candidate returned by nearestNeighbor
 closefids = SpInd.intersects(QgsRectangle(px - mindist,
                                           py - mindist,
                                           px + mindist,
                                           py + mindist))

Then loop through these features selecting the feature that has the shortest distance to qpoint using qpoint.distance.

  • thanks for your answer. This time we responded using "actionSelect (). Trigger ()". Do you agree with the recognition that the "nearestNeighbor" method can not be used to get the nearest neighbor feature using actual geometry? – yshi Oct 4 '17 at 2:38
  • "nearestNeighbor" alone is not useful, but it is useful in combination with "intersects". I have updated my answer to show how this can be done. – Håvard Tveite Oct 4 '17 at 22:29

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.