forked from sentinel-hub/custom-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscript.js
executable file
·174 lines (149 loc) · 4.76 KB
/
script.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
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
//VERSION=3 (auto-converted from 1)
/*
Author: Karasiak Nicolas
*/
// Put 3 to have synthesis of the last 90 days
var numberOfMonthsToUse = 1;
// Thresold to consider pixel as snow
var NDSIthresold = 0.2;
// In order to dismiss snow from water
var redThresold = 0.2;
// In order to dismiss clouds
var blueThresold = 0.12;
var highBlueThresold = 0.45;
var numberOfTimesForWater = 2; // minimum number of times to identify as water
var stretchMin = 0;
var stretchMax = 1;
function setup() {
return {
input: [{
bands: [
"B02",
"B03",
"B04",
"B05",
"B08",
"B11"
]
}],
output: { bands: 3 },
mosaicking: "ORBIT"
}
}
function NDSI(sample) {
return ((sample.B03 - sample.B11) / (0.01 + sample.B03 + sample.B11));
}
function NDWI(sample) {
return ((sample.B03 - sample.B08) / (sample.B03 + sample.B08));
}
function median(values) {
// from https://stackoverflow.com/questions/45309447/calculating-median-javascript
if (values.length === 0) return 0;
if (values.length === 1) return values[0];
values.sort(function(a, b) {
return a - b;
});
var half = Math.floor(values.length / 2);
return values[half];
}
function r(a, b) {
return (a / b);
}
function stretch(val, min, max) {
return (val - min) / (max - min);
}
function indexOfMaxRatio(a, b) {
ratios = [];
for (i = 0; i < a.length; i++) {
ratios.push(r(a[i], b[i]));
}
if (ratios.length === 0) {
return -1;
}
var max = ratios[0];
var maxIndex = 0;
for (var i = 1; i < ratios.length; i++) {
if (ratios[i] > max) {
maxIndex = i;
max = ratios[i];
}
}
return maxIndex;
}
function evaluatePixel(samples, scenes) {
// for snow scene
let snowyCount = 0;
let snowB02 = [];
let snowB03 = [];
let snowB04 = [];
// for unsnow scene
let B02 = [];
let B03 = [];
let B04 = [];
let B05 = [];
let B08 = [];
// for high blue scenes
let highB02 = [];
let highB03 = [];
let highB04 = [];
let highB05 = [];
let highB08 = [];
// isWater
let isWater = 0;
// to manage image length between tiles
let realSampleLength = 0;
for (i = 0; i < samples.length; i++) {
// in order to avoid black pixel (the ones between tiles)
if ((samples[i].B02 > 0) & (samples[i].B03 > 0)) {
realSampleLength++;
if (samples[i].B02 < blueThresold) {
B02.push(samples[i].B02);
B03.push(samples[i].B03);
B04.push(samples[i].B04);
B05.push(samples[i].B05);
B08.push(samples[i].B08);
} else if ((samples[i].B02 < highBlueThresold) & (samples[i].B02 > blueThresold)) {
highB02.push(samples[i].B02);
highB03.push(samples[i].B03);
highB04.push(samples[i].B04);
highB05.push(samples[i].B05);
highB08.push(samples[i].B08);
}
if ((NDSI(samples[i]) > NDSIthresold) & (samples[i].B04 > redThresold)) {
snowyCount++;
snowB02.push(samples[i].B02);
snowB03.push(samples[i].B03);
snowB04.push(samples[i].B04);
}
if ((samples[i].B02 < blueThresold) & (NDWI(samples[i]) > 0)) {
isWater++;
}
}
}
if ((B02.length > 0)) {
if (isWater > 2) {
bestRatio = indexOfMaxRatio(B02, B08);
} else {
bestRatio = indexOfMaxRatio(B08, B03);
}
colorMap = [stretch((2.8 * B04[bestRatio] + 0.1 * B05[bestRatio]), stretchMin, stretchMax), stretch((2.8 * B03[bestRatio] + 0.15 * B08[bestRatio]), stretchMin, stretchMax), stretch((2.8 * B02[bestRatio]), stretchMin, stretchMax)];
} else if ((highB02.length > 0) & (B02.length < 1)) {
if (isWater > 2) {
bestRatio = indexOfMaxRatio(B02, B08);
} else {
bestRatio = indexOfMaxRatio(highB03, highB02);
}
colorMap = [stretch((2.8 * highB04[bestRatio] + 0.1 * highB05[bestRatio]), stretchMin, stretchMax), stretch((2.8 * highB03[bestRatio] + 0.15 * highB08[bestRatio]), stretchMin, stretchMax), stretch((2.8 * highB02[bestRatio]), stretchMin, stretchMax)];
} else if ((snowyCount > 0) & (highB02.length < 1) & (B02.length < 1)) {
// snowColorMap
colorMap = [1.1 * median(snowB04), 1.3 * median(snowB03), 1.1 * median(snowB02)];
} else {
colorMap = [1, 0, 0];
}
return colorMap;
}
function filterScenes(scenes, inputMetadata) {
return scenes.filter(function(scene) {
return scene.date.getTime() >= (inputMetadata.to.getTime() - (numberOfMonthsToUse * 31 * 24 * 3600 * 1000));
});
}