6

In QGIS 3.18.0 I have imported a series of points (representing points along the perimeter of both sides of a stream). The stream is segmented into 10 meter sections. The goal is to map out the stream - but broken down into individual sections.

My attribute table for the point layer (image example below). And, sample data here: tab delimited file

Section Sequence Type X Y
  • SECTION: numeric identifier for the given section
  • SEQUENCE: ordered value indicating which points to connect in given order, per section (via PointToPath)
  • TYPE: designates side of stream bank, left or right (ignore this)
  • X / Y - ordinate values for the points.

If I were to create a layer for only one section of the stream, I'm golden by:

  1. Add a delimited layer (my data file) - points are assigned a SEQUENCE number
  2. Run Points-to-Path (create closed path, order expression = SEQUENCE)
  3. Run Lines-to-Polygons to form a polygon of the given section.

The problem is, I have 7 streams, 1400 sections each. I'm hoping to automate the process in some way.

Currently, I have imported all of my points to one point shapefile (image below). SECTION and SEQUENCE could be used to organize the sections. But I can't figure out how to perform the above single-section process on each section.

I think I need to break each section into a shapefile of its own - then batch the process? Is there an easier way?

Hoping this makes sense?

THIS ugly picture is what I'm going for. The ugliness is just to point out the different polygons.

Shooting for this idea

attribute table

5
  • 2
    Welcome to GIS SE. Interesting question! Sharing your data or at least a sample of it would it make easier to help - otherwise one would have to invest time in creating similar data first.
    – Babel
    Commented Mar 14, 2021 at 19:55
  • I'm not quite sure what your problem is: if you perform it for every of the 7 rivers separately, it sould work, shouldn't it? Based on a few points (labeled with section : sequence) as in your example, I was able to create your desired result, see: i.sstatic.net/sPlfD.png - so the problem is only that you have the same combination of section : sequence several times (for each river) and you're not able automatically keep the different rivers apart? Did I understand that right?
    – Babel
    Commented Mar 14, 2021 at 20:44
  • Thanks. Yea, I'm new so will try to figure out how to share the data.
    – Mike Bosko
    Commented Mar 14, 2021 at 21:19
  • Hmm, no, what you did seems to be precisely what I'm looking for. If I can make what you did happen, I can just tackle each stream separately. I guess I'm not seeing how you were able to accomplish this - I must be seriously over thinking it. Sorry - I'm also pretty new to QGIS.
    – Mike Bosko
    Commented Mar 14, 2021 at 21:21
  • I don't know how, but I think, somehow, it can be done using Geometry by Expression tool in QGIS. Commented Mar 14, 2021 at 21:26

2 Answers 2

6

I think you're almost there. You just have to add the section field as group field in the points to path dialog window. See my screenshot, where I have points in a similar order as yours, labeled with section : sequence (so the point at the bottom right corner is section 6, sequence 5):

enter image description here

You could than treat all your 7 rivers separately. If you want to treat them all together, add a new field river_id. A quick and dirty option is to manually select the points belonging to the same river and create entries for the selected features only with the field calculator - or run points to path for selected features only, even simpler than creating a new field.

A more sophisticated option is to automatically group points together based on the distance to the nearest neighbor(s). I guess that the rivers are far enough and the points of your sections close enough that the nearest neighbor of each point belongs to the same river - right? Maybe with the exception of cases where one of the rivers flows in another one (if this is the case). A detailed description how to do this is found in my second answer.

3
  • 1
    Ah man!! That's two simple things I've missed on the Point to Paths processor; ergg. Thank you so much! It seems my data is messed up a little, as it didn't paint the pretty picture of a stream as it should have. I believe that might have to do with my waypoints (collecting my benchmark point via handheld GPS, in a canyon). bummer. This was it, THANK YOU!
    – Mike Bosko
    Commented Mar 14, 2021 at 21:41
  • AND yes, I have two of these streams that are confluence to the other. But that part will be easy - and yes again, I'll create a "river" field. I suspect that if there's only one 'group by' option in the points to paths processor, I could just create a calculated field combining RiverID + SegmentID. Again, thanks!
    – Mike Bosko
    Commented Mar 14, 2021 at 21:45
  • 1
    Great to see that a quite simple solution works - sometimes it's great to let someone else look at a problem. That's what GIS SE is for :-)
    – Babel
    Commented Mar 14, 2021 at 21:47
1

There is a way to automatically assign a river_id field to your points so that you don't have to do that manually. As it adresses a completely different aspect as in my first answer, I post it as a second answer. The only thing you have to do manually is creating a line that defines where two rivers meet (step 4).

  1. On your points layer, add a symbol layer / Geometry generator / line and paste this expression (replace 'vertices' in line 8 with the name of your points layer). The overlay_nearest function is available since QGIS 3.16 (see refFunctions plugin for older versions):
collect_geometries (
    array_foreach( 
        generate_series( 0,1),    
        make_line (
            $geometry, 
            array_get ( 
                overlay_nearest( 
                    'vertices', 
                    $geometry, 
                    limit:=20
                ), 
                to_int(@element)
            )
        )
    )
)

This generates a line connecting each point with its nearest neighboring point. The trick is now to succesively increase the value 1 in line 3 (in the expression generate_series( 0,1)): this will additionally create a line to the nearest 2 neighbors, than next 3 etc. Increase the value as long until all points are connected together. In my case, I had to increase to value to 4 (see screenshots - the solution continues afterwards):

Value with 1: many gaps in the connecting red line: enter image description here

*Value with 2: most point connected, but still a gap left at the left, where there is the pink colored polygon - here, points are not yet connected: * enter image description here

Value with 3: still not connected in the same place as before (see arrow), but some further connections added in other places enter image description here

Value with 4: finally, all points are connected :-) enter image description here

Value increased to 19: too many connections, a real mess :-( enter image description here

  1. When you found the ideal setting (in my case: 4), copy the expression, run Menu Processing / Toolbox /Geometry by epxression and paste the expression there. This creates the same lines as before - but this time as actual geometries (new layer) - before, we had it only for visualization purpose:

enter image description here

  1. Now apply a buffer to the line generated in step 2: Menu Vector / Geoprocessing Tools / Buffer - the buffer size should not be too large, it's OK to set it to a distance considerably smaller than the distance between your points. Be sure to check the box Dissolve result

What appears here as a thick blue line is in fact a polygon, the buffer created in step 3: enter image description here

  1. Select the buffer, toggle editing and select the icon Split features, than make a line that crosses the buffer where the two rivers meet. Activate snapping to snap the line to the vertices where the rivers meet. When your line has the right shape, right click to finish it and the buffer will be split.

The small red line that splits the buffer, highlighted in yellow: enter image description here

Result: your buffer now consists of two features - highlighted (selected) the one on the right:

enter image description here

  1. Now go back to your vertices layer and create a new field with filed calculator. Paste this expression (the overlay_within function is available since QGIS 3.16, see above). The expression looks for each point within which one of the buffer-features it is located and creates the belonging id as a new attribute in the point layer:
array_first (
    overlay_within(
    'buffer',
    $id
    )
)

The expression to create the river_id field: enter image description here

  1. Now you can use select by expression to select all the points that belong to the same river, than run points to path (as described in the other solution) for the selected features only. You could also use this field to run it in batch process or to create a model.

The points (vertices) are labeled with the field river_id created in step 5. Using select by expression, you can select all points belonging to the same river - here with the expression "river_id" = 1: enter image description here

And this is how my result looks like after applying points to path and than lines to polygons, using a categorized renderer for the colors (color ramp blues):

enter image description here

2
  • 1
    Whoa, this is freaking awesome!! I think I just found the land they call heaven. Thanks so much! Next up is going to be the placement of obstacles in the stream (rocks, logs, etc) - with actual dimensions associated with them. Length x width. I'm playing now but will post if I can't figure it out. A new question on an entirely new thread I suspect is proper protocol. (??)
    – Mike Bosko
    Commented Mar 15, 2021 at 18:34
  • Yes, every new question is a new post. Be as precise, detailed and focused as possible. If an answer did solve your problem, apart from upvoting, consider accepting it (hit the green checkmark next to it).
    – Babel
    Commented Mar 15, 2021 at 19:10

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.