It all depends on the level of accuracy that you need.
A coarse approach would be the spherical law of cosines. This has issues with small distances - some say that it is around 1km, others say down to a few meters.
A better approach would be the Haversine Formula. This works well, however, it doesn't take into account that the earth is not actually a sphere, but a spheroid.
The "best" approach would be Vincenty's formula.
You can find a very nice implementation of all of the above at R-bloggers written by Mario Pineda-Krch.
Vincenty's formula is also implemented in R as distance() in the SDMTools-package.
A crude R-script to outline how it could be done can be found below.
It should be noted that I am by no means good at R. The script is likely inefficient and redundant.
The script doesn't use the time-field in the current state, but using the lubridate-package to interpret the time and date fields will allow working with the time dimension in a decent manner.
Currently, it is assumed that the points come in the right order and that only one 'Collar ID' is present in the shapefile. These things can be dealt with by sorting the data entries by the time-field and subsetting based on the 'Collar ID'.
library(SDMTools)
library(rgeos)
library(maptools)
library(lubridate)
points <- readShapePoints("C:/Users/mlra/Desktop/FunWithDistance/DummyBird.shp")
lon <- as.vector(points@data$lon)
lat <- as.vector(points@data$lat)
z <- as.vector(points@data$z)
time <- parse_date_time(as.vector(points@data$time),"H!M!")
#The flight vector will be the distance between the current point and the previous point.
flight <- vector()
#The first element of the flight-vector will have to be zero, since no distance have been traveled
flight[1] <- 0
#We iterate from 2 to the number of observations.
for(i in 2:NROW(lon)){
Vincenty <- distance(lat1=lat[i-1],lon1=lon[i-1],lat2=lat[i],lon2=lon[i])
DirectDistance <- as.numeric(Vincenty[5]) # the fifth element of the output frame is the distance between the points.
#To be more accurate, we also take into account difference in altitude between the points
AltitudeChange <- abs(z[i]-z[i-1])
if(AltitudeChange!=0){
flight[i] <- sqrt(DirectDistance^2+AltitudeChange^2)
} else {
flight[i] <- DirectDistance
}
}
ResultingFrame <- data.frame(lon,lat,z,time,flight)