5

I have a Linestring layer for which I have build a QgsSpatialIndex with the following code:

my_linestrings_lyr_idx = QgsSpatialindex()
for f in my_linetraings_lyr.getFeatures():
    my_linestrings_lyr_idx.insertFeature(f)

Now I want to find the nearest neighbor for a QgsPoint that is definitly located on one of the linestrings layers features, code:

#assume pt is of type QgsPoint
fid = my_linestrings_lyr_index.nearestNeighbor(pt, 1)
r = QgsFeatureRequest(fid[0])
nearest_feat = my_linestrings_lyr.getFeatures(r).next()

I expect nearest_feat to be the feature on which pt lies in any case (because this is definitly the nearest neighbor to pt), but in some cases that I can't exactly specify, nearest_feat does contain other features, which does not contain pt.

Do I use the nearestNeighbor() method incorrectly in some way?

2

Meanwhile, I've found an answer in this post: Why does QgsSpatialIndex.nearestNeighbor(point, 1) sometimes return 2 lines?

QgsSpatialIndex() seems not to work on the geometries themselves, but on the bounding boxes, and though nearestNeighbor() neither calculates the distances to the distinct feature geometries nor returns them ordered by the distance.

Keeping this in mind, it does not play a role whether pt in my question above lies strictly on a certain linestring or not.

If one wants the closest line feature to a point pt, we have to calculate and minimize the distance on the line features geometries to pt, sth. like

# assume pt is a QgsPoint()
# assume line_layer is a QgsVectorLayer() to test
pt_geom = QgsGeometry().fromPoint(pt)
dist, feat = min([(f.geometry().distance(pt_geom), f) for f in line_layer.getFeatures()], key = lambda x:x[0])

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.