0

I am working on calculating NDVI values for both SEN2 and SEN3 from the same time frame and storing the results on my Google Drive. I have a feature collection called "region" which is an assemble of 4 fields (polygons) and is imported from my assets.

I run this code to compute and save NDVI values for each field and for both SEN2 and SEN3 but I am unable to save the outputs as the task cannot be complete due to this error:

Error: Collection.geometry, argument 'collection': Invalid type. Expected type: FeatureCollection. Actual type: Feature.

This is the code:

//define all AOI
var field1 = ee.FeatureCollection(region.filterMetadata("system:index","equals","00000000000000000000").first());
var field2 = ee.FeatureCollection(region.filterMetadata("system:index","equals","00000000000000000001").first());
var field3 = ee.FeatureCollection(region.filterMetadata("system:index","equals","00000000000000000002").first());
var field4 = ee.FeatureCollection(region.filterMetadata("system:index","equals","00000000000000000003").first());
var fields = [field1, field2, field3, field4];

//Get the ndvi for the specific field and time
function get_ndvi_sen2(region, startdate, enddate){
  region = ee.FeatureCollection(region)
  var ndvi_s2 = ee.ImageCollection('COPERNICUS/S2_SR')
    .filterDate(startdate, enddate)
    .map(function (image) {
      return image
        .clipToCollection(region)
        .normalizedDifference(['B8', 'B4'])
        .updateMask(image.select('QA60').not());
    })
    .median()
    .rename('ndvi_s2');

  var ndvi_s2_Features = ee.FeatureCollection(ee.List(ndvi_s2
  .reduceRegion({
    reducer: ee.Reducer.toList(),
    geometry: region,
    scale: 10
  })
  .get('ndvi_s2'))
  .map(function (ndvi_s2) {
    return ee.Feature(null, {ndvi_s2: ndvi_s2});
  })
  );
  return ndvi_s2_Features;
}
function get_ndvi_sen3(region, startdate, enddate){
  var SEN3 = ee.ImageCollection('COPERNICUS/S3/OLCI')
                    .filterDate(startdate, enddate);

  // Select bands for NDVI and apply band-specific scale factors.
  var SEN_corr = SEN3.select(['Oa17_radiance', 'Oa08_radiance'])
                .median()
                // Convert to radiance units.
                .divide(ee.Image([0.00493004, 0.00876539]));
  region = ee.FeatureCollection(region)
  var ndviSEN3 = SEN_corr
        .clipToCollection(region)
        .normalizedDifference(['Oa17_radiance', 'Oa08_radiance'])
        .rename('ndviSEN3');

  var ndviFeatures = ee.FeatureCollection(ee.List(ndviSEN3
    .reduceRegion({
      reducer: ee.Reducer.toList(),
      geometry: region,
      scale: 10
    })
    .get('ndviSEN3'))
    .map(function (ndviSEN3) {
      return ee.Feature(null, {ndviSEN3: ndviSEN3});
    })
  );
  return ndviFeatures;
}
function write_to_drive(col, disc, selc, folder){
  Export.table.toDrive({
    collection: col,
    description: disc,
    selectors: selc,
    folder: folder
  })
}

var start = '2019-03-1'
var end = '2019-04-01'
var sen2_disc, sen2_selc = 'ndvi_s2';
var sen3_disc, sen3_selc = 'ndviSEN3';
var sen2_folder = 'GOOD/SEN2'
var sen3_folder = 'GOOD/SEN3'

for (var i in fields){
  var sen2_loop = get_ndvi_sen2(fields[i], start, end);
  var sen3_loop = get_ndvi_sen3(fields[i], start, end);
  write_to_drive(sen2_loop,sen2_disc,sen2_disc,sen2_folder)
  write_to_drive(sen3_loop,sen3_disc,sen3_disc,sen3_folder)
}
1

You write

var field1 = ee.FeatureCollection(region.filterMetadata("system:index","equals","00000000000000000000").first());

You haven't defined the global variable region in the code you shared, but assuming it is a collection of features, first() of it is a feature, not a feature collection.

Unfortunately, while the documentation of ee.FeatureCollection() says that it converts single Features to FeatureCollections, this doesn't appear to work all the time. (I've reported this as a bug.)

Try this:

var field1 = ee.FeatureCollection(region.filterMetadata("system:index","equals","00000000000000000000"));

That way you actually have a FeatureCollection, that happens to contain a single element, and you don't need to take the extra step of .first().

| improve this answer | |
  • Thank you, works perfectly! – Sahar Attia Apr 24 at 8:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.