Description: The code below contains a function that calculates the least required days for Sentinel 2 image collection to cover at least 99% of a given area of interest (aoi). In other words, Sentinel 2 can fully cover small areas with image collection filtered with 1 day only. If an area is relatively large then image collections need to be gathered from more than 1 day and then mosaiced.
Problem:
The function works as expected ,however, it freezes the web browser because it uses .getInfo()
command inside it. Specifically at var c = data1.size().getInfo()
line located near the end of the code.
Requirement: I would like to find an alternative to this command, so that the function won't freeze the web browser. I believe the solution is by converting the whole function to server-side, but I couldn't achieve that.
Failed solutions:
- I've tried using
.evaluate()
instead of.getInfo()
, and it didn't work. - I've tried to reconstruct the whole function by using
.map
instead ofwhile
loop. It also didn't work.
The Code:
var Iraq = ee.FeatureCollection("users/Yousif_Almamalachy/Iraq_Governorates");
var Gov_name = 'ANBAR'
var aoi = Iraq.filter(ee.Filter.eq("NAME_GOVER", Gov_name));
print(CdaysCheck(aoi))
function CdaysCheck(aoii){
var stoper = false;
var i = 1;
while (i) {
var sentinel = ee.ImageCollection("COPERNICUS/S2_SR");
var aoi = aoii;
var sStart_Date = ee.Date(Date.now()).advance(-1,'month')
var eEnd_Date = ee.Date(Date.now())
var aAllowed_Cloud = 100
var Minimum_Areal_Coverage = 0.99
var cCoverage_Days = i
var data = sentinel.filterBounds(aoi).filterDate(sStart_Date,eEnd_Date)
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', aAllowed_Cloud));
var sscale=data.first().select('B1').projection().nominalScale().getInfo()
var polygon_area;
// if (definedmode.getValue() == 1)
polygon_area = aoi.geometry().area().divide(1e6)
// else{polygon_area = aoi.area().divide(1e6)}
var minimum_area = ee.Number(polygon_area).multiply(Minimum_Areal_Coverage)
// Get the dates of filtered images with less than specified cloud percentage
var dates = data
.map(function(image) {
return ee.Feature(null, {'date': image.date().format('YYYY-MM-dd')})
})
//.distinct('date')
.aggregate_array('date')
// Filter Images that doesn't contain all bands
var data = data.map(function(n) {
return n.set('Num_of_bands',n.bandNames().length());
})
data = data.filterMetadata("Num_of_bands","equals",23);
// Mosaic images of the same date and calculate its average cloud cover
var dd = ee.ImageCollection(
ee.List(dates.distinct()).map(function (n) {
var date = ee.Date(n)
var filtered = data.filterDate(date, date.advance(cCoverage_Days,'day'))
var image = ee.Image(filtered.mosaic())
return image.set({'date':n})
}));
// Filter Images that doesn't cover polygon area (raster area calculation method)
var data1 = dd.map(function(n) {
var data = ee.Image(1).mask(n.select('B1'))
var raster_area = data.multiply(ee.Image.pixelArea()).reduceRegion({
reducer: ee.Reducer.sum(),
geometry: aoi,
scale: sscale,
maxPixels: 1E13
}).get('constant')
raster_area=ee.Number(raster_area).divide(1e6)
return n.set('Area_KM2',raster_area)
})
data1 = data1.filterMetadata("Area_KM2","greater_than",ee.Number(minimum_area));
var c = data1.size().getInfo()
if (c !== 0)
{break}
i += 1
}
return ee.String(i.toString())
}