-
Notifications
You must be signed in to change notification settings - Fork 9
/
mapzoomps.m
454 lines (379 loc) · 12.8 KB
/
mapzoomps.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
function h = mapzoomps(varargin)
% mapzoomps zooms a south polar stereographic map to a specified location and extent.
% This is an adaptation of mapzoom, but does not require Matlab's Mapping Toolbox.
% Syntax for mapzoomps is similar to mapzoom, but differs slightly for some options.
%
%% 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}
% }
%
%% Syntax
%
% mapzoomps
% mapzoomps(lat,lon)
% mapzoomps(x,y)
% mapzoomps('SCAR location')
% mapzoomps(...,'size',mapsizekm)
% mapzoomps(...,InsetLocation)
% mapzoomps(...,'insetsize',sizefraction)
% mapzoomps(...,'frame','off')
% mapzoomps(...,'km')
% h = mapzoomps(...)
%
%% Description
%
% mapzoomps(lat,lon) centers a 500 km wide map about the georeferenced
% location given by lat, lon.
%
% mapzoomps(x,y) centers a 500 km wide map about the polar stereographic
% eastings and northings x and y. Polar stereographic coordinates are
% automatically determined by the islatlon function.
%
% mapzoomps('SCAR location') uses scarloc to find the coordinates corresponding
% to the string 'SCAR location'.
%
% mapzoomps(...,'size',mapsizekm) specifies size of the map in kilometers given
% mapsizekm, which can be a scalar to create a square map or a two-element array
% for a rectangular map in the form [mapwidthkm mapheightkm], where mapwidthkm and
% mapheightkm are the dimensions of the map in kilometers.
%
% mapzoomps(...,InsetLocation) creates an inset map at the location InsetLocation,
% which can be
% 'southeast' or 'se' lower right corner
% 'northwest' or 'nw' upper left corner
% 'northeast' or 'ne' upper right corner
% 'southwest' or 'sw' lower left corner
%
% mapzoomps(...,'insetsize',sizefraction) specifies size of the inset as a
% fraction of the width of the current map. Default sizefraction is 0.25.
%
% mapzoomps(...,'frame','off') removes frame from the inset.
%
% mapzoomps(...,'km') is for plots in polar stereographic kilometers rather than the default meters.
%
% h = mapzoomps(...) returns a handle h of inset map axes.
%
%% Example 1
% Initialize a 500 km by 500 km map centered on Pitman Fracture Zone, plot ibcso
% bathymetry, and place a graphical reference scale with scalebarps. When calling mapzoomps
% specify 'ne' to place an inset map in the upper right-hand corner.
%
% mapzoomps('pitman fracture zone','ne')
% ibcso('image','xy')
% scalebarps
%
%% Example 2
% Plot Bedmap2 bed elevation, apply relief shading with shadem, and center a 1600 km wide
% by 800 km tall map on the Lambert Glacier/Amery Ice Shelf system at (71°S,69°N). Place
% frameless inset map in the upper left hand corner:
%
% bedmap2('bed','xy')
% shadem([225 60],3)
% mapzoomps(-71,69,'size',[1600 800],'nw','frame','off')
% scalebarps
% scarlabel({'Lambert Glacier','Cape Child','Landing Bluff'},...
% 'fontangle','italic','fontsize',8)
%
%% Author Info
% This function and supporting documentation were written by Chad A. Greene of the
% University of Texas at Austin's Institute for Geophysics (UTIG), February 2016.
% Feel free to contact me if you have any questions or comments.
% http://www.chadagreene.com
%
% See also scarloc, scarlabel, scarclick, mapzoom, and scalebarps.
%% Set defaults:
inset = false;
insetsize = 0.25;
frameon = true;
location = 'northeast';
usekm = false;
meridian = 0;
if nargin==0
UseCurrentExtents = true;
else
UseCurrentExtents = false;
mapsize = [500 500]; % sets default map size to 500 km by 500 km
end
%% Parse inputs:
% Inset location:
tmp = strcmpi(varargin,'southwest')|strcmpi(varargin,'northwest')|...
strcmpi(varargin,'southeast')|strcmpi(varargin,'northeast')|...
strcmpi(varargin,'sw')|strcmpi(varargin,'nw')|...
strcmpi(varargin,'se')|strcmpi(varargin,'ne');
if any(tmp)
inset = true;
location = varargin{tmp};
if tmp(1)
UseCurrentExtents = true;
end
end
% Check for inset size declaration:
tmp = strcmpi(varargin,'insetsize');
if any(tmp)
inset = true;
insetsize = varargin{find(tmp)+1};
if tmp(1)
UseCurrentExtents = true;
end
end
% Check for frame declaration:
tmp = strcmpi(varargin,'frame');
if any(tmp)
inset = true;
if strcmpi(varargin{find(tmp)+1},'off')||strcmpi(varargin{find(tmp)+1},'none');
frameon = false;
if tmp(1)
UseCurrentExtents = true;
end
end
end
% Map width:
tmp = strcmpi(varargin,'size')|strcmpi(varargin,'mapsize')|strcmpi(varargin,'mapwidth')|strcmpi(varargin,'mapwidthkm')|strcmpi(varargin,'width');
if any(tmp)
mapsize = varargin{find(tmp)+1};
assert(isnumeric(mapsize)==1,'Map size must be numeric.');
if isscalar(mapsize)
mapsize = [mapsize mapsize];
end
assert(numel(mapsize)==2,'Map size must be a one- or two-element numeric value.')
end
% Polar stereographic kilometers or meters?
tmp = strcmpi(varargin,'km');
if any(tmp)
usekm = true;
if tmp(1)
UseCurrentExtents = true;
end
end
% Center location declaration:
if ~UseCurrentExtents
% Determine center location:
if ~isnumeric(varargin{1})
% User has entered a location by string:
if strcmpi(varargin{1},'default')
set(gca,'xlim',3000*[-1 1],'ylim',3000*[-1 1]);
else
[xc,yc] = scarloc(varargin{1},'xy');
% [xc,yc] = ll2ps(tmplat,tmplon,'meridian',meridian); % no, this won't work yet.
end
else
% User has entered location by coordinates:
if islatlon(varargin{1},varargin{2})
[xc,yc] = ll2ps(varargin{1},varargin{2},'meridian',meridian);
else
xc = varargin{1};
yc = varargin{2};
end
end
% Check for inputs of lat,lon limits:
try
if isequal(numel(varargin{1}),numel(varargin{2}),2) & islatlon(varargin{1},varargin{2})
latlim = varargin{1};
lonlim = varargin{2};
meridian = mean(lonlim);
end
end
end
tmp = strcmpi(varargin,'meridian');
if any(tmp)
meridian = varargin{find(tmp)+1};
assert(isscalar(meridian)==1,'Error: meridian must be a scalar.')
warning('specifying meridian might not work yet.')
end
%% Set axes of map:
% Find and delete old inset if one exists:
try
hinsetmap = findobj(gcf,'tag','insetmap');
delete(hinsetmap);
end
gcah = gca; % handle of initial plot
if UseCurrentExtents
ax = axis;
else
if meridian==0
axis equal xy
ax = [xc-mapsize(1)*500 xc+mapsize(1)*500 yc-mapsize(2)*500 yc+mapsize(2)*500];
axis(ax);
end
end
% Define x,y coordinates of axis perimeter:
if meridian==0
axx = [ax(1) ax(2) ax(2) ax(1) ax(1)];
axy = [ax(3) ax(3) ax(4) ax(4) ax(3)];
else
lat = [linspace(latlim(1),latlim(1),200),linspace(latlim(2),latlim(2),200),latlim(1)];
lon = [linspace(lonlim(1),lonlim(2),200),linspace(lonlim(2),lonlim(1),200),lonlim(1)];
[axx,axy] = ll2ps(lat,lon,'meridian',meridian);
axis equal xy
axis([min(axx) max(axx) min(axy) max(axy)])
end
%% Place an inset map:
if inset
load AMTdata.mat % contains crude grounding line and ice shelf outlines, approximated and downsampled significantly from Bedmap2
gp = plotboxpos(gca);
insetwidth = insetsize*gp(3);
insetheight = insetsize*gp(4);
switch lower(location)
case {'southwest','sw'}
insetx = gp(1);
insety = gp(2);
case {'northeast','ne'}
insetx = gp(1) + gp(3) - insetwidth;
insety = gp(2) + gp(4) - insetheight;
case {'northwest','nw'}
insetx = gp(1);
insety = gp(2) + gp(4) - insetheight;
case {'southeast','se'}
insetx = gp(1) + gp(3) - insetwidth;
insety = gp(2);
otherwise
error('Unrecognized inset location.')
end
% Create new set of axes for inset map:
h = axes('position',[insetx insety insetwidth insetheight],'tag','insetmap');
hold on
% Plot ice shelves as patch objects:
for k = 1:30
[tmpx,tmpy] = ll2ps(slat{k},slon{k},'meridian',meridian);
patch(tmpx,tmpy,[.8 .8 .8],'linewidth',0.25)
end
% Plot grounding lines as patch objects:
for k = 1:30
[tmpx,tmpy] = ll2ps(glat{k},glon{k},'meridian',meridian);
patch(tmpx,tmpy,[.5 .5 .5],'linewidth',0.25)
end
% Plot red box:
if usekm
plot(axx*1000,axy*1000,'r-','linewidth',1);
else
plot(axx,axy,'r-','linewidth',1);
end
axis equal tight
% Set final dimensions after plotting the inset:
gpinset = plotboxpos(gca);
insetwidth = gpinset(3);
insetheight = gpinset(4);
switch lower(location)
case {'southwest','sw'}
insetx = gp(1);
insety = gp(2);
case {'northeast','ne'}
insetx = gp(1) + gp(3) - insetwidth;
insety = gp(2) + gp(4) - insetheight;
case {'northwest','nw'}
insetx = gp(1);
insety = gp(2) + gp(4) - insetheight;
case {'southeast','se'}
insetx = gp(1) + gp(3) - insetwidth;
insety = gp(2);
otherwise
error('Unrecognized inset location.')
end
% Format inset axes:
set(gca,'xtick',[],'ytick',[],'position',[insetx insety insetwidth insetheight])
if frameon
box on
else
axis off
end
% Make the original map axes current:
axes(gcah);
% Ensure inset map is on top of the stack:
uistack(gcah,'down');
% Clean up:
if nargout==0
clear h
end
end
%% Kelly Kearney's plotboxpos function:
function pos = plotboxpos(h)
%PLOTBOXPOS Returns the position of the plotted axis region
%
% pos = plotboxpos(h)
%
% This function returns the position of the plotted region of an axis,
% which may differ from the actual axis position, depending on the axis
% limits, data aspect ratio, and plot box aspect ratio. The position is
% returned in the same units as the those used to define the axis itself.
% This function can only be used for a 2D plot.
%
% Input variables:
%
% h: axis handle of a 2D axis (if ommitted, current axis is used).
%
% Output variables:
%
% pos: four-element position vector, in same units as h
% Copyright 2010 Kelly Kearney
% Check input
if nargin < 1
h = gca;
end
if ~ishandle(h) || ~strcmp(get(h,'type'), 'axes')
error('Input must be an axis handle');
end
% Get position of axis in pixels
currunit = get(h, 'units');
set(h, 'units', 'pixels');
axisPos = get(h, 'Position');
set(h, 'Units', currunit);
% Calculate box position based axis limits and aspect ratios
darismanual = strcmpi(get(h, 'DataAspectRatioMode'), 'manual');
pbarismanual = strcmpi(get(h, 'PlotBoxAspectRatioMode'), 'manual');
if ~darismanual && ~pbarismanual
pos = axisPos;
else
dx = diff(get(h, 'XLim'));
dy = diff(get(h, 'YLim'));
dar = get(h, 'DataAspectRatio');
pbar = get(h, 'PlotBoxAspectRatio');
limDarRatio = (dx/dar(1))/(dy/dar(2));
pbarRatio = pbar(1)/pbar(2);
axisRatio = axisPos(3)/axisPos(4);
if darismanual
if limDarRatio > axisRatio
pos(1) = axisPos(1);
pos(3) = axisPos(3);
pos(4) = axisPos(3)/limDarRatio;
pos(2) = (axisPos(4) - pos(4))/2 + axisPos(2);
else
pos(2) = axisPos(2);
pos(4) = axisPos(4);
pos(3) = axisPos(4) * limDarRatio;
pos(1) = (axisPos(3) - pos(3))/2 + axisPos(1);
end
elseif pbarismanual
if pbarRatio > axisRatio
pos(1) = axisPos(1);
pos(3) = axisPos(3);
pos(4) = axisPos(3)/pbarRatio;
pos(2) = (axisPos(4) - pos(4))/2 + axisPos(2);
else
pos(2) = axisPos(2);
pos(4) = axisPos(4);
pos(3) = axisPos(4) * pbarRatio;
pos(1) = (axisPos(3) - pos(3))/2 + axisPos(1);
end
end
end
% Convert plot box position to the units used by the axis
temp = axes('Units', 'Pixels', 'Position', pos, 'Visible', 'off', 'parent', get(h, 'parent'));
set(temp, 'Units', currunit);
pos = get(temp, 'position');
delete(temp);