-
Notifications
You must be signed in to change notification settings - Fork 61
/
Copy pathm_lldist.m
65 lines (49 loc) · 1.95 KB
/
m_lldist.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
function [dist,lons,lats] = m_lldist(long,lat,N)
% M_LLDIST Spherical earth distance between points in long/lat coordinates.
% RANGE=M_LLDIST(LONG,LAT) gives the distance in kilometers between
% successive points in the vectors LONG and LAT, computed
% using the Haversine formula on a spherical earth of radius
% 6378.137km. Distances are probably good to better than 1% of the
% "true" distance on the ellipsoidal earth
%
% [RANGE,LONGS,LATS]=M_LLDIST(LONG,LAT,N) computes the N-point geodesics
% between successive points. Each geodesic is returned on its
% own row of length N+1.
%
% See also M_XYDIST
% Rich Pawlowicz (rich@ocgy.ubc.ca) 6/Nov/00
% This software is provided "as is" without warranty of any kind. But
% it's mine, so you can't sell it.
%
% 30/Dec/2005 - added n-point geodesic computations, based on an algorithm
% coded by Jeff Barton at Johns Hopkins APL in an m-file
% I looked at at mathworks.com.
pi180=pi/180;
earth_radius=6378.137;
m=length(long)-1;
long1=reshape(long(1:end-1),m,1)*pi180;
long2=reshape(long(2:end) ,m,1)*pi180;
lat1= reshape(lat(1:end-1) ,m,1)*pi180;
lat2= reshape(lat(2:end) ,m,1)*pi180;
dlon = long2 - long1;
dlat = lat2 - lat1;
a = (sin(dlat/2)).^2 + cos(lat1) .* cos(lat2) .* (sin(dlon/2)).^2;
angles = 2 * atan2( sqrt(a), sqrt(1-a) );
dist = earth_radius * angles;
if nargin==3 & nargout>1, % Compute geodesics.
% Cartesian unit vectors in rows of v1,v2
v1=[cos(long1).*cos(lat1) sin(long1).*cos(lat1) sin(lat1) ];
v2=[cos(long2).*cos(lat2) sin(long2).*cos(lat2) sin(lat2) ];
% We want to get a unit vector tangent to the great circle.
n1=cross(v1,v2,2);
t1=cross(n1,v1,2);
t1=t1./repmat(sqrt(sum(t1.^2,2)),1,3);
lons=zeros(m,N+1);
lats=zeros(m,N+1);
for k=1:m,
% Radials for all points
p1=v1(k,:)'*cos(angles(k)*[0:N]/N) + t1(k,:)'*sin(angles(k)*[0:N]/N);
lons(k,:)=atan2(p1(2,:),p1(1,:))/pi180;
lats(k,:)=asin(p1(3,:))/pi180;
end;
end;