Calculating distance travelled along a flight trajectory

Hello,
I have a series of longitude, latitude, and altitude points corresponding to a flight trajectory (attached). I would like to calculate the distance (m/km) travelled at each point along the flight trajectory from a fixed point (e.g. the center of Paris 48.85 N, 2.34E). Is this possible to do this with IGOR?
Thank you in advance.
Example_flighttrajectory.pxp (9.58 KB)
I'm not at my computer at the moment, but you should check out Vincenty's formulae. Do an Internet search. It shows how to calculate Great Circles between points, which you need in order to properly calculate the distance between two points. I don't think Igor has a built in function to do that, but I could be wrong.

That in mind, I don't understand the part of your question, "from a fixed point." Wouldn't you just want to calculate the distance between each point, and then add them all up to get the total distance? Or are you saying you want the distance from an a priori point to each of the points in your track?
Hello,
Thank you for your comment and suggestions.

""That in mind, I don't understand the part of your question, "from a fixed point." Wouldn't you just want to calculate the distance between each point, and then add them all up to get the total distance? Or are you saying you want the distance from an a priori point to each of the points in your track?""

I would like to calculate the distance that the plane has travelled from the centre of Paris, which could be calculated by adding the distances between each point and add them together.

Someone had given me a bit of IGOR code a few years ago that did this, but I unfortunately cannot find it. I do not think that I could write this code myself.
I will keep searching...
Does this help? It's code I wrote that I'm pretty sure uses Vincenty's formulae. The LAT is the latitude wave, LON is longitude wave. It calculates the distances between each successive point, storing them to "dist_calc" and "dist_m". It's not elegant, but it does the job.

Macro CalculateDistances()

Silent(1)
PauseUpdate

Variable i
Make/O/N=(numpnts(LAT)-1) dist_calc; dist_calc = NaN
do
	dist_calc[i] = (sin((LAT[i]-LAT[i+1])*pi/180/2))^2 + cos(LAT[i]*pi/180)*cos(LAT[i+1]*pi/180)*(sin((LON[i]-LON[i+1])*pi/180/2))^2
	dist_calc[i] = 2*atan2(sqrt(dist_calc[i]),sqrt(1-dist_calc[i]))
	i += 1
while(i < numpnts(LAT)-1)

//Save as both meters and feet.
Duplicate/O dist_calc dist_m
dist_m = dist_calc * 6371*1000	//convert to meters
dist_calc *= 3959*5280			//convert to feet

//Integrate along the path, such that the last point in dist_m_INT will be the total length travelled in meters.
Duplicate/O dist_m dist_m_INT
Integrate dist_m/D=dist_m_INT

End


If you wanted to modify this to do it from a fixed point each time, then you would set a
Variable LAT_ORIGIN = [value]
and
Variable LON_ORIGIN = [value]
, change the LAT[i] and LON[i] to those origin variables, change
i+1
to
i
, and run it. You'd want to get rid of the do-while loop in that case, using Igor's matrix notation, but again, without that it'd still get the job done.
Hello,
Yes, it works very well. Thank you very much! I really appreciate that.

astrostu wrote: Does this help? It's code I wrote that I'm pretty sure uses Vincenty's formulae. The LAT is the latitude wave, LON is longitude wave. It calculates the distances between each successive point, storing them to "dist_calc" and "dist_m". It's not elegant, but it does the job.

*****IGOR CODE****
If you wanted to modify this to do it from a fixed point each time, then you would set a
Variable LAT_ORIGIN = [value]
and
Variable LON_ORIGIN = [value]
, change the LAT[i] and LON[i] to those origin variables, change
i+1
to
i
, and run it. You'd want to get rid of the do-while loop in that case, using Igor's matrix notation, but again, without that it'd still get the job done.

Hi

While searching for a solution to this myself I came across this thread. I'll add my own solutions here for completeness if anyone has need for it. 

Firstly, a function that takes lat,lon, plus optional start and end points, and altitude. The total distance can be calculated in 3 ways:

1. total distance over WGS-84 ellipsoid

2. total distance over WGS-84 ellipsoid accounting for altitude using simple pythagorean theorem - beware this works OK if you have high time resolution positional data, but not necessarily if you have two points far apart.

3. total spherical distance

 

// Calculate total distance along a set of lat-lon co-ordinates
// method=0 (default) - total distance over WGS-84 ellipsoid accounting for altitude above if given
// method=1 - total spherical distance 
Function DistanceAlongTrack(lat,lon[,stPnt,endPnt,method,alt])
	Wave lat,lon
	Variable stPnt,endPnt,method
	Wave alt
	
	// if no altitude is given make a zero wave in its place
	if (paramIsDefault(alt))
		Make/O/FREE/N=(dimSize(lat,0)) alt=0
		endif
	
	// Lat and Lon waves should be the same size 
	if (dimSize(lat,0)!=dimSize(lon,0))
		return 0
		endif
	
	// if no endpoint is given 	
	if (paramisDefault(endPnt))
		endPnt=dimSize(lat,0)
		endif

	Variable i,totDist
	for (i=stPnt;i<(endPnt-1);i+=1)
		if (method==0) // total distance over WGS-84 ellipsoid accounting for altitude above
			totDist+=EllipsoidalDistanceBetweenTwoPoints(lat[i],lon[i],lat[i+1],lon[i+1],alt1=alt[i],alt2=alt[i+1])
		elseif (method==1) // total spherical distance 		
			totDist+=SphericalDistanceBetweenTwoPoints(lat[i],lon[i],lat[i+1],lon[i+1])
		endif
	endfor
	
	// distance in meters	
	return totDist
end

 Secondly there is code to calculate total spherical distance using the Haversine formula

// calculates spherical distance between two points on earth given coords in decimal degrees
// uses haversine formula
// radius of earth is taken to be 6371 km (IUGG/WGS-84 mean)
Function SphericalDistanceBetweenTwoPoints(lat1, long1, lat2, long2)
    Variable lat1, long1, lat2, long2
    
   	// convert inputs in degrees to radians
	lat1*= pi/180
	long1*= pi/180
	lat2*= pi/180
	long2*= pi/180
    
    Variable dlon = long1 - long2
    Variable dlat = lat1 - lat2
    Variable aa = ((sin(dlat / 2) ^ 2) + cos(lat1) * cos(lat2) * (sin(dlon / 2) ^ 2))
    Variable cc = 2 * atan2(sqrt(aa), sqrt(1 - aa))
    Variable dd = 6371 * cc
    
    // return distance in metres
    return dd * 1000
end

Thirdly there is code to calculate the distance over a ellipsoid using Vincenty's formula, with optional complication of accounting for altitude.

// calculates ellipsoidal distance between two points on earth given coords in decimal degrees
// uses Vincenty's formula + optional approximately correction for altitude above the ellipsoid 
Function EllipsoidalDistanceBetweenTwoPoints(lat1, long1, lat2, long2 [,alt1, alt2])
	Variable lat1, long1, lat2, long2, alt1, alt2
	
	// convert inputs in degrees to radians
	lat1*= pi/180
	long1*= pi/180
	lat2*= pi/180
	long2*= pi/180
	
	// approximately correct for altitude above the ellipsoid 
	variable delta_alt = abs(alt1 - alt2)
	variable avg_alt = (alt1 + alt2) / 2
	
	// correct for errors at exact poles by adjusting 0.6 millimeters
	if (abs(pi/2-abs(lat1)) < 1e-10)
	    lat1 = sign(lat1)*(pi/2-(1e-10))
	endif
	if (abs(pi/2-abs(lat2)) < 1e-10)
	    lat2 = sign(lat2)*(pi/2-(1e-10))
	endif
	
	Variable a = 6378137.0 // equatorial radius in meters 
	Variable f = 1/298.257223563 // ellipsoid flattening 
	Variable b = (1 - f)*a 
	Variable tolerance = 1e-11 // to stop iteration
	
	Variable phi1 = lat1 
	Variable phi2 =lat2
	Variable U1 = atan((1-f)*tan(phi1))
	Variable U2 = atan((1-f)*tan(phi2))
	Variable L1 = long1
	Variable L2 = long2
	Variable L = L2 - L1
	
	Variable lambda_old = L + 0
	Variable t
	Variable sin_sigma
	Variable cos_sigma
	Variable sigma
	Variable sin_alpha
	Variable cos_sq_alpha
	Variable cos_2sigma_m
	Variable C
	Variable lambda_new
	
	do	
		t = (cos(U2)*sin(lambda_old))^2
		t += (cos(U1)*sin(U2) - sin(U1)*cos(U2)*cos(lambda_old))^2
		sin_sigma = t^0.5
		cos_sigma = sin(U1)*sin(U2) + cos(U1)*cos(U2)*cos(lambda_old)
		sigma = atan2(sin_sigma, cos_sigma) 
		
		sin_alpha = cos(U1)*cos(U2)*sin(lambda_old) / sin_sigma
		cos_sq_alpha = 1 - sin_alpha^2
		cos_2sigma_m = cos_sigma - 2*sin(U1)*sin(U2)/cos_sq_alpha
		C = f*cos_sq_alpha*(4 + f*(4-3*cos_sq_alpha))/16
		
		t = sigma + C*sin_sigma*(cos_2sigma_m + C*cos_sigma*(-1 + 2*cos_2sigma_m^2))
		lambda_new = L + (1 - C)*f*sin_alpha*t
		
		 // correct for convergence failure in the case of essentially antipodal points
		if (lambda_new > pi)
			Print "Points are essentially antipodal. Precision may be reduced slightly."
			lambda_new = pi
			break
		endif
			
		if (abs(lambda_new - lambda_old) <= tolerance)
			break
		else
			lambda_old = lambda_new
		endif
	while (1)		
	
	u2 = cos_sq_alpha*((a^2 - b^2)/b^2)
	variable Av = 1 + (u2/16384)*(4096 + u2*(-768+u2*(320 - 175*u2)))
	variable Bv = (u2/1024)*(256 + u2*(-128 + u2*(74 - 47*u2)))
	t = cos_2sigma_m + 0.25*Bv*(cos_sigma*(-1 + 2*cos_2sigma_m^2))
	t -= (Bv/6)*cos_2sigma_m*(-3 + 4*sin_sigma^2)*(-3 + 4*cos_2sigma_m^2)
	Variable delta_sigma = Bv * sin_sigma * t
	Variable s = (b+(avg_alt-(delta_alt/2)))*Av*(sigma - delta_sigma)
	
	// pythagorean theorem
	s = sqrt(s^2 + delta_alt^2)
	
	// in meters	
	return s
end

Some of this is converted from elsewhere and different languages and I take no credit for it.