I have a series of GPS points recorded at an interval from a crop dusting/ aerial topdressing aircraft. They are all time stamped so sequencing is no issues.

When the aircraft is spraying/spreading an attribute is recorded as either '0' for off or '2' on (gate is open).

I have created a subset of data so only have the points for '2' (On). I now want to create lines linking these points but there are gaps in between spread runs ie the pilot will shut off (not spread) over roads, rivers, bush areas etc (see attached image). The data points also record things like altitude, speed, heading etc

I have tried Points to Paths but this just creates one continuous set of lines. Thats not I want as I want to buffer for swath width ie 20m to create a proof of release map.


I have tried the solution provided in this answer on some spread data and works great.

But running the code on the large file failed..

Error Message:

  • 2
    Brent, I think that you're going to need something in your data that will identify a unique flight segment during the gate was open. One identifier that comes to mind is when the gate value changes from 0 to 2 (and vice versa) between two adjacent records in your time sequence. It's late where I am, but I'll ponder a possible solution and get back to you. – Stu Smith Feb 3 at 5:54

I am learning pyQGIS and written a script that may solve this issue.

Start with the original dataset but the timestamps converted to integers (Unix time). You can do it with the epoch() expression in the Field Calculator.

This is my Attributes Table to test:


To create subgroups of the group numbered 2, ordered by the timestamp values, open the Python Console, show the Editor, and paste the following code:

#Layer name
layername = 'test points'
#Field name to ordering
orderfield = 'timestamp'
#Field name to group
groupfield = 'group'
#Field value to group
groupvalue = 2
#Unique values field
uvf = 'fid'

#get the layer
lyr = QgsProject.instance().mapLayersByName(layername)[0]
lyrcrs = lyr.sourceCrs().authid()
#Ordered Request
request = QgsFeatureRequest().addOrderBy(orderfield)
#Features Iterator
iterator = lyr.getFeatures(request)
#Features List
feats = [i for i in iterator]
#New Attributes Logic
groupscounter = 1
hadchanged = 0
for feat in feats:
    if feat[groupfield] == groupvalue:
        if hadchanged == 1:
            groupscounter += 1
            hadchanged = 0
        subgroup = groupscounter
        hadchanged = 1
        subgroup = 0

#Create a memory layer
uri = "Point?crs=" + lyrcrs + \
        "&field=" + uvf + ":integer" + \
        "&field=" + orderfield + ":integer" + \
        "&field=subgroup:integer" + \
mem_layer = QgsVectorLayer(uri,'reordered','memory')
prov = mem_layer.dataProvider()

What are we doing is request the features of the test points layer, ordered by timestamp values.
In logic we are creating subgroups every time a group value other than 2 appears.

The output is a new memory layer named reordered, with the same features as the original layer, its fid and tiemstamp value and the new subgroups. All values not equal to 2 go to subgroup 0:


Then, you can run the Points to Path tool against that layer.

Any advice about the code will be welcome.

| improve this answer | |
  • Hi Gabriel. Thanks for the suggestion and code. I just tried this on some spread data and works great. By using the subgroup value as the group field in "Points to Path" this creates the individual lines I can now work with. BTW, the screen shot above is from a dataset of 629,000 points. Running your code on this large file failed. I'm guessing my file has far too many points to run through the code? – Brent Robertson Feb 5 at 1:19
  • Hi Brent. " I'm guessing my file has far too many points to run through the code?" - I think that the code must work with too many points.. – Gabriel De Luca Feb 5 at 18:30
  • Hi Gabriel. I was wondering that. I have tried to insert a screenshot of the image without success. Traceback (most recent call last): File "C:\........code.py", line 90, in run code exec(code, self.locals) File "<input>", line 1, in <module> File "<string>", line 33, in <module> KeyError: 'Timestamp' – Brent Robertson Feb 5 at 19:25
  • Edit your question post to indicate that following the code of this answer fails in the large dataset. Include, as formatted text, the console output. – Gabriel De Luca Feb 5 at 19:27

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.