-
Notifications
You must be signed in to change notification settings - Fork 58
/
arcslope.m
90 lines (79 loc) · 2 KB
/
arcslope.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 SLP = arcslope(DEM,unit)
%ARCSLOPE mean gradient from a digital elevation model sensu ArcGIS
%
% Syntax
%
% SLP = arcslope(DEM)
% SLP = arcslope(DEM,unit)
%
% Description
%
% ARCSLOPE returns the gradient as calculated by ArcGIS (mean slope of
% 8 connected neighborhood). Default unit is as tangent, but you can
% specify alternative units identical to gradient8 function.
%
% Input
%
% DEM digital elevation model (class: GRIDobj)
% unit 'tan' --> tangent (default)
% 'rad' --> radian
% 'deg' --> degree
% 'sin' --> sine
% 'per' --> percent
%
% Output
%
% SLP mean gradient (class: GRIDobj)
%
% Example
%
% DEM = GRIDobj('srtm_bigtujunga30m_utm11.tif');
% SLP = arcslope(DEM);
% imageschs(DEM,SLP);
%
% See also: GRIDobj/gradient8
%
% Author: Wolfgang Schwanghart (w.schwanghart[at]geo.uni-potsdam.de) and
% Adam M. Forte (aforte[a]asu.edu)
% Date: 6. February, 2017
z=DEM.Z;
% Pad array to avoid edge effects
zp=padarray(z,[1 1],'replicate');
% Handle nans
I = isnan(zp);
in = any(I(:));
if in
[~,L] = bwdist(~I);
zp = zp(L);
end
% Define anon function to calculate the mean gradient of 8 connected neighborhood
% by same algorithm as the ArcGIS slope function
kernel = [ -1 -2 -1; 0 0 0; 1 2 1]';
rr = sqrt((conv2(zp,kernel','valid')./(8*DEM.cellsize)).^2 + ...
(conv2(zp,kernel,'valid')./(8*DEM.cellsize)).^2);
% Package output
if nargin == 1
unit = 'tangent';
else
unit = validatestring(unit,{'tangent' 'degree' 'radian' 'percent' 'sine'},'gradient8','unit',2);
end
if in
rr(I(2:end-1,2:end-1)) = nan;
end
% create a copy of the DEM instance
SLP = DEM;
SLP.name = 'slope (arcgis)';
SLP.zunit = unit;
SLP.Z=rr;
switch unit
case 'tangent'
% do nothing
case 'degree'
SLP.Z = atand(SLP.Z);
case 'radian'
SLP.Z = atan(SLP.Z);
case 'sine'
SLP.Z = sin(atan(SLP.Z));
case 'percent'
SLP.Z = SLP.Z*100;
end