-
Notifications
You must be signed in to change notification settings - Fork 110
/
castshadow.m
executable file
·89 lines (74 loc) · 2.2 KB
/
castshadow.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
function SH = castshadow(DEM,varargin)
%CASTSHADOW cast shadow
%
% Syntax
%
% SH = castshadow(DEM,azid,altd)
%
% Description
%
% castshadow calculates the shadow created on a form next to a surface
% that is turned away from the source of light.
%
% Input arguments
%
% DEM digital elevation model (class: GRIDobj)
% azid azimuth angle in degrees of light source (clockwise from top)
% altd elevation angle in degrees of light source above horizon
%
% Output arguments
%
% SH values between 0 and 1 with values of 1 indicating shadowed
% and 0 indicating non-shadowed areas. Values between 0 and 1
% can be interpreted to indicate a degree of shadowing.
%
% Example
%
% DEM = GRIDobj('srtm_bigtujunga30m_utm11.tif');
% C = castshadow(DEM,135,20);
% imageschs(DEM,C,'colormap',flipud(gray))
%
%
% See also: GRIDobj/imageschs, GRIDobj/hillshade
%
% Author: Wolfgang Schwanghart (w.schwanghart[at]geo.uni-potsdam.de)
% Date: 17. August, 2017
p = inputParser;
p.FunctionName = 'GRIDobj/castshadow';
addRequired(p,'DEM', @(x) isa(x,'GRIDobj'));
addOptional(p,'azid', 180);
addOptional(p,'altd', 45);
parse(p,DEM,varargin{:});
azid = mod(-p.Results.azid,360);
% force values in the DEM to be larger than zero
% because imrotate fills loose image ends with zeros
DEM.Z = - min(DEM.Z(:)) + DEM.Z + 1;
%
% affine transformation matrix
A = [cosd(azid) sind(azid); ...
-sind(azid) cosd(azid)];
A(3,3) = 1;
% tform = affine2d(A);
tform = maketform('affine',A);
% image transformation
[demr,xdata,ydata] = imtransform(DEM.Z,tform,'bilinear',...
'Udata',[1 DEM.size(2)],'Vdata',[1 DEM.size(1)]);
% calculate height of sunbeams
lowering = DEM.cellsize*tand(p.Results.altd);
demrcopy = demr;
for r = 2:size(demr,1)
demr(r,:) = max(demr(r-1,:) - lowering,demr(r,:)).*(demr(r,:)>0);
end
demr = single(demr>demrcopy);
% backtransform image
azid = -azid;
A = [cosd(azid) sind(azid); ...
-sind(azid) cosd(azid)];
A(3,3) = 1;
demr = imtransform(demr,maketform('affine',A),'bilinear',...
'Udata',xdata,'Vdata',ydata,...
'xdata',[1 DEM.size(2)],'ydata',[1 DEM.size(1)],...
'Size',DEM.size);
% write to GRIDobj
SH = DEM;
SH.Z = demr;