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.
Is there anything strange about code?
Answer
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.
No comments:
Post a Comment