4

I often want to join sequences of GPS points to form sets of lines that represent periods of at-sea survey effort.

My GPS point file includes an integer "Order" field with unique values, and an integer "Leg" field. "Order" specifies the sequence for points to be joined; "Leg" specifies that points with the same value should be grouped into separate paths / lines. The CRS is WGS84.

I've used Points2One and Points To Paths plugins to do this successfully in the past. But in recent versions of QGIS 3, the processing toolbox's "Points to Path" joins all points in order as a single line only. The "Leg" field appears to be ignored.

I keep the option box for closed paths un-ticked. I've tried different tables, geographical and projected CRS, converted "Order" and "Leg" fields between integer and text, but always the same result.

Can anyone tell me whether I'm making a mistake, if this is a bug, or an unintended application of points to path? And if there is a simple workaround I can use. (Please, if a workaround involves applying code, include an explanation of how to add and run the code...). I'm currently using QGIS 3.22.1-Białowieża.

Here is a link to a cut down copy of my GPS points file - I would like it to form two separate lines (leg 20 and leg 21): https://we.tl/t-5UbL8YJ59R

1
  • Hi Taras - I have added a subset of data from my current points file, with two line groupings.
    – ChrisP
    Dec 7, 2021 at 14:38

3 Answers 3

2

Manual solution

See below for automatic solution

Use the Id from your points as Order expression. To separate the two groups (clusters) of points, create an expression for Path group expression. As the last point of the northern line has an Id = 82398 and the first of the southern line has Id = 32399, set the expression to Id <= 82398:

enter image description here

Separate lines created for the two groups of points: enter image description here


Automatic solution

For an automatic solution, calculate the distance from each point to the next point (point with the next id). If the distance is larger than a ceratin threshold, consider this as a new line.

Proceed as follows:

  1. Calculate the distance to the next line and create a new field named length_to_next with this value (consider reprojecting your points to a projected CRS for distance measurements):

    length (make_line ($geometry, geometry(get_feature_by_id (@layer, $id+1))))
    
  2. Create a new field group that generates a common value for all points belonging to the same line. To do so, aggregate all values from the field length_to_next that are larger then a certain threshold (here: 50 meters). These are the end-points of the lines (from this point, it is more then 50 meters to the next point, thus a new line starts). Get the Id of these last points, again in an array: you get the Ids of all end-points. Then check for each point if it's Id is larger then every of the end-points Id and return all end-points-Id that fulfill this condition. In the end, get the highest of the end-point-Ids. In this way, you assign to each point the Id of the start-point of the line it belongs to. To achieve this, create a new field with this expression. Change the threshold distance (here: 50) on line 7:

     array_max(
          array_foreach (
             array_foreach (
                 array_foreach (
                     array_agg( 
                         length_to_next, 
                         filter:=length_to_next > 50
                     ),
                     get_feature( 
                         @layer, 
                         'length_to_next',
                         @element
                     )
                 ),
                 attribute (
                     @element,
                     'Id'
                 )
             )
             ,
             case 
             when @element < Id then @element end
         )
     )
    
  3. Use the attribute group created in step 2 as Path group expression in the Points to Path tool.

Points classified based on the field group from step 2. Create the line based on this attribute: enter image description here

2
  • Hi Babel - Thanks for your suggestion. This does work for creating two lines. But I have many line groupings in my data and I don't want to specify an Id number to split them each time. I would like an automatic method of setting the grouping parameter, like using the Leg_num field.
    – ChrisP
    Dec 7, 2021 at 15:21
  • See updated answer - based on distance between points, you can identify where lines should be broken.
    – Babel
    Dec 7, 2021 at 16:15
1

IMHO it is just a visual delusion cased by a point with "id"= 82398 and not a problem either with an algorithm or data.

When I use the "Point to path" geoalgorithm for provided data and with the following settings

window

I get this output

result

However, when you zoom into location with that "special" point, one can see that lines are not connected.

issue


There is a workaround available:

Cluster your points by means of either "K-means clustering" or "DBSCAN clustering" (here a reprojection should be applied) and then run the "Point to path" using "CLUSTER_ID" as the 'Path group expression'.

3
  • 1
    Hi Taras - you are right. It is my formula for creating the Leg_num values that is at fault... The change from one Leg to the next happens at the last point of a 'leg', and not at the first point of the next 'leg'. Solved - thanks very much.
    – ChrisP
    Dec 7, 2021 at 15:28
  • 1
    I like your k-means clustering idea. In my case it may not work out correctly if a survey line covers the same area as a previous line from earlier in the survey. But I will bear it in mind for future processing - thanks.
    – ChrisP
    Dec 7, 2021 at 15:54
  • Always a pleasure to help !
    – Taras
    Dec 7, 2021 at 15:56
1

First of all, Chris, there appears to be an error in your data. You have two "legs", one to the north (leg = 20) and a second to the south (leg = 21). However, the last point in the northern leg (order = 243) has leg = 21. Since order = 243 was clearly part of the northern leg, I edited it to leg = 20.

For the solution (using QGIS 3.22.1) I used the Points to Paths plugin (note the plural Paths). Screenshot below. Make sure to check the Line per Vertex box.

Voila! The output respects both leg and order, which means that there will be a separate line between each point pair. Additionally, each of the lines will contain the beginning and ending point order values, which means that you now have the ability to join each line back to its parent points and copy additional point data values to the line. This can be very useful!

If you only need two "leg" lines instead of the separate "order" lines, simply leave the Line per Vertex box unchecked.

In your post you mix and match the tool names Points to Path with Points to Paths. They are two separate entities; the former is installed with QGIS, while the latter is a plugin that is added by the user. Using your (corrected) data, Points to Path will only output one line per leg. Points to Paths with the Line per Vertex box unchecked is identical to Points to Path. However, Points to Paths with the Line per Vertex box checked has the added value of outputting separate point-to-point (order) lines while also maintaining leg grouping.

enter image description here

2
  • Hi Stu - thanks a lot for your answer. I noticed my error with coding legs... (as per my comment to Taras, above). The processing tool Points to Path then worked fine. My boo-boo. Regarding the Points To Paths plugin though, I haven't seen this in the repository for quite a while now. Out of interest, how did you manage to download and install it in QGIS 3.22?
    – ChrisP
    Dec 8, 2021 at 12:59
  • You're correct, Chris - Points to Paths was missing for awhile because it hadn't been upgraded from QGIS 2.x to 3.x. Fortunately that upgrade occurred a few months ago, so it's back in the repository, and works fine - just as it did at 2.x. I may have discovered why you haven't found it: it is listed in the repository as PointstoPaths, without any spaces. Thus, searching for Points to Paths turns up nothing. I've contacted the developer to see if the repository name can be changed to Points to Paths: github.com/chiatt/pointstopaths/pull/7
    – Stu Smith
    Dec 8, 2021 at 16:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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