filterScenes filter by month and year

Hi,
I am trying to filter my scenes according to month and year. like this

return scenes.filter(function(scene) {
return scene.date.getFullYear()>=2017 && scene.date.getMonth()==10;
});

but when I try to filter scenes with month in evaluatePixel function I get an error

Cannot read property ‘date’ of undefined let initMonth = scenes[0].date.getMonth();

but it is working smoothly when only use year filtering. I just want to get specific scenes how can I do that ?

Thanks in advance,

Hi @hasanimgecelik,

I have just been testing your code snippet in one of my Evalscripts and it works just fine for me. If you could provide us with the whole Evalscript, we could try to find out where the error is coming from :slight_smile:

Follow this link to the official documentation of the filterScenes function.

Cheers, Max

Hi Max,

My script is like below. You can change the filter option at the end of the script.

//VERSION=3 (auto-converted from 1)
// Minimum difference between the two mean NDVIs
var thresold = 0.25;
// Thresold to dismiss clouds to calculate the mean
var blueThresold = 0.18;
// Minimum mean NDVI to consider for month(s) of last year
var minimunNDVI = 0.7;
// to normalize colormap
var stretchMin = 0;
var stretchMax = 0.8;

function setup() {
return {
input: [{
bands: [
“B02”,
“B03”,
“B04”,
“B05”,
“B08”,
“B12”
]
}],
output: { bands: 3 },
mosaicking: “ORBIT”
}
}

function stretch(val, min, max) {
return (val - min) / (max - min);
}

function NDVI(sample) {
let denom = sample.B08 + sample.B04;
return ((denom != 0) ? (sample.B08 - sample.B04) / denom : 0.0);
}

function NDWI(sample) {
let denom = sample.B03 + sample.B08;
return ((denom != 0) ? (sample.B03 - sample.B08) / denom : -1);
}

function mean(array) {
if (array.length == 0) {
return 1
} else {
var sum = 0;
for (var i = 0; i < array.length; i++) {
sum += parseFloat(array[i]); //don’t forget to add the base
}

    var avg = sum / array.length;
    return avg
}

}

// Manage overlapping years.
// If january is selected and user need 2 months to take
// script needs to take december from last year as second month.
function getNeededDates(sceneMonth, sceneYear, monthsToTake) {
let monthToGet = [];
let yearToGet = [];

for (i = 0; i < monthsToTake; i++) {
    if (sceneMonth - i <= 0) {
        month = 12 - (sceneMonth - i);
        year = sceneYear - 1;
    } else {
        month = sceneMonth - i;
        year = sceneYear;
    }
    monthToGet.push(month);
    yearToGet.push(year);
}

return [monthToGet, yearToGet];

}

function evaluatePixel(samples, scenes) {
let initMonth = scenes[0].date.getMonth();
let initYear = scenes[0].date.getFullYear();

let monthsAndYears = getNeededDates(initMonth, initYear, 3);

let currentYearNDVI = 0;
let currentYearCount = 0;

let previousYearNDVI = 0;
let previousYearCount = 0;
let lastYearMonth0 = [];
let lastYearMonth1 = [];
let lastYearMonth2 = [];

for (i = 0; i < samples.length; i++) {
    if (!(samples[i].B04 == 0) & !(samples[i].B03 == 0)) {
        sceneMonth = scenes[i].date.getMonth();
        sceneYear = scenes[i].date.getFullYear();
        if (monthsAndYears[0].includes(sceneMonth)) {
            if (samples[i].B02 < blueThresold) {
                ndvi = NDVI(samples[i]);
                if (monthsAndYears[1].includes(sceneYear))
                // if current year (last 12 months max)
                {
                    currentYearNDVI = currentYearNDVI + ndvi;
                    currentYearCount++;

                }
                // if year before
                else if (monthsAndYears[1].includes(sceneYear + 1)) {
                    previousYearNDVI = previousYearNDVI + ndvi;

                    if (monthsAndYears[0][0] == sceneMonth) {
                        lastYearMonth0.push(ndvi);
                    } else if (monthsAndYears[0][1] == sceneMonth) {
                        lastYearMonth1.push(ndvi);
                    } else if (monthsAndYears[0][2] == sceneMonth) {
                        lastYearMonth2.push(ndvi);
                    }
                    previousYearCount++;
                }
            }
        }
    }
}

// compute the mean
let avgCurrentYearNDVI = currentYearNDVI / currentYearCount;
let avgPreviousYearNDVI = previousYearNDVI / previousYearCount;

// if ndvi decreases from defined thresold in the same months from previous year
// highlights in red the pixel
// check also if is not water
let difference = avgPreviousYearNDVI - avgCurrentYearNDVI;

if ((NDWI(samples[0]) < 0.5) & (difference >= thresold) & (avgPreviousYearNDVI > minimunNDVI) & (mean(lastYearMonth0) > minimunNDVI) & (mean(lastYearMonth1) > minimunNDVI) & (mean(lastYearMonth2) > minimunNDVI)) {
    // the more the difference is high, the more it is red
    colorMap = [stretch((2.8 * (2 / 3) * 10 * difference * samples[0].B04 + 0.1 * samples[0].B05), stretchMin, stretchMax), stretch((2.8 * samples[0].B03 + 0.15 * samples[0].B08), stretchMin, stretchMax), stretch((2.8 * samples[0].B02), stretchMin, stretchMax)];
}
// else show current image
else {
    colorMap = [stretch((2.8 * samples[0].B04 + 0.1 * samples[0].B05), stretchMin, stretchMax), stretch((2.8 * samples[0].B03 + 0.15 * samples[0].B08), stretchMin, stretchMax), stretch((2.8 * samples[0].B02), stretchMin, stretchMax)];
}
return colorMap;

}

function filterScenes(scenes, inputMetadata) {

return scenes.filter(function(scene) {
return scene.date.getMonth()==10;
//return scene.date.getFullYear()>=2017;
});
}

Hi @hasanimgecelik,

We checked your script and it works fine if the time range you specify in the request payload coincides with the specified return scene.date.getMonth() or return scene.date.getFullYear() calls you use in the filterScenes function.

Can you confirm that you are requesting images from a time range that covers 2017 or the month of November (or combined)? If the data you request is not containing these dates, the filterScenes function cannot filter and you get an error message.

Hope that helps the troubleshooting :slight_smile:

Hi Max,

You are right when I use year filter when I use script with

  return scenes.filter(function(scene) {
    return scene.date.getFullYear()>=2017;
  });

and make a request like below

http://services.sentinel-hub.com/ogc/fis/{{TOKEN}}?LAYER=ANOMALY_ANALYSIS_V2&TIME=2018-10-08/2020-10-08&RESOLUTION=20&CRS=EPSG:3857&geometry=%20POLYGON%20((4338379.70798844%204435662.11596043,4338513.06873841%204436071.9281716,4338658.2293544%204436000.30395004,4338668.02546959%204435995.56617812,4338658.2293544%204435965.46744128,4338534.77603911%204435585.75691806,4338379.70798844%204435662.11596043))

I get an answer from server.

with the same request when I change the script to this

  return scenes.filter(function(scene) {
    return scene.date.getMonth()=="10";
  });

I get an error but I know there is data at [“2020-10-04”,“2019-10-30”,“2019-10-20”,“2019-10-25”…“2018-10-10”]

Hi @hasanimgecelik,

If you are looking for data from October you’d have to use:

 return scenes.filter(function(scene) {
    return scene.date.getMonth()=="9";
  });

because it is a zero-based indexing system where the index of 0 refers to January and accordingly October would be at index 9.

Cheers, Max

Hi Max,
İ tried the month with 9 but I still get the same error I mentioned before.

Hi @hasanimgecelik,

Your script works completely fine for me. Could you provide the rest of your request so that we can figure out why you are still receiving the error message?

Cheers, Max

Hi Max,
Below I give you full request. It still doesn’t work when I try to filter by month.
I am getting the same error.

https://services.sentinel-hub.com/ogc/fis/e95318f4-e465-4aa4-927b-d42426bf3aa0?LAYER=ANOMALY&geometry=POLYGON((4332578.056858547%204425747.42719139%2C4332578.0532000335%204425747.993574083%2C4332578.156061227%204425748.550550127%2C4332578.361775667%204425749.078266253%2C4332578.663010715%204425749.55791215%2C4332579.04902892%204425749.972390965%2C4332579.506070762%204425750.306928694%2C4332580.017845101%204425750.549600834%2C4332580.566109865%204425750.691757395%2C4332581.131322297%204425750.72833124%2C4332829.417455499%204425743.296945397%2C4332830.019049712%204425743.217541668%2C4332830.592358605%204425743.018701373%2C4332831.113926164%204425742.708559744%2C4332831.562413291%204425742.299805726%2C4332831.919470853%204425741.809162836%2C4332832.170490418%204425741.256704939%2C4332832.305201919%204425740.665034962%2C4332869.441984338%204425439.163443645%2C4332869.457570826%204425438.593122129%2C4332869.364904228%204425438.030163459%2C4332869.167336085%204425437.494928557%2C4332868.872011987%204425437.006775669%2C4332868.489613136%204425436.583360165%2C4332868.033970032%204425436.239996032%2C4332867.52156225%204425435.989101963%2C4332866.970922417%204425435.839752236%2C4332866.4019659255%204425435.797348482%2C4332611.749618756%204425441.105455184%2C4332611.134531251%204425441.1823307155%2C4332610.548373257%204425441.383977166%2C4332610.016169973%204425441.701785517%2C4332609.560643077%204425442.12218739%2C4332609.201240659%204425442.627234305%2C4332608.953306903%204425443.19536399%2C4332608.827426998%204425443.802320934%2C4332578.056858547%204425747.42719139))&srs=EPSG%3A3857&time=2020-10-07&RESX=10&RESY=10