Bug report #8044

Strange behavior of feature request with filter rectangle for memory layers

Added by Denis Rouzaud over 6 years ago. Updated over 6 years ago.

Status:Closed
Priority:High
Assignee:-
Category:Vectors
Affected QGIS version:master Regression?:No
Operating System: Easy fix?:No
Pull Request or Patch supplied:No Resolution:
Crashes QGIS or corrupts data:No Copied to github as #:16886

Description

I am experiencing some problems with a feature request using a rectangle
filter on a memory layer containing circles.

If I set the rectangle filter within a circle feature (i.e. the
rectangle is strictly enclosed in the circle), the select does returns
this feature, even though it should not (since it is a circle and not a disk).

Even stranger, this occurs for arcs, as soon as the angle is strictly greater than 90.

I have written a few lines to reproduce this with a memory layer. It
creates a circle as a line in the memory layer and does the feature request. It prints the selected features id field.

from math import cos, sin, pi

# params
circle_x = 0
circle_y = 0
circle_r = 2
tolerance = .1  # tolerance for Filter Rectangle around center of circle in the feature request
arc_angle = 360  # 360=full circle, arc if lesser. Returns the feature if > 90

# create memory layer
epsg = iface.mapCanvas().mapRenderer().destinationCrs().authid()
layer = QgsVectorLayer("LineString?crs=%s&field=id:string&index=yes" % epsg, "Circle", "memory")
QgsMapLayerRegistry.instance().addMapLayer(layer)

# uncomment to test on another layer
#layer = QgsMapLayerRegistry.instance().mapLayer("pipe20130612142848065")

# add a circle as a line in the layer
f = QgsFeature()
fields = layer.dataProvider().fields()
f.setFields(fields)
f["id"] = "test" 

f.setGeometry(QgsGeometry().fromPolyline([QgsPoint(circle_x + circle_r * cos(pi/180*a),
                                                   circle_y + circle_r * sin(pi/180*a))
              for a in range(0, arc_angle, 3)]))
layer.dataProvider().addFeatures([f])
layer.updateExtents()
layer.setCacheImage(None)
layer.triggerRepaint()

# select and print id of selected features
features = []
featReq = QgsFeatureRequest()
box = QgsRectangle(circle_x-tolerance, circle_y-tolerance, circle_x+tolerance, circle_y+tolerance)
featReq.setFilterRect(box)
f = QgsFeature()
vliter = layer.getFeatures(featReq)
while vliter.nextFeature(f):
    print f["id"]
    pass

History

#1 Updated by Denis Rouzaud over 6 years ago

  • Status changed from Open to Closed

I did miss the flag exactIntersection in QgsFeatureRequest.

With the flag, it works as expected.

Also available in: Atom PDF