Created
September 2, 2020 13:26
-
-
Save maximlamare/b26e9662a21b145c28071d8da6665796 to your computer and use it in GitHub Desktop.
Evalscript replacing EOLearn import tasks with Batch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//VERSION=3 | |
// Calculate number of bands needed for all intervals | |
// Initialise dates and interval | |
// Beware: in JS months are 0 indexed | |
var start_date = new Date(2019, 3, 1, 0, 0, 0); | |
var end_date = new Date(2019, 9, 31, 0, 0, 0); | |
var sampled_dates = sample_timestamps(start_date, end_date, 15, 'day').map(d => withoutTime(d)); | |
var nb_bands = sampled_dates.length; | |
var n_valid = 0; | |
var n_all = 0; | |
function interval_search(x, arr) { | |
let start_idx = 0, end_idx = arr.length - 2; | |
// Iterate while start not meets end | |
while (start_idx <= end_idx) { | |
// Find the mid index | |
let mid_idx = (start_idx + end_idx) >> 1; | |
// If element is present at mid, return True | |
if (arr[mid_idx] <= x && x < arr[mid_idx + 1]) { | |
return mid_idx; | |
} | |
// Else look in left or right half accordingly | |
else if (arr[mid_idx + 1] <= x) start_idx = mid_idx + 1; | |
else end_idx = mid_idx - 1; | |
} | |
if (x == arr[arr.length-1]){ | |
return arr.length-2; | |
} | |
return undefined; | |
} | |
function linearInterpolation(x, x0, y0, x1, y1, no_data_value=NaN) { | |
if (x < x0 || x > x1) { | |
return no_data_value; | |
} | |
var a = (y1 - y0) / (x1 - x0); | |
var b = -a * x0 + y0; | |
return a * x + b; | |
} | |
function lininterp(x_arr, xp_arr, fp_arr, no_data_value=NaN) { | |
results = []; | |
data_mask = []; | |
xp_arr_idx = 0; | |
for(var i=0; i<x_arr.length; i++){ | |
var x = x_arr[i]; | |
n_all+=1; | |
interval = interval_search(x, xp_arr); | |
if (interval === undefined) { | |
data_mask.push(0); | |
results.push(no_data_value); | |
continue; | |
} | |
data_mask.push(1); | |
n_valid+=1; | |
results.push( | |
linearInterpolation( | |
x, | |
xp_arr[interval], | |
fp_arr[interval], | |
xp_arr[interval+1], | |
fp_arr[interval+1], | |
no_data_value | |
) | |
); | |
} | |
return [results, data_mask]; | |
} | |
function interpolated_index(index_a, index_b){ | |
// Calculates the index for all bands in array | |
var index_data = []; | |
for (var i = 0; i < index_a.length; i++){ | |
// UINT index returned | |
let ind = (index_a[i] - index_b[i]) / (index_a[i] + index_b[i]); | |
index_data.push(ind * 10000 + 10000); | |
} | |
return index_data | |
} | |
function increase(original_date, period, period_unit){ | |
date = new Date(original_date) | |
switch(period_unit){ | |
case 'millisecond': | |
return new Date(date.setMilliseconds(date.getMilliseconds()+period)); | |
case 'second': | |
return new Date(date.setSeconds(date.getSeconds()+period)); | |
case 'minute': | |
return new Date(date.setMinutes(date.getMinutes()+period)); | |
case 'hour': | |
return new Date(date.setHours(date.getHours()+period)); | |
case 'day': | |
return new Date(date.setDate(date.getDate()+period)); | |
case 'month': | |
return new Date(date.setMonth(date.getMonth()+period)); | |
default: | |
return undefined | |
} | |
} | |
function sample_timestamps(start, end, period, period_unit) { | |
var cDate = new Date(start); | |
var sampled_dates = [] | |
while (cDate < end) { | |
sampled_dates.push(cDate); | |
cDate = increase(cDate, period, period_unit); | |
} | |
return sampled_dates; | |
} | |
function is_valid(smp){ | |
// Check if the sample is valid (i.e. contains no clouds or snow) | |
let clm = smp.CLM; | |
let dm = smp.dataMask; | |
if (clm === 1 || clm === 255) { | |
return false; | |
} else if (dm !=1 ) { | |
return false; | |
} else { | |
return true; | |
} | |
} | |
function withoutTime(intime){ | |
// Return date without time | |
intime.setHours(0, 0, 0, 0); | |
return intime; | |
} | |
// Sentinel Hub functions | |
function setup() { | |
// Setup input/output parameters | |
return { | |
input: [{ | |
bands: ["B02", "B03", "B04", "B08", "B11", "B12", "CLM", "dataMask"], | |
units: "DN" | |
}], | |
output: [ | |
{id: "B02", bands: nb_bands, sampleType: SampleType.UINT16}, | |
{id: "B03", bands: nb_bands, sampleType: SampleType.UINT16}, | |
{id: "B04", bands: nb_bands, sampleType: SampleType.UINT16}, | |
{id: "B08", bands: nb_bands, sampleType: SampleType.UINT16}, | |
{id: "B11", bands: nb_bands, sampleType: SampleType.UINT16}, | |
{id: "B12", bands: nb_bands, sampleType: SampleType.UINT16}, | |
{id: "NDVI", bands: nb_bands, sampleType: SampleType.UINT16}, | |
{id: "NDWI", bands: nb_bands, sampleType: SampleType.UINT16}, | |
{id: "NDBI", bands: nb_bands, sampleType: SampleType.UINT16}, | |
{id: "data_mask", bands: nb_bands, sampleType: SampleType.UINT8} | |
], | |
mosaicking: "ORBIT" | |
} | |
} | |
// Evaluate pixels in the bands | |
function evaluatePixel(samples, scenes) { | |
// Initialise arrays | |
var valid_samples = {'B02':[], 'B03':[], 'B04':[], 'B08':[], 'B11':[], 'B12':[]}; | |
var valid_dates = [] | |
// Loop over samples. | |
for (var i = samples.length-1; i >= 0; i--){ | |
if (is_valid(samples[i])) { | |
valid_dates.push(withoutTime(new Date(scenes[i].date))); | |
valid_samples['B02'].push(samples[i].B02); | |
valid_samples['B03'].push(samples[i].B03); | |
valid_samples['B04'].push(samples[i].B04); | |
valid_samples['B08'].push(samples[i].B08); | |
valid_samples['B11'].push(samples[i].B11); | |
valid_samples['B12'].push(samples[i].B12); | |
} | |
} | |
var [b02_interpolated, b02_dm] = lininterp(sampled_dates, valid_dates, valid_samples['B02'], 0); | |
var [b03_interpolated, b03_dm] = lininterp(sampled_dates, valid_dates, valid_samples['B03'], 0); | |
var [b04_interpolated, b04_dm] = lininterp(sampled_dates, valid_dates, valid_samples['B04'], 0); | |
var [b08_interpolated, b08_dm] = lininterp(sampled_dates, valid_dates, valid_samples['B08'], 0); | |
var [b11_interpolated, b11_dm] = lininterp(sampled_dates, valid_dates, valid_samples['B11'], 0); | |
var [b12_interpolated, b12_dm] = lininterp(sampled_dates, valid_dates, valid_samples['B12'], 0); | |
// Calculate indices and return optimised for UINT16 format (will need unpacking) | |
var ndvi = interpolated_index(b08_interpolated, b04_interpolated); | |
var ndwi = interpolated_index(b03_interpolated, b08_interpolated); | |
var ndbi = interpolated_index(b11_interpolated, b08_interpolated); | |
// Return all arrays | |
return { | |
B02: b02_interpolated, | |
B03: b03_interpolated, | |
B04: b04_interpolated, | |
B08: b08_interpolated, | |
B11: b11_interpolated, | |
B12: b12_interpolated, | |
NDVI: ndvi, | |
NDWI: ndwi, | |
NDBI: ndbi, | |
data_mask: b02_dm | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment