2

I am trying to select (point) features within an envelope (buffer) of the start point of a line feature.

I have

line_layer = QgsProject.instance().mapLayersByName('DSC_Roads')[0]
chainage_layer= QgsProject.instance().mapLayersByName('DSC_Roads_10m_Chainage')[0]
for feature in line_layer.getFeatures(): # for each road select line and point features
    road = feature['RoadMntnc']
    if road == "Bamboo_Creek_Rd": #temporary for testing
        request = QgsFeatureRequest(QgsExpression('"RoadMntnc"= \'{0}\''.format(road)))
        l_sel = line_layer.getFeatures(request)
        c_sel = chainage_layer.getFeatures(request) #make sure points are on the same road
        for l in l_sel:
          geom = l.geometry().asPolyline()
          g = QgsGeometry.fromPointXY(geom[0])
          buffer = g.buffer(5,4) #10m buffer with 4 segments
          print (buffer) #test to see if the buffer works
          processing.run("qgis:selectbylocation",buffer,c_sel,['within'],0,0)
          chainage_selection=layer.selectedFeatures()
          print (chainage_selection) #test to see if selection worked

With this I am getting an error as there's probably something wrong with the selectbylocation that's based on https://gis.stackexchange.com/a/259441/2891

Traceback (most recent call last):
  File "C:\OSGEO4~1\apps\Python37\lib\code.py", line 90, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
  File "<string>", line 12, in <module>
  File "C:/OSGEO4~1/apps/qgis-dev/./python/plugins\processing\tools\general.py", line 106, in run
    return Processing.runAlgorithm(algOrName, parameters, onFinish, feedback, context)
  File "C:/OSGEO4~1/apps/qgis-dev/./python/plugins\processing\core\Processing.py", line 130, in runAlgorithm
    if context.feedback() is None:
AttributeError: 'int' object has no attribute 'feedback'

--- NEW CODE based on Joseph's answer

I tried the following but still get the same error

for l in l_sel:
    geom = l.geometry().asPolyline()
    g = QgsGeometry.fromPointXY(geom[0])
    buffer = g.buffer(5,4) #10m buffer with 4 segments
    buff_layer = QgsVectorLayer('Polygon', 'buffer' , 'memory')
    prov = buff_layer.dataProvider()
    feat = QgsFeature()
    feat.setGeometry(buffer)
    prov.addFeatures([feat])
    buff_layer.updateExtents()
    QgsProject.instance().addMapLayers([buff_layer])[0]
    processing.run("qgis:selectbylocation",buff_layer,c_sel,['within'],0,0)
    chainage_selection=layer.selectedFeatures()
    print (chainage_selection
0

2 Answers 2

4

I think the error is persisting because your c_sel argument is not a vector layer object either.

I would not worry about using the Select By Location processing algorithm and just work directly with the point feature geometries and their relationships to the buffers.

I created some test layers as a 'mock-up' and put together the script below which should do what you want. My point layer has a different name and chainage distance to yours, so my buffer is also larger. Just change the details to suit your data. I also assume you are wanting to do the buffer and selection for the start point of each line in your roads layer. If not, see the comments in my code- comment and uncomment the lines as indicated to use only the line features which match a feature name e.g. 'Bamboo_Creek_Rd' etc.

Here is the result I obtained on my test data after running the code:

enter image description here

line_layer = QgsProject().instance().mapLayersByName('DSC_Roads')[0]
chainage_layer = QgsProject().instance().mapLayersByName('Chainage_points')[0] #Change name to match your chainage layer
fids = []
feats = [f for f in line_layer.getFeatures()]
# comment above and uncomment below to run only on Bamboo Creek Road etc
#feats = [f for f in line_layer.getFeatures() if f['RoadMntnc'] == 'Bamboo_Creek_Rd']
for feat in feats:
    name = feat['RoadMntnc']
    c_sel = [p for p in chainage_layer.getFeatures() if p['RoadMntnc'] == name]
    geom = feat.geometry().asPolyline()
    start_point = QgsGeometry.fromPointXY(geom[0])
    buffer = start_point.buffer(5000, 4) #5000m buffer with 4 segments
    points_within_buffer = []
    for f in c_sel:
        if f.geometry().within(buffer):
            points_within_buffer.append(f.id())
    for x in points_within_buffer:
        fids.append(x)
chainage_layer.selectByIds(fids)
2

The qgis:selectbylocation tool requires two input vector layers. The first input you used is buffer which is just a geometry feature.

Try storing your buffer features in a new memory layer and use this as the first input layer.

2
  • Thanks - I tried but still get the same error. Can I do this without using processing?
    – GeorgeC
    Commented Sep 27, 2019 at 21:39
  • Ideally I would simply like to use request.setFilterRect(areaOfInterest) based on qgis-docs.readthedocs.io/en/latest/docs/… . The areaOfInterest should just be the buffer.
    – GeorgeC
    Commented Sep 27, 2019 at 21:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.