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?

Mestrexama
  • 91
  • 4

2 Answers2

1

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

BERA
  • 72,339
  • 13
  • 72
  • 161
  • 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 Sep 21 '23 at 02:12
0

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)
Cary H
  • 964
  • 9
  • 21