-
Notifications
You must be signed in to change notification settings - Fork 3
/
HLI.js
79 lines (71 loc) · 2.72 KB
/
HLI.js
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
var utils = require("users/aazuspan/geeTools:utils.js");
/**
* Calculate McCune and Keon 2002 Heat Load Index (HLI) with corrected coefficients from McCune 2007. This
* implementation follows the R spatialEco library with the addition of per-pixel latitude calculation.
* @param {ee.Image} x An elevation image.
* @param {object} optionalParamters A dictionary of parameters to use in place of default parameters.
* @param {number} optionalParameters.forceLatitude A fixed latitude in degrees to use in HLI calculations. If missing,
* latitudes will be calculated per-pixel.
* @param {string} optionalParameters.forceHemisphere A fixed hemisphere to use in HLI calculations. One of "north" or
* "south". If missing, the hemisphere will be calculated per-pixel based on latitude.
* @return {ee.Image} The McCune and Keon 2002 Heat Load Index.
*/
exports.hli = function (x, optionalParameters) {
var params = {
forceLatitude: null,
forceHemisphere: null,
};
params = utils.updateParameters(params, optionalParameters);
// If a latitude is forced, use the fixed latitude
if (params.forceLatitude) {
try {
var lat = ee.Image.constant(ee.Number(params.forceLatitude));
} catch (err) {
throw (
'Invalid forceLatitude argument "' +
params.forceLatitude +
'". Argument must be a number or missing.'
);
}
}
// Otherwise, use per-pixel latitudes
else {
lat = ee.Image.pixelLonLat().select("latitude");
}
lat = utils.deg2rad(lat);
// If a hemisphere is forced, set the aspect folding coefficient based on the hemisphere
if (params.forceHemisphere) {
var foldCoeffs = { north: 225, south: 315 };
try {
var foldCoeff = ee.Image.constant(
foldCoeffs[params.forceHemisphere.toLowerCase()]
);
} catch (err) {
throw (
'Invalid forceHemisphere argument "' +
params.forceHemisphere +
'". Argument must be "north", "south", or missing.'
);
}
}
// Otherwise, set the aspect folding coefficient based on latitude (N = 225, S = 315)
else {
foldCoeff = ee.Image(225).where(lat.lt(0), 315);
}
var slope = utils.deg2rad(ee.Terrain.slope(x));
// Folded aspect
var aspect = utils.deg2rad(
ee.Terrain.aspect(x).subtract(foldCoeff).abs().multiply(-1).add(180).abs()
);
// Equation from McCune 2002 with corrected coefficients from McCune 2007
var x1 = slope.cos().multiply(lat.cos()).multiply(1.582);
var x2 = slope
.sin()
.multiply(lat.sin())
.multiply(aspect.cos())
.multiply(-1.5);
var x3 = slope.sin().multiply(lat.sin()).multiply(-0.262);
var x4 = slope.sin().multiply(aspect.sin()).multiply(0.607);
var h = x1.add(x2).add(x3).add(x4).add(-1.467).exp().rename("HLI");
return h;
};