I am working with GPS track points, and would like to calculate the speed of movement between points within the same attribute table. Google didn't come up with any obvious solutions, so I assume I need to calculate the distance between a point and the previous one, and then the time elapsed between each two points, and divide the former by the latter.
I therefore would like to know
how I can use Calculate Field to obtain the difference in time between points in the attribute table (all points have time stamps)?
Huge thanks to whoever can help with this. I am at the end of my thesis and I have spent too many hours trying to figure this out by myself. I'm sure it's simple, but I just cannot find a way to do it . Happy New Year!
Hi @GreerJarrett,
A few things to ask in order to figure out the direction.
If the answer is yes to both, then this can easily be accomplished.
var fs = $featureset
var QueryField = 'fieldname'
var QueryValue = $feature.fieldvalue
var Query = QueryField + ' = @QueryValue'
var DTField = 'DateTimeField'
var fs = Filter( fs , Query )
var Cntfs = Count( fs )
if( Cntfs >= 2 ){
var topfs = Top( OrderBy( fs , DTField + ' DESC' ) , 2 )
var N = 0
var A = Null
var B = Null
for( var i in topfs ){
if( N < Cntfs ){ A = topfs[ i ] }
else{ B = topfs[ i ] }
N++
}
if( !IsEmpty( A ) && !IsEmpty( B ) ){
var ATime = A[ DTField ]
var BTime = B[ DTField ]
var DTDiff = DateDiff( ATime , BTime , 'Seconds' )
var Dist = Distance( Geometry( A ) , Geometry( B ) , 'Unit' )
var Speed = Dist/DTDiff
// If you need to round the speed, simply use Round( value , decimal places )
if( Speed > 0 ){ return Speed }
}
}
You can simply use the expression to create an attribute rule and then run some anonymous field calculation to trigger the rule. You cannot do this in a field calculation, at least to the best of my knowledge.
Another option is to use Tracking Functions but only if you have GeoAnalytics.
Combining the previous answers should get you a working solution, but if you can field calculate using Python this will also work:
last_shp = None
last_dt = None
def run(shp, dt):
global last_shp
global last_dt
retval = None
if last_shp is not None and last_dt is not None:
dist = last_shp.angleAndDistanceTo(shp, "GEODESIC")[1] / 1000 # Kilometres
diff = (dt - last_dt).seconds / 3600 # Hours
retval = dist / diff
last_shp = arcpy.PointGeometry(shp.firstPoint, shp.spatialReference)
last_dt = dt
return retval
This assumes your data is pre-sorted but it should run faster than an Arcade equivalent due to the massive reduction in database hits. This assumes your data is stored in Web Mercator or another CRS that's meters based, you'll have to convert the CRS units to your desired ones as needed (e.g. multiply by 0.0001893936 if your data is in a US State Plane and you want MPH).