-
Notifications
You must be signed in to change notification settings - Fork 9
/
pathdistps.m
152 lines (136 loc) · 4.92 KB
/
pathdistps.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
function d = pathdistps(lat_or_x,lon_or_y,varargin)
% pathdistps returns the cumulative distance along a path in polar stereographic
% coordinates (true lat 71 S).
%
%% Syntax
%
% d = pathdistps(lat,lon)
% d = pathdistps(x,y)
% d = pathdistps(...,'km')
% d = pathdistps(...,'ref',[reflat reflon])
% d = pathdistps(...,'ref',[refx refy])
% d = pathdistps(...,'FixDistortion',false)
%
%% Description
%
% d = pathdistps(lat,lon) returns the cumulative distance d in meters along the path
% specified by geo coordinates lat,lon. Coordinates must be vectors of equal size.
%
% d = pathdistps(x,y) returns the cumulative distance d in meters along the path
% specified by polar stereographic coordinates x,y where x and y are vectors of equal
% size in ps71 meters.
%
% d = pathdistps(...,'km') simply divides output by 1000 to give distance in kilometers.
%
% d = pathdistps(...,'ref',[reflat reflon]) references the output to the track coordinate
% nearest to the location given by a two-element vector [reflat reflon]. This might be
% useful when analyzing distance along a satellite ground track relative to a point of
% interest such as a grounding line.
%
% d = pathdistps(...,'ref',[refx refy]) references the output as above, but using polar
% stereogprahic (ps71) coordinates.
%
% d = pathdistps(...,'FixDistortion',false) calculates distances in pure polar stereographic
% coordinates without accounting for distortion induced by the projection. In Nov 2018,
% the default behavior changed from 'FixDistortion',false to 'FixDistortion',true,
% meaning distances now reflect true distances rather than distances in the polar
% stereographic projection.
%
%% Example
% Use reftrack from the ICESat reference tracks toolbox and clip to the eastern hemisphere:
%
% [lat,lon] = reftrack(1304);
% lat = lat(lon>0);
% lon = lon(lon>0);
%
% % Calculate the total distance in meters:
% d = pathdistps(lat,lon);
%
% % Or calculate total distance in kilometers, referenced to (66.8575 S, 143.5678 E), which
% % is a point near the ICESat track's intersection with the grounding line:
% d = pathdistps(lat,lon,'km','ref',[-66.8575 143.5678]);
%
% plot(d,lon)
% xlabel 'distance relative to the grounding line (km)'
% ylabel 'longitude (deg)'
%
%% Citing Antarctic Mapping Tools
% This function was developed for Antarctic Mapping Tools for Matlab (AMT). If AMT is useful for you,
% please cite our paper:
%
% Greene, C. A., Gwyther, D. E., & Blankenship, D. D. Antarctic Mapping Tools for Matlab.
% Computers & Geosciences. 104 (2017) pp.151-157.
% http://dx.doi.org/10.1016/j.cageo.2016.08.003
%
% @article{amt,
% title={{Antarctic Mapping Tools for \textsc{Matlab}}},
% author={Greene, Chad A and Gwyther, David E and Blankenship, Donald D},
% journal={Computers \& Geosciences},
% year={2017},
% volume={104},
% pages={151--157},
% publisher={Elsevier},
% doi={10.1016/j.cageo.2016.08.003},
% url={http://www.sciencedirect.com/science/article/pii/S0098300416302163}
% }
%
%% Author Info
% This function was written by Chad A. Greene of the University of Texas
% at Austin Institute for Geophysics (UTIG), April 2016.
% http://www.chadagreene.com
%
% See also: pathdist, pspath, and cumsum.
%% Initial error checks:
narginchk(2,inf)
assert(exist('islatlon.m','file')==2,'Error: Cannot find Antarctic Mapping Tools (AMT). Make sure you have an up-to-date version of AMT which can be found on the Mathworks File Exchange site and make sure Matlab can find the functions in AMT.')
assert(isvector(lat_or_x)==1,'Input Error: input coordinates must be vectors.')
assert(isequal(size(lat_or_x),size(lon_or_y))==1,'Input error: Dimensions of input coordinates must agree.')
%% Set defaults:
kmout = false;
ref = false;
%% Parse inputs:
% Convert geo coordinates to ps71 if necessary:
if islatlon(lat_or_x,lon_or_y)
lat = lat_or_x;
[x,y] = ll2ps(lat_or_x,lon_or_y);
else
x = lat_or_x;
y = lon_or_y;
[lat,~] = ps2ll(x,y); % only need lat for distortion
end
% Does the user want output in kilometers?
if any(strcmpi(varargin,'km'))
kmout = true;
end
% Does the user want the output distances in reference to some location?
tmp = strcmpi(varargin,'ref');
if any(tmp)
ref = true;
refcoord = varargin{find(tmp)+1};
assert(numel(refcoord)==2,'Input Error: Reference coordinate must be a two-element vector.')
if islatlon(refcoord(1),refcoord(2))
[refx,refy] = ll2ps(refcoord(1),refcoord(2));
else
refx = refcoord(1);
refy = refcoord(2);
end
end
%% Perform mathematics:
m = psdistortion(lat(2:end));
% Cumulative sum of distances:
if isrow(x)
d = [0,cumsum(hypot(diff(x)./m,diff(y)./m))];
else
d = [0;cumsum(hypot(diff(x)./m,diff(y)./m))];
end
% Reference to a location:
if ref
dist2refpoint = hypot(x-refx,y-refy);
[~,mind] = min(dist2refpoint);
d = d - d(mind(1));
end
% Convert to kilometers if user wants it that way:
if kmout
d = d/1000;
end
end