0

I have a layer that has date and time information and I need the difference between this information in seconds, I managed to get close to this but I needed to loop for the difference between the features. I used something like:

campotempo = pr.fieldNameIndex('Data/Hora GPS')
tempo1= feature1.attributes()[campotempo]
tempo2 = feature2.attributes()[campotempo]
tempo1form = datetime.datetime.strptime(tempo1, "%d/%m/%Y %H:%M:%S")
tempo2form = datetime.datetime.strptime(tempo2, "%d/%m/%Y %H:%M:%S")
datarange = ((tempo1form - tempo2form).seconds)
with edit(vl):
  for f in vl.getFeatures():
    f['Tempo(s)'] = datarange
    vl.updateFeature(f)

But it did not work

enter image description here

How can I use PyQGIS to make the difference between the time of each feature?

2
  • Yea, but I dont know how to do this in pyqgis, Just in fieldcalculator
    – Mestrexama
    Commented Sep 18, 2023 at 9:23
  • Is your field 'Tempo(s)' formatted as a decimal or a datetime?
    – Cary H
    Commented Sep 18, 2023 at 16:45

2 Answers 2

2

You can use an expression like this, which you can execute using python like this.

If you dont want to use expression you can:

import datetime
layer = QgsProject.instance().mapLayersByName("pointswithtime")[0]
timefield = "gpstime"

#Add the tempo field
pr = layer.dataProvider()
fieldname = "tempo"
pr.addAttributes([QgsField(fieldname, QVariant.Int)])
layer.updateFields()
ix = layer.fields().indexFromName(fieldname)
    
#List all features and sort by timestamp. You might want to sort by something else?
features = [[f.id(), datetime.datetime.strptime(f[timefield], "%d/%m/%Y %H:%M:%S")] for f in layer.getFeatures()]
features.sort(key=lambda x: x[1])

ids = [x[0] for x in features] #Extract the ids
timestamps = [x[1] for x in features] #And timestamps

#Calculate diff between row2-row1, row3-row2, ... and insert a starting None/NULL value
deltas = [None]+[(b-a).seconds for a,b in zip(timestamps, timestamps[1:])]

attributemap = {id : {ix: d} for id, d in zip(ids, deltas)} #A dict of {feature id : {fieldindex to update: value}, ..
pr.changeAttributeValues(attributemap) #Update the values

enter image description here

1
  • Hi, it works! Thank you very much, but now I have another problem, the layer with time and the calculation of the time difference that has IDs is filtered, that is, the layer does not start at ID 1, and I need to place the field with the calculated times in another layer that starts with ID 1, I managed to do this but when transferring the field, it starts at the ID of the filtered layer. Remembering that the filtered layer has X features, the layer where I want to place the time delta has X -1 features (all data will be used, considering that the time delta 1 is NULL)
    – Mestrexama
    Commented Sep 21, 2023 at 2:12
1

Check your field data type. If it is decimal you will have to convert your datarange variable to a float. Your code should work. I tested with putting a decimal in datarange. Also getting the difference between 2 datetimes should result in a datetime.timedelta.

    #Lists Fields in current layer
from datetime import timedelta
current_fields = []
layer = iface.activeLayer()
lfields = layer.fields()
for fld in lfields:
    fname = fld.name()
    current_fields.append(fname)
print(current_fields)
#datarange = timedelta(seconds = 4.5)
datarange = 4.5
with edit(layer):
  for f in layer.getFeatures():
    f['Tempo(s)'] = datarange
    f["Name"] = "hello"
    layer.updateFeature(f)

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.