I have code that calculates NDVI, then calculate statistics inside a dictionary and then based on statistics calculte 3 layers that later on mosaiced. The problem is that for some reason I get this error:
range map: Layer error: Number.divide: Parameter 'left' is required.
I have read the debugging guide but I saw that this error might happen if I don't print the dictionary, but in my case I have had, so I don't know how to fix it.
This is the relevant part of my code:
//********try to create table with all the polygon stistics data***
//*******Results: print table similar, relates to all the polygon as one***
var tableWithStats = MyImage.reduceRegions({
collection: geometry,
reducer: ee.Reducer.mean().combine({
reducer2: ee.Reducer.stdDev(),
sharedInputs: true
}),
scale: 20
});
print(tableWithStats);
//***end of trial of print the statistics******
var std2 = ee.Number(tableWithStats.get("NDVI")).divide(2);
var mean1 = ee.Number(tableWithStats.get("NDVI"));
// the classes borders
var negBorder=mean1.subtract(std2);
var posBorder=mean1.add(std2);
//create the layers
var imageNDVI=MyImage.select('NDVI');
var gtPOS=MyImage.gt(posBorder).selfMask().rename('range');
var ltNEG=MyImage.lt(negBorder).selfMask().rename('range');
var betMEAN=MyImage.gt(negBorder).and(imageNDVI.lt(posBorder)).selfMask().rename('range');
var ndviClassCol = ee.ImageCollection.fromImages([ltNEG,betMEAN, gtPOS]);
// Mosaic the ImageCollection.
var ndviClassImg = ndviClassCol.mosaic();
// // Display the classified mosaic to the Map.
// Map.centerObject(geometry, 8);
Map.addLayer(ndviClassImg, {palette: ['blue', 'orange', 'green'], min: 0, max: 3},' map');
The code works if I run everything beside the addLayer part in the end.
how can I solve this?
EDIT: I'm adding here the full code:
/**
* Function to mask clouds using the Sentinel-2 QA band
* @param {ee.Image} image Sentinel-2 image
* @return {ee.Image} cloud masked Sentinel-2 image
*/
function maskS2clouds(image) {
var qa = image.select('QA60');
// Bits 10 and 11 are clouds and cirrus, respectively.
var cloudBitMask = 1 << 10;
var cirrusBitMask = 1 << 11;
// Both flags should be set to zero, indicating clear conditions.
var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
.and(qa.bitwiseAnd(cirrusBitMask).eq(0));
return image.updateMask(mask).divide(10000)
.copyProperties(image, ['system:time_start']);
}
// Map the function over one year of data and take the median.
// Load Sentinel-2 TOA reflectance data.
var dataset = ee.ImageCollection('COPERNICUS/S2')
.filterDate('2019-05-25','2020-01-06')
// Pre-filter to get less cloudy granules.
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
.select('B1','B2','B3','B4','B8','QA60')
.filterBounds(geometry)
.map(maskS2clouds);
var rgbVis = {
min: 0.0,
max: 0.3,
bands: ['B4', 'B3', 'B2'],
};
var count=dataset.size();
print(count);
var clippedCol=dataset.map(function(im){
return im.clip(geometry);
});
//test if clipping the image collection worked
Map.centerObject(geometry,9);
Map.addLayer(clippedCol.first(), rgbVis, 'RGB');
//function to calculate NDVI
var addNDVI = function(image) {
var ndvi = image.normalizedDifference(['B8', 'B4'])
.rename('NDVI')
.copyProperties(image,['system:time_start']);
return image.addBands(ndvi);
};
//NDVI to the clipped image collection
var withNDVI = clippedCol.map(addNDVI).select('NDVI');
var colorizedVis = {
min: 0.0,
max: 1.0,
palette: [
'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901',
'66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01',
'012E01', '011D01', '011301'
],
};
//var ListImage=withNDVI.toList(withNDVI.size());
var listOfImages =(withNDVI.toList(withNDVI.size()));
var NumberOfImages=listOfImages.size();
print('number of images',NumberOfImages);
////////select the first image///////////
var MyImage=ee.Image(withNDVI.first());
print(MyImage);
// // Map.addLayer(MyImage,colorizedVis,'ndvi');
//********try to create table with all the polygon stistics data***
//*******Results: print table similar, relates to all the polygon as one***
var tableWithStats = MyImage.reduceRegions({
collection: geometry,
reducer: ee.Reducer.mean().combine({
reducer2: ee.Reducer.stdDev(),
sharedInputs: true
}),
scale: 20
});
print(tableWithStats);
var std2 = ee.Number(tableWithStats.get("NDVI")).divide(2);
var mean1 = ee.Number(tableWithStats.get("NDVI"));
print(mean1);
print(std2);
// the classes borders
var negBorder=mean1.subtract(std2);
var posBorder=mean1.add(std2);
//create the layers
var imageNDVI=MyImage.select('NDVI');
var gtPOS=MyImage.gt(posBorder).selfMask().rename('range');
var ltNEG=MyImage.lt(negBorder).selfMask().rename('range');
var betMEAN=MyImage.gt(negBorder).and(imageNDVI.lt(posBorder)).selfMask().rename('range');
var ndviClassCol = ee.ImageCollection.fromImages([ltNEG,betMEAN, gtPOS]);
// Mosaic the ImageCollection.
var ndviClassImg = ndviClassCol.mosaic();
// // Display the classified mosaic to the Map.
// Map.centerObject(geometry, 8);
Map.addLayer(ndviClassImg, {palette: ['blue', 'orange', 'green'], min: 0, max: 1},'range map');
MyImage
has no band namedNDVI
, but we can't be sure since you haven't included the definition ofMyImage
. Please include a code sample that is complete enough to run. (Also, about "The code works if I run everything beside the addLayer part in the end" — if you don't addLayer then you haven't actually run the computation, just defined it, so it's expected that errors won't show up there. When trying to remove things to simplify the problem, you need to always have aprint
oraddLayer
, but with a simpler input to it.)