[GIS] Joining segments of a line in QGIS

lineqgis

I have lots of different lines composed of hundreds of segments in a Shapefile.

I would like to join them spatially where every start (or end) point of a segment correspond exactly (or within a range of X mm, but this extra) to the start (or end) point of an other segment. And only there. In other word everywhere a segment touch an other at his beginning or ending, they should be joined. (Attributes are always the same except for one column with specifics IDs I don't care about.)

The dissolve tool doesn't work; it compose a unique feature containing absolutely all lines, even those which are far away.
All the segments are entire features, so the "multi to single part" vector tool doesn't work either.
I have also tried the "Join Lines" and "Join multiples lines" plugins; they both don't do the job. Except the "Join Lines"; it is doing it correctly, but I have to select manually two segments then click to join them. It's not possible to do so manually of hundreds of them.

It would be nice if this can be done on a selection as there is several types (rivers, roads, paths, etc) of lines in this Shapefile.

Best Answer

The problem can be solved in several simple steps - 5 in total as you can see below. The core of the solution conists in using the Join attributes by nearest tool.

Let's say you have a the following line segments with white dots representing start- and end points and the number the id of the line segments. Some segments are connected (end point of 1 = start point of 2), other not, there are gaps in between, like between segment 2 and 3. In the following screenshots, you have 19 line segments that can be grouped to 8 groups of connected lines as follows:

  1. 1,2
  2. 3,4,5
  3. 6
  4. 7
  5. 8,9,10,11,12
  6. 13
  7. 14,15,16,17,18
  8. 19

You see this here on the screenshots: there are totally 8 gaps: enter image description here

To join the segmentes that are connected to one single line, proceed as follows:

  1. Select Menu Processing / Toolbox / Join attributes by nearest, set both input layers to your line layer and Maximum nearest neighbors to 1. You could also define a Maximum distance (to get your extra). Run the tool.
  2. You get a new layer. If you have a look at the attribute table, you see that there are several new fields, between else also a field named distance. This tells you the distance between neighboring segments: if it is 0, the two segments are connected. Those lines that have a value > 0 are no. 6, 7, 13, 19: exactly those we identified above as not being part of a group of connected line segments. To get your extra condition, you could define a distance threshold: if the distance is smaller, you could consider the lines as "connected".

enter image description here

  1. Now click the select by expression symbol in the toolbar (see screenshot above) and paste the expression "distance" = 0 to select all segments that have a distance of 0 to their nearest neighbors - thus segments that are connected.
  2. Toggle edit mode and click the Merge Selected Features symbol in the toolbar: enter image description here
  3. You now get a line with all segments (expect 6,7,13 and 19) merged to one single line. We're close to where you want to go, but not yet there.
  4. You're probably not able to save the merged lines as we have a multipart line: a single line-feature that consists of several segments that are not connected. We have to apply Menu Vector / Geometry Tools / Multipart to singleparts. At the same time, this also solves our last problem: the one large line gets split into several lines that are connected: Now, we have exactly the merged lines that we defined at the beginning. You can see this in the next screenshot - red dots are start- and end points of the new line, the number of the line labels represent the totally 8 new features (lines). As you see, the do not follow the original order any more, but that should not be a problem.

enter image description here

Related Question