This is a quite a complicated problem for me. I'm working with bird records, trying to figure out the eventual density of river bird species along rivers. I've managed to create a layer of records of bird species in interest within a 100 m buffer along the rivers in interest.

As there are better and worse parts of the rivers for birds, the records are not distributed evenly along rivers obviously. What I want to achieve is to create, let's say, a 500 m radius around the record points and to project those buffers on rivers considering that this way I'll get sort of "territories" of the observed birds along rivers.

The final step would be to sum the length of the buffer projections on rivers eventually getting the length of "territories" against the whole length of rivers.

I think I should first project the record points on rivers but I've found several threads saying that it's near to impossible in QGIS.

Is that so?

I could perhaps go without projecting.

As the species in interest are close to 50 there should be SQL query involved I believe, because I need the values separated for each species. I am lost in options, where in the sequence the SQL comes in.

What would be my best workflow?

  • Who sayed where that using QGIS it is not possible? If I understand you correct, this solution here is very similar to what you're looking for: gis.stackexchange.com/a/384194/88814 If not, please state what is different in your case, provide a screenshot that shows what you want to achieve and best provide sample data for testing.
    – Babel
    Jan 2, 2022 at 11:46
  • If its just projecting points to the nearest line, this can help: gis.stackexchange.com/a/419972/88814
    – Babel
    Jan 2, 2022 at 11:48
  • 1
    "Best" questions are somewhat problematic here GIS SE, where we use a Focused question/Best answer model that closes opinion-based questions. Generally questions should attempt to solve the problem, not make unsupported claims that the task is impossible. Please Edit the Question to focus on the issue you want answered.
    – Vince
    Jan 2, 2022 at 12:52

1 Answer 1


The basic idea is the create a dissolved buffer around every bird species and create the intersection of this buffer with the river.

There is a direct way to do that by creating a virtual layer with this query:

select st_intersection (st_union (st_buffer(b.geometry, 100)),l.geometry) as geom
from line as l, birds as b
where b.species =4
  • replace line and birds in line 2 with the names of your layers
  • on line 3, replace species with the name of your attribute field and 4 with the name of the species you want to create the result for.
  • The size of the buffer (here: 100) can be adapted in line 1

Solution for species=1 (red crosses; all other species in black); the dotted line is just added for visualization purpose to show how the buffer around the red points looks like: the part of the line highlighted in orange is the output of the virtual layer: enter image description here

For a different, more manual approach, use this workflow:

  1. Create a buffer around the birds - check the box Dissolve results.

  2. Create the intersection of the buffer with the river line. There are different options to do this:

    a) Run Menu Vector / Geoprocessing Tools / Intersection

    b) Create a new virtual layer with this query (replace line and buffer in line two with your layer names):

    select st_intersection(l.geometry, b.geometry) as geom
    from line as l, buffer as b

    enter image description here

    c) Use QGIS expressions with Geometry generator or Geometry by expression (see here for details) and this expression (replace buffer with the name of your buffer layer):

     intersection (
             overlay_intersects (

    Red section of the river created with the expression from above using Geometry generator: enter image description here

  • +1 for your options 2a and 2b. I need to become more familiar with virtual layers, geometry generators, and geometry by expression. I probably would have clipped the river layer with the buffers, but that's old-school!
    – Stu Smith
    Jan 2, 2022 at 15:57
  • Aweseome, this is just what I need! Hoped to avoid code, just to stick with GUI options but looks like it`s not the case. Additional question - if all the bird species are in one .shp, how do I automate the solution above for each species seperately? Can I somehow output each dissolved buffer in different .shp?
    – edge
    Jan 2, 2022 at 16:43
  • You can use it without code, replacing step 2 with intersection tool, see updated answer
    – Babel
    Jan 2, 2022 at 17:16
  • To run it separately for all species, of course this can be done using code. If you want to do it without, use Menu Processing / Toolbox / Split vector layer to generate a separate layer for each species. Then run the tools Buffer and Dissolve in batch mode with these layers as inputs. Even better would be creating a model for Buffer / Dissolve that you then could run in batch mode.
    – Babel
    Jan 2, 2022 at 17:27

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