-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbbox2ind.m
67 lines (57 loc) · 2.81 KB
/
bbox2ind.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
function ixes = bbox2ind(bbox,LON,LAT)
%function ixes = bbox2ind(bbox,LON,LAT)
%
% Return a 4x2 matrix of indices IXES in LON,LAT for bounding box BBOX (must
% be in the form [MINX, MAXX, MINY,MAXY]; indices are for the lon and lat of
% lower-left, lower-right, upper-right, and upper-left corners of BBOX, resp.
% Sizes of all non-singleton dimensions of LON must equal those of LAT. NOTE:
% If LON and LAT are vectors, uses MESHGRID (v.) to put them in plaid form.
%
% Last Saved Time-stamp: <Fri 2016-05-20 11:10:03 Eastern Daylight Time gramer>
if ( bbox(2)<=bbox(1) || bbox(4)<=bbox(3) )
error('Ecoforecasts:BBox:badbbox','BBOX should have form [MINX,MAXX,MINY,MAXY]');
end;
if ( ~isnumeric(LON) || ~isnumeric(LAT) || ~ismatrix(LON) || ~ismatrix(LAT) )
error('Ecoforecasts:BBox:badargs','LON and LAT should be numeric matrices');
end;
% Remove any singleton dimensions
LON = squeeze(LON);
LAT = squeeze(LAT);
if ( isvector(LON) && isvector(LAT) )
warning('Ecoforecasts:BBox:nonplaid','Using MESHGRID(SORT(LON(:)),SORT(LAT(:)))');
lon = sort(LON(:));
lat = sort(LAT(:));
[LON,LAT] = meshgrid(lon,lat);
elseif ( isvector(LON) || isvector(LAT) )
error('Ecoforecasts:BBox:badargs','If either LON or LAT is a vector, both must be vectors');
else
if ( LON(1,1) == LON(1,2) )
warning('Ecoforecasts:BBox:transposed','Transposing LON');
LON = LON';
end;
if ( LAT(1,1) == LAT(2,1) )
warning('Ecoforecasts:BBox:transposed','Transposing LAT');
LAT = LAT';
end;
lon = LON(1,:);
lat = LAT(:,1);
end;
if ( ndims(LON) ~= ndims(LAT) || any(size(LON) ~= size(LAT)) )
error('Ecoforecasts:BBox:badargs','If matrices, LON and LAT should be equal-sized');
end;
maxerr_ul = abs(LON(1,1)-LON(2,2)) + abs(LAT(1,1)-LAT(2,2));
maxerr_lr = abs(LON(end-1,end-1)-LON(end,end)) + abs(LAT(end-1,end-1)-LAT(end,end));
maxerr = max(maxerr_ul,maxerr_lr)*sqrt(2);
[err,ix] = min( abs(LON(:)-bbox(1)) + abs(LAT(:)-bbox(3)) );
if (err>maxerr+eps); warning('Ecoforecasts:BBox:badbbox','MINX,MINY may be outside region'); end;
[ixes(1,2),ixes(1,1)] = ind2sub(size(LON),ix);
[err,ix] = min( abs(LON(:)-bbox(2)) + abs(LAT(:)-bbox(3)) );
if (err>maxerr+eps); warning('Ecoforecasts:BBox:badbbox','MAXX,MINY may be outside region'); end;
[ixes(2,2),ixes(2,1)] = ind2sub(size(LON),ix);
[err,ix] = min( abs(LON(:)-bbox(2)) + abs(LAT(:)-bbox(4)) );
if (err>maxerr+eps); warning('Ecoforecasts:BBox:badbbox','MAXX,MAXY may be outside region'); end;
[ixes(3,2),ixes(3,1)] = ind2sub(size(LON),ix);
[err,ix] = min( abs(LON(:)-bbox(1)) + abs(LAT(:)-bbox(4)) );
if (err>maxerr+eps); warning('Ecoforecasts:BBox:badbbox','MINX,MAXY may be outside region'); end;
[ixes(4,2),ixes(4,1)] = ind2sub(size(LON),ix);
return;