Skip to content

Commit cfdd613

Browse files
Merge pull request #348 from azlinszkysinergise/main
Correction of agri growth stage quarterly mosaic custom script
2 parents 3af7e1e + b56597a commit cfdd613

File tree

1 file changed

+40
-36
lines changed

1 file changed

+40
-36
lines changed

sentinel-2/agriculture_growth_stage/quarterly_mosaics.js

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
//VERSION=3 (auto-converted from 1)
22
/*
3-
Source: @HarelDan - https://github.com/hareldunn/GIS_Repo/blob/master/Multi-Temporal%20NDVI%20for%20Sentinel%20Hub%20Custom%20Scripts
4-
Visualizing NDVI multi-temporal trends in Sentinel-2 imagery.
5-
will take the current image as baseline and calculate average NDVI for the previous 2 months
6-
Based on:
7-
https://twitter.com/sentinel_hub/status/922813457145221121
8-
https://twitter.com/sentinel_hub/status/1020755996359225344
3+
Based on Source: @HarelDan - https://github.com/hareldunn/GIS_Repo/blob/master/Multi-Temporal%20NDVI%20for%20Sentinel%20Hub%20Custom%20Scripts
4+
Adapted to visualize NDVI for Sentinel-2 quarterly cloudless mosaics by András Zlinszky using GitHub Copilot.
5+
Each quarter's NDVI is assigned to an RGB channel:
6+
- Red: NDVI for the oldest quarter
7+
- Green: NDVI for the middle quarter
8+
- Blue: NDVI for the most recent quarter
99
Script requires multi-temporal processing so parameter TEMPORAL=true should be added to the request.
1010
*/
1111

12+
// How to use this script:
13+
// Open Copernicus Browser, zoom to your area of interest
14+
// Select Sentinel-2 Quarterly Mosaics
15+
// On the date panel, select Time Range mode (calendar icon with from-to arrows on the right side of the date panel)
16+
// Set the time range - it should be 7 months. This is because the date of a Quarterly Mosaic refers to the first date in the 3 month interval that is used for generating data (https://forum.dataspace.copernicus.eu/t/scenes-getmonth-for-quarterly-mosaics/3045/2?u=andras.zlinszky_education). So eg. if your start date is 2022-01-01 and your end date is 2022-07-01, your are actually looking at images from 2022-01-01 to 2022-09-30
17+
// If it is longer, the algorithm will use only the last 9 months
18+
1219
function setup() {
1320
return {
1421
input: [
@@ -25,50 +32,47 @@ function calcNDVI(sample) {
2532
var denom = sample.B04 + sample.B08;
2633
return denom != 0 ? (sample.B08 - sample.B04) / denom : 0.0;
2734
}
28-
function stretch(val, min, max) {
29-
return (val - min) / (max - min);
30-
}
3135

3236
function evaluatePixel(samples, scenes) {
33-
var avg1 = 0;
34-
var count1 = 0;
35-
var avg2 = 0;
36-
var count2 = 0;
37-
var avg3 = 0;
38-
var count3 = 0;
39-
var endMonth = scenes[0].date.getMonth();
37+
var ndvi1 = 0; // NDVI for the oldest quarter
38+
var ndvi2 = 0; // NDVI for the middle quarter
39+
var ndvi3 = 0; // NDVI for the most recent quarter
40+
41+
// Get the quarter of the most recent scene
42+
var endQuarter = Math.floor(scenes[0].date.getMonth() / 3);
4043

4144
for (var i = 0; i < samples.length; i++) {
4245
var ndvi = calcNDVI(samples[i]);
43-
if (scenes[i].date.getMonth() == endMonth) {
44-
avg3 = avg3 + ndvi;
45-
count3++;
46-
} else if (scenes[i].date.getMonth() == endMonth - 1) {
47-
avg2 = avg2 + ndvi;
48-
count2++;
49-
} else {
50-
avg1 = avg1 + ndvi;
51-
count1++;
46+
var sceneQuarter = Math.floor(scenes[i].date.getMonth() / 3);
47+
48+
if (sceneQuarter == endQuarter) {
49+
ndvi3 = ndvi; // Most recent quarter
50+
} else if (sceneQuarter == endQuarter - 1 || (endQuarter == 0 && sceneQuarter == 3)) {
51+
ndvi2 = ndvi; // Middle quarter
52+
} else if (sceneQuarter == endQuarter - 2 || (endQuarter == 0 && sceneQuarter == 2) || (endQuarter == 1 && sceneQuarter == 3)) {
53+
ndvi1 = ndvi; // Oldest quarter
5254
}
5355
}
54-
avg1 = avg1 / count1;
55-
avg2 = avg2 / count2;
56-
avg3 = avg3 / count3;
57-
avg1 = stretch(avg1, 0.1, 0.7);
58-
avg2 = stretch(avg2, 0.1, 0.7);
59-
avg3 = stretch(avg3, 0.1, 0.7);
6056

61-
return [avg1, avg2, avg3];
57+
// Stretch NDVI values for visualization
58+
ndvi1 = stretch(ndvi1, 0.1, 0.7);
59+
ndvi2 = stretch(ndvi2, 0.1, 0.7);
60+
ndvi3 = stretch(ndvi3, 0.1, 0.7);
61+
62+
return [ndvi1, ndvi2, ndvi3];
63+
}
64+
65+
function stretch(val, min, max) {
66+
return (val - min) / (max - min);
6267
}
6368

6469
function preProcessScenes(collections) {
65-
collections.scenes.orbits = collections.scenes.orbits.filter(function (
66-
orbit
67-
) {
70+
// Filter scenes to include only the last three quarters
71+
collections.scenes.orbits = collections.scenes.orbits.filter(function (orbit) {
6872
var orbitDateFrom = new Date(orbit.dateFrom);
6973
return (
7074
orbitDateFrom.getTime() >=
71-
collections.to.getTime() - 3 * 31 * 24 * 3600 * 1000
75+
collections.to.getTime() - 3 * 3 * 30 * 24 * 3600 * 1000 // Last 9 months
7276
);
7377
});
7478
return collections;

0 commit comments

Comments
 (0)