I am trying to retrieve monthly Sentinel-2 band data using zonal statistics (mean) and point buffer for further analysis.
I have created monthly median composites from January to December of 2017 using the .map function. However, when I call the variable "S2A" (which has the monthly composites), I get an error which says that S2A is not defined. I tried printing the S2A variable, and I realise that it has 12 monthly images with no properties.
I want S2A as an image collection with properties like band names, band values and system time properties.
My code is below:
// Year
var year = 2017;
// List of months parameter
// Name is the name of the month
// End is the last day of the month
var months = [
{ name: 'January', end: 31 },
{ name: 'February', end: 28 },
{ name: 'March', end: 31 },
{ name: 'April', end: 30 },
{ name: 'May', end: 31 },
{ name: 'June', end: 30 },
{ name: 'July', end: 31 },
{ name: 'August', end: 31 },
{ name: 'September', end: 30 },
{ name: 'October', end: 31 },
{ name: 'November', end: 30 },
{ name: 'December', end: 31 }
];
// Composite and export per months
months.map(function(month, index){
// Name of the image
var name = year + '_' + month.name;
// Create start and end date from the composite
var start = ee.Date.fromYMD(year, index + 1, 1);
var end = ee.Date.fromYMD(year, index + 1, month.end);
// https://geetools.readthedocs.io/en/latest/cloud_mask.html (Documentation)
// For Shumaila Mam
// SIAC atmospheric correction module
var siac = require('users/marcyinfeng/utils:SIAC');
// Hollstein cloud mask module
var cld = require('users/fitoprincipe/geetools:cloud_masks')
var S2A = ee.ImageCollection('COPERNICUS/S2_HARMONIZED')
.filterDate(start, end)
// Pre-filter to get less cloudy granules.
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 30))
.filterBounds(Ethiopia)
// Apply cloud-masking to each image
.map(cld.hollstein_S2(['shadow','cloud', 'cirrus']))
// Apply SIAC to each image
.map(siac.get_sur)
// Combine all masked, corrected images with a median
.median()
//.divide(10000);
Map.addLayer(S2A,{bands:"B4,B3,B2", min: 0.0, max: 0.3, gamma: 1.4},name, false)
Map.centerObject(S2A)
});
Map.addLayer(Points, {}, 'Points', false)
Map.centerObject(Ethiopia,6)
function zonalStats(ic, fc, params) {
// Initialize internal params dictionary.
var _params = {
reducer: ee.Reducer.mean(),
scale: null,
crs: null,
bands: [null],
imgProps: null,
imgPropsRename: null,
datetimeName: 'datetime',
datetimeFormat: 'YYYY-MM-dd HH:mm:ss'
};
// Replace initialized params with provided params.
if (params) {
for (var param in params) {
_params[param] = params[param] || _params[param];
}
}
// Set default parameters based on an image representative.
var imgRep = ic.first();
var nonSystemImgProps = ee.Feature(null)
.copyProperties(imgRep).propertyNames();
if (!_params.bands) _params.bands = imgRep.bandNames();
if (!_params.bandsRename) _params.bandsRename = _params.bands;
if (!_params.imgProps) _params.imgProps = nonSystemImgProps;
if (!_params.imgPropsRename) _params.imgPropsRename = _params.imgProps;
// Map the reduceRegions function over the image collection.
var results = ic.map(function(img) {
// Select bands (optionally rename), set a datetime & timestamp property.
img = ee.Image(img.select(_params.bands, _params.bandsRename))
.set(_params.datetimeName, img.date().format(_params.datetimeFormat))
.set('timestamp', img.get('system:time_start'));
// Define final image property dictionary to set in output features.
var propsFrom = ee.List(_params.imgProps)
.cat(ee.List([_params.datetimeName, 'timestamp']));
var propsTo = ee.List(_params.imgPropsRename)
.cat(ee.List([_params.datetimeName, 'timestamp']));
var imgProps = img.toDictionary(propsFrom).rename(propsFrom, propsTo);
// Subset points that intersect the given image.
var fcSub = fc.filterBounds(img.geometry());
// Reduce the image by regions.
return img.reduceRegions({
collection: fcSub,
reducer: _params.reducer,
scale: _params.scale,
crs: _params.crs
})
// Add metadata to each feature.
.map(function(f) {
return f.set(imgProps);
});
}).flatten().filter(ee.Filter.notNull(_params.bandsRename));
return results;
}
//Define parameters for the zonalStats function.
var params = {
collection:Points,
reducer: ee.Reducer.mean(),
scale: 60,
//crs: 'EPSG:5070',
bands: [0, 1,2,3,4,5,6,7,8,9,10,11,12,13],
bandsRename:['B1','B2', 'B3','B4','B5','B6','B7','B8','B8A','B11','B12','aot','tcwv','tco3'],
};
// Extract zonal statistics per point per image.
var ptsTopoStats = zonalStats(S2A, points, params);
print(ptsTopoStats);
Map.addLayer(ptsTopoStats)
Export.table.toDrive({
collection: ptsTopoStats,
folder: 'Etse_sent_1',
description: 'S1_2018',
fileFormat: 'CSV'
});