2

I have thousands of points generated along river channels. I am trying to connect these points based on distance. Furthermore, I tried "Join attributes by nearest Points" and "Geometry by expression" in QGIS.

The method was mentioned here by @Babel. It works somehow. However, there are many gaps between the line segments and some lines are drawn repeatedly.

enter image description here

How can I use QGIS to fill the gaps and remove the repeated line segments?

Taras
  • 32,823
  • 4
  • 66
  • 137
Bo Wang
  • 69
  • 7
  • As far as I can see, this solution should work: https://gis.stackexchange.com/a/382246/88814 – Babel Dec 30 '20 at 00:09
  • Please decide whether it’s ArcMap, QGIS or Python that you wish to ask about in this particular question. If it’s Python then please include a code snippet that illustrates what you have tried and where you are stuck. – PolyGeo Dec 30 '20 at 00:13
  • As long as the question is closed, I can't add an answer, so please update your question (stating you're interested in a solution in QGIS) so that it can be reopened. Just to give a few ideas: 1. from the red lines, create start- and end points and use these to cretate a connecting line where you have gaps. 2. Repeated line segments: define a min/max value for the angle of your line to avoid this. 3. Can you use river date (e.g. OpenStreetMap)? You could snap your points to this line and try this: https://gis.stackexchange.com/a/382253/88814 (should work better with rivers than with streets). – Babel Dec 30 '20 at 11:08
  • 1
    I think part of the question (and resulting answer) is going to be "what do you want the output to look like"? --- Those straight line segments are probably not the exact course traveled. A moving average applied to each segment, followed by a curve fitting is probably more representative of the route taken; but you should be clear in your question if you want to preserve the error or beautify the output (at risk of introducing error). – Rob Dec 30 '20 at 17:23
  • Hi, Rob, the figure you made is exactly what I want. I tried "Grid(moving average)" but it returns empty results (a black tiff). Could you please give more details about how did you do it? – Bo Wang Dec 30 '20 at 21:18
  • Hi Babel, thank you for your help. I tried to retrieve start and endpoints using the code you wrote before. https://gis.stackexchange.com/questions/306190/generating-start-and-end-points-for-linestrings. However, the line returns exactly the same points as the previous input. I think this is because the file is a multiline file in which we made the line by connecting every nearest point. These points were calculated using the Google Earth Engine and there is no available channel line (that is the one I want to build). Therefore, I cannot do snaps. – Bo Wang Dec 30 '20 at 21:22
  • 2
  • Hi Taras, thank you for your comments. I tried your python code, it works somehow if I subset my dataset to only contain a small part of the points. But the connected lines are still incorrect. For example, some points shouldn't be connected because they are too far. I guess I can add some codes to restrict the mapping distance between these points. Another issue is that if I run the code on my more than 30000 points, it will return the error "maximum recursion depth exceeded". I increased the system recursion limit to 10000 and run again, the QGIS died after running a while. – Bo Wang Jan 01 '21 at 00:18
  • Okay, thank you for you feedback! I will try to improve the code I wrote, will let you know – Taras Jan 04 '21 at 15:42
  • Hi Taras, thank you very much for your help! -Bo – Bo Wang Jan 04 '21 at 16:22

3 Answers3

4

Let's suppose your points do not have an order attribute like an id or timestamp that would make it ease to connect the points accordingly (from 1 to 2 to 3 to 4 etc.). So I suppose your points are just randomly distributed all along the river with varying distances between them. I created such a points layer (see my first screenshot with the id as label) to demonstrate how to generate a connecting line based on location alone. There are five steps involved, including the Plugin Join multiple lines. Install it before you start from Menu Plugins / Manage and Install Plugins…. This plugin should do what you want to do, connecting the separate lines on your screenshot. Steps 1 to 3 generate such lines from a points layer.

  1. Menu Processing / Toolbox / Join attributes by nearest - set Maximum nearest neighbors to 1 only! Optionally, you can set a Maximum distance
  2. Menu Processing / Toolbox / Geometry by expression: select the output from above as input layer, for Output geometry type select line and as Geometry expression insert this expression: make_line ( make_point ( "feature_x" , "feature_y" ) , make_point ( "nearest_x" , "nearest_y" ) )
  3. Menu Processing / Toolbox / Delete duplicate geometries and set the output from 2 as input layer
  4. On the output layer from 3, select all features (I use Ctrl - A on my Windows machine, or click on the Select all icon in the Toolbar )
  5. Open/run the Plugin Join multiple lines (from Menu Vector): you get the connecting line you wanted, see screenshot:

enter image description here

enter image description here

Babel
  • 71,072
  • 14
  • 78
  • 208
  • Thank you for your time! Please see my result after following your steps. The river have multi-channels and this may cause a mess of the connection. I have more than 30000 lines in the vector, if I select all and do the "Join multiple lines", QGIS becomes no response after running a while. https://photos.google.com/share/AF1QipMcW1j0sBTgR079oJTRGb7hjEdvmCPSq4blNbfi7Fmea4UQGcBqyuYg9dSZfCOPSQ/photo/AF1QipPJOviJHJvWxgjOp-yknbIDPo4dWO3fmN8Q5ibJ?key=OTFEOVVrbVlQWENRQkhtZXJPdFJrZ1RuMnZlTTRn – Bo Wang Dec 31 '20 at 16:29
3

Find a river centerline dataset or digitize your own.

Then use the processing steps:

enter image description here

Result: enter image description here

BERA
  • 72,339
  • 13
  • 72
  • 161
  • Thank you. The points are obtained from the google earth engine and I am trying to build river channel lines for global rivers. Therefore, I cannot digitize them manually. The existed global channel lines are simplified also. – Bo Wang Jan 01 '21 at 00:22
  • Then download them, for example: http://overpass-turbo.eu/s/5ts, then pan to your area and press Run – BERA Jan 01 '21 at 10:14
  • Thank you for the method. I tried it in the Model designer but the generated lines are in a mess. This is because the river has multiple channels separated by vegetated islands or channel bars in it. The centerlines downloaded from your supplied website are generalized into a single-channel which means there are no nearby extracted vertices for many points. – Bo Wang Jan 05 '21 at 23:35
1

You can try "Nearest Points to Path" from ProcessX Plug-In. Default settings should do the job.

enter image description here

Disclaimer: I am the author of this Plug-In.

MrXsquared
  • 34,292
  • 21
  • 67
  • 117